|
|
@@ -97,55 +97,102 @@ def generate_flow_graph(blocks):
|
|
|
b.add_edge_to(blocks[i + 1])
|
|
|
|
|
|
|
|
|
-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
|
|
|
-
|
|
|
-# statements = parse_file(...)
|
|
|
-# b = find_basic_blocks(statements)
|
|
|
-# generate_flow_graph(b) # nodes now have edges
|
|
|
-# generate_dominator_tree(b) # nodes now have dominators
|
|
|
+#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
|
|
|
+
|
|
|
+
|
|
|
+class Dag:
|
|
|
+ def __init__(self, block):
|
|
|
+ """Create the Directed Acyclic Graph of all binary operations in a
|
|
|
+ basic block."""
|
|
|
+ self.nodes = []
|
|
|
+
|
|
|
+ for s in block:
|
|
|
+ if s.is_command('move') or s.is_monop():
|
|
|
+ rd, rs = s
|
|
|
+ y = self.find_reg_node(rs)
|
|
|
+ self.find_op_node(s.name, rd, y)
|
|
|
+ elif s.is_binop():
|
|
|
+ rd, rs, rt = s
|
|
|
+ y = self.find_reg_node(rs)
|
|
|
+ z = self.find_reg_node(rt)
|
|
|
+ self.find_op_node(s.name, rd, y, z)
|
|
|
+
|
|
|
+ def find_reg_node(self, reg):
|
|
|
+ for n in self.nodes:
|
|
|
+ if reg in n.reg:
|
|
|
+ return n
|
|
|
+
|
|
|
+ node = DagLeaf(reg)
|
|
|
+ self.nodes.append(node)
|
|
|
+
|
|
|
+ return node
|
|
|
+
|
|
|
+ def find_op_node(self, op, rd, *args):
|
|
|
+ for n in self.nodes:
|
|
|
+ if n.op == op and n.nodes == args:
|
|
|
+ n.labels.append(rd)
|
|
|
+
|
|
|
+ return n
|
|
|
+
|
|
|
+ node = DagNode(op, rd, *args)
|
|
|
+ self.nodes.append(node)
|
|
|
+
|
|
|
+ return node
|
|
|
+
|
|
|
+
|
|
|
+class DagNode:
|
|
|
+ def __init__(self, op, label, *args):
|
|
|
+ self.op = op
|
|
|
+ self.labels = [label]
|
|
|
+ self.nodes = args
|
|
|
+
|
|
|
+
|
|
|
+class DagLeaf:
|
|
|
+ def __init__(self, reg):
|
|
|
+ self.reg = reg
|