| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- from copy import copy
- def generate_dominator_tree(nodes):
- """Add dominator administration to the given flow graph nodes."""
- # Dominator of the start node is the start itself
- nodes[0].dom = set([nodes[0]])
- # For all other nodes, set all nodes as the dominators
- for n in nodes[1:]:
- n.dom = set(copy(nodes))
- def pred(n, known=[]):
- """Recursively find all predecessors of a node."""
- direct = filter(lambda x: x not in known, n.edges_from)
- p = copy(direct)
- for ancestor in direct:
- p += pred(ancestor, direct)
- return p
- # Iteratively eliminate nodes that are not dominators
- changed = True
- while changed:
- changed = False
- for n in nodes[1:]:
- old_dom = n.dom
- intersection = lambda p1, p2: p1.dom & p2.dom
- n.dom = set([n]) | reduce(intersection, pred(n), set([]))
- if n.dom != old_dom:
- changed = True
- def idom(d, n):
- """Check if d immediately dominates n."""
- for b in n.dom:
- if b != d and b != n and b in n.dom:
- return False
- return True
- # Build tree using immediate dominators
- for n in nodes:
- for d in n.dom:
- if idom(d, n):
- d.set_dominates(n)
- break
|