Commit a2a424d0 authored by Jayke Meijer's avatar Jayke Meijer

Tested copy_propagation.

parent 2fdd48ad
......@@ -236,5 +236,16 @@ addu $regA, $regB, 4 addu $regD, $regB, 4
Code not writing $regB -> ...
... ...
addu $regC, $regB, 4 move $regC, $regD
# Constant folding
# Copy propagation
move $regA, $regB move $regA, $regB
... ...
Code not writing $regA, -> ...
$regB ...
... ...
addu $regC, $regA, ... addu $regC, $regB, ...
\end{verbatim}
\end{document}
......@@ -153,50 +153,49 @@ def fold_constants(block):
def copy_propagation(block):
"""
Rename values that were copied to there original, so the copy statement
might be useless, allowing it to be removed by dead code elimination.
Replace a variable with its original variable after a move if possible, by
walking through the code, storing move operations and checking whether it
changes or whether a variable can be replaced. This way, the move statement
might be a target for dead code elimination.
"""
moves_from = []
moves_to = []
changed = False
while not block.end():
s = block.read()
if len(s) == 3:
print "s[0] = ", s[0]
print "s[1] = ", s[1]
print "s[2] = ", s[2]
if moves_from:
print "fr: ", moves_from
print "to: ", moves_to
if s.is_command('move') and s[0] not in moves_to:
# Add this move to the lists, because it is not yet there.
moves_from.append(s[1])
moves_to.append(s[0])
print "Added move to list."
elif s.is_command('move'):
elif s.is_command('move') and s[0] in moves_to:
# This move is already in the lists, so only update it
for i in xrange(len(moves_to)):
if moves_to[i] == s[0]:
moves_from[i] = s[1]
break
elif len(s) == 3 and s[0] in moves_to:
print len(s)
print len(moves_to)
for i in xrange(len(moves_to)):
# The result gets overwritten, so remove the data from the list.
i = 0
while i < len(moves_to):
if moves_to[i] == s[0]:
del moves_to[i]
del moves_from[i]
"Removed move from list."
else:
i += 1
elif len(s) == 3 and (s[1] in moves_to or s[2] in moves_to):
print "Have to propagate."
# Check where the result of the move is used and replace it with
# the original variable.
for i in xrange(len(moves_to)):
if s[1] == moves_to[i]:
s[1] = moves_from[i]
print "Propagated"
break
if s[2] == moves_to[i]:
s[2] = moves_from[i]
print "Propagated"
print ""
return False
break
changed = True
return changed
......@@ -14,30 +14,52 @@ class TestOptimizeAdvanced(unittest.TestCase):
def test_eliminate_common_subexpressions(self):
pass
def test_copy_propagation_true(self):
print "testing true"
def test_copy_propagation_true(self):
block = B([self.foo,
S('command', 'move', '$1', '$2'),
self.foo,
S('command', 'addu', '$3', '$1', '$4'),
self.bar])
copy_propagation(block)
self.assertTrue(copy_propagation(block))
self.assertEqual(block.statements, [self.foo,
S('command', 'move', '$1', '$2'),
self.foo,
S('command', 'addu', '$3', '$2', '$4'),
self.bar])
print "Test true succesfull"
def test_copy_propagation_overwrite(self):
block = B([self.foo, \
S('command', 'move', '$1', '$2'),
S('command', 'move', '$1', '$5'),
S('command', 'addu', '$3', '$1', '$4'),
self.bar])
self.assertTrue(copy_propagation(block))
self.assertEqual(block.statements, [self.foo,
S('command', 'move', '$1', '$2'),
S('command', 'move', '$1', '$5'),
S('command', 'addu', '$3', '$5', '$4'),
self.bar])
# def test_copy_propagation_false(self):
# print "Testing false"
# arguments = [self.foo,
# S('command', 'move', '$1', '$2'),
# S('command', 'move', '$10', '$20'),
# S('command', 'addu', '$1', '$5', 1),
# S('command', 'addu', '$3', '$1', '$4'),
# self.bar]
# block = B(arguments)
# copy_propagation(block)
# self.assertEqual(block.statements, arguments)
def test_copy_propagation_false(self):
arguments = [self.foo,
S('command', 'move', '$1', '$2'),
S('command', 'move', '$10', '$20'),
S('command', 'addu', '$1', '$5', 1),
S('command', 'addu', '$3', '$1', '$4'),
self.bar]
block = B(arguments)
self.assertFalse(copy_propagation(block))
self.assertEqual(block.statements, arguments)
def test_copy_propagation_false_severalmoves(self):
arguments = [self.foo,
S('command', 'move', '$1', '$2'),
self.foo,
S('command', 'addu', '$1', '$5', 1),
S('command', 'addu', '$3', '$1', '$4'),
self.bar]
block = B(arguments)
self.assertFalse(copy_propagation(block))
self.assertEqual(block.statements, arguments)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment