reaching_definitions.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from dataflow import BasicBlock as B
  2. def get_defs(blocks):
  3. """Collect definitions of all registers."""
  4. defs = {}
  5. for b in blocks:
  6. for s in b:
  7. for reg in s.get_def():
  8. if reg not in defs:
  9. defs[reg] = set([s.sid])
  10. else:
  11. defs[reg].add(s.sid)
  12. return defs
  13. def create_gen_kill(block, global_defs):
  14. block_defs = {}
  15. # Get the last of each definition series and put in in the `def' set
  16. block.gen_set = set()
  17. for s in reversed(block):
  18. for reg in s.get_def():
  19. if reg not in block_defs:
  20. block_defs[reg] = s.sid
  21. block.gen_set.add(s.sid)
  22. # Generate kill set
  23. block.kill_set = set()
  24. for reg, statement_ids in global_defs.iteritems():
  25. if reg in block_defs:
  26. block.kill_set |= statement_ids - set([block_defs[reg]])
  27. def create_in_out(blocks):
  28. """Generate the `in' and `out' sets of the given blocks using the iterative
  29. algorithm from the lecture slides."""
  30. # Create gen/kill sets
  31. defs = get_defs(blocks)
  32. for b in blocks:
  33. create_gen_kill(b, defs)
  34. b.reach_out = b.gen_set
  35. change = True
  36. while change:
  37. change = False
  38. for b in blocks:
  39. b.reach_in = set()
  40. for pred in b.edges_from:
  41. b.reach_in |= pred.reach_out
  42. new_out = b.gen_set | (b.reach_in - b.kill_set)
  43. if new_out != b.reach_out:
  44. b.reach_out = new_out
  45. change = True