liveness.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. from copy import copy
  2. def create_use_def(block):
  3. used = set()
  4. defined = set()
  5. # Get the last of each definition series and put in in the `def' set
  6. block.use_set = set()
  7. block.def_set = set()
  8. for s in block:
  9. # use[B] is the set of variables whose values may be used in B prior to
  10. # any definition of the variable
  11. for reg in s.get_use():
  12. used.add(reg)
  13. if reg not in defined:
  14. block.use_set.add(reg)
  15. # def[B] is the set of variables assigned values in B prior to any use
  16. # of that variable in B
  17. for reg in s.get_def():
  18. defined.add(reg)
  19. if reg not in used:
  20. block.def_set.add(reg)
  21. def succ(block, known=[]):
  22. """Recursively find all successors of a node."""
  23. direct = filter(lambda b: b != block and b not in known, block.edges_to)
  24. s = copy(direct)
  25. for successor in direct:
  26. s += succ(successor, known + direct)
  27. return s
  28. return s
  29. def create_in_out(blocks):
  30. for b in blocks:
  31. create_use_def(b)
  32. b.live_in = b.use_set
  33. b.live_out = set()
  34. change = True
  35. while change:
  36. change = False
  37. for b in blocks:
  38. # in[B] = use[B] | (out[B] - def[B])
  39. new_in = b.use_set | (b.live_out - b.def_set)
  40. # out[B] = union of in[S] for S in succ(B)
  41. new_out = set()
  42. for s in succ(b):
  43. new_out |= s.live_in
  44. # Check if either `in' or `out' changed
  45. if new_in != b.live_in:
  46. b.live_in = new_in
  47. change = True
  48. if new_out != b.live_out:
  49. b.live_out = new_out
  50. change = True