Skip to content
Snippets Groups Projects
Commit 1f8dbb4f authored by Jayke Meijer's avatar Jayke Meijer
Browse files

Merge branch 'master' of github.com:taddeus/peephole

parents 38a5bdca ec54b66b
No related branches found
No related tags found
No related merge requests found
......@@ -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
......@@ -21,7 +21,7 @@ class Statement:
arguments."""
return self.stype == other.stype and self.name == other.name \
and self.args == other.args
def __len__(self):
return len(self.args)
......@@ -74,6 +74,14 @@ class Statement:
return self.is_command() \
and re.match('^(add|sub|mult|div|abs|neg)(u|\.d)?$', self.name)
def is_monop(self):
"""Check if the statement is an unary operation."""
return len(self) == 2 and self.is_arith()
def is_binop(self):
"""Check if the statement is an binary operation."""
return self.is_command() and len(self) == 3 and not self.is_jump()
def jump_target(self):
"""Get the jump target of this statement."""
if not self.is_jump():
......@@ -123,7 +131,7 @@ class Block:
replacement."""
if self.pointer == 0:
raise Exception('No statement have been read yet.')
if start == None:
start = self.pointer - 1
......
No preview for this file type
......@@ -2,7 +2,7 @@ import unittest
from src.statement import Statement as S
from src.dataflow import BasicBlock as B, find_leaders, find_basic_blocks, \
generate_flow_graph
generate_flow_graph, Dag
class TestDataflow(unittest.TestCase):
......@@ -44,3 +44,6 @@ class TestDataflow(unittest.TestCase):
self.assertEqual(b2.edges_to, [b3])
self.assertIn(b1, b3.edges_from)
self.assertIn(b2, b3.edges_from)
def test_dag(self):
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment