| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- from copy import copy
- def create_use_def(block):
- used = set()
- defined = set()
- # Get the last of each definition series and put in in the `def' set
- block.use_set = set()
- block.def_set = set()
- for s in block:
- # use[B] is the set of variables whose values may be used in B prior to
- # any definition of the variable
- for reg in s.get_use():
- used.add(reg)
- if reg not in defined:
- block.use_set.add(reg)
- # def[B] is the set of variables assigned values in B prior to any use
- # of that variable in B
- for reg in s.get_def():
- defined.add(reg)
- if reg not in used:
- block.def_set.add(reg)
- def succ(block, known=[]):
- """Recursively find all successors of a node."""
- direct = filter(lambda b: b != block and b not in known, block.edges_to)
- s = copy(direct)
- for successor in direct:
- s += succ(successor, known + direct)
- return s
- return s
- def create_in_out(blocks):
- for b in blocks:
- create_use_def(b)
- b.live_in = b.use_set
- b.live_out = set()
- change = True
- while change:
- change = False
- for b in blocks:
- # in[B] = use[B] | (out[B] - def[B])
- new_in = b.use_set | (b.live_out - b.def_set)
- # out[B] = union of in[S] for S in succ(B)
- new_out = set()
- for s in succ(b):
- new_out |= s.live_in
- # Check if either `in' or `out' changed
- if new_in != b.live_in:
- b.live_in = new_in
- change = True
- if new_out != b.live_out:
- b.live_out = new_out
- change = True
|