Commit bf493e78 authored by Taddeus Kroes's avatar Taddeus Kroes

Merged conflicts.

parents d0af1443 a2133db3
...@@ -236,5 +236,16 @@ addu $regA, $regB, 4 addu $regD, $regB, 4 ...@@ -236,5 +236,16 @@ addu $regA, $regB, 4 addu $regD, $regB, 4
Code not writing $regB -> ... Code not writing $regB -> ...
... ... ... ...
addu $regC, $regB, 4 move $regC, $regD 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{verbatim}
\end{document} \end{document}
...@@ -162,50 +162,49 @@ def fold_constants(block): ...@@ -162,50 +162,49 @@ def fold_constants(block):
def copy_propagation(block): def copy_propagation(block):
""" """
Rename values that were copied to there original, so the copy statement Replace a variable with its original variable after a move if possible, by
might be useless, allowing it to be removed by dead code elimination. 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_from = []
moves_to = [] moves_to = []
changed = False
while not block.end(): while not block.end():
s = block.read() 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: 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_from.append(s[1])
moves_to.append(s[0]) moves_to.append(s[0])
print "Added move to list." elif s.is_command('move') and s[0] in moves_to:
elif s.is_command('move'): # This move is already in the lists, so only update it
for i in xrange(len(moves_to)): for i in xrange(len(moves_to)):
if moves_to[i] == s[0]: if moves_to[i] == s[0]:
moves_from[i] = s[1] moves_from[i] = s[1]
break
elif len(s) == 3 and s[0] in moves_to: elif len(s) == 3 and s[0] in moves_to:
print len(s) # The result gets overwritten, so remove the data from the list.
print len(moves_to) i = 0
for i in xrange(len(moves_to)): while i < len(moves_to):
if moves_to[i] == s[0]: if moves_to[i] == s[0]:
del moves_to[i] del moves_to[i]
del moves_from[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): 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)): for i in xrange(len(moves_to)):
if s[1] == moves_to[i]: if s[1] == moves_to[i]:
s[1] = moves_from[i] s[1] = moves_from[i]
print "Propagated" break
if s[2] == moves_to[i]: if s[2] == moves_to[i]:
s[2] = moves_from[i] s[2] = moves_from[i]
print "Propagated" break
print "" changed = True
return False
return changed
...@@ -11,6 +11,10 @@ class TestOptimizeAdvanced(unittest.TestCase): ...@@ -11,6 +11,10 @@ class TestOptimizeAdvanced(unittest.TestCase):
self.foo = S('command', 'foo') self.foo = S('command', 'foo')
self.bar = S('command', 'bar') self.bar = S('command', 'bar')
def tearDown(self):
del self.foo
del self.bar
def test_eliminate_common_subexpressions(self): def test_eliminate_common_subexpressions(self):
pass pass
...@@ -18,29 +22,51 @@ class TestOptimizeAdvanced(unittest.TestCase): ...@@ -18,29 +22,51 @@ class TestOptimizeAdvanced(unittest.TestCase):
pass pass
def test_copy_propagation_true(self): def test_copy_propagation_true(self):
print "testing true"
block = B([self.foo, block = B([self.foo,
S('command', 'move', '$1', '$2'), S('command', 'move', '$1', '$2'),
self.foo, self.foo,
S('command', 'addu', '$3', '$1', '$4'), S('command', 'addu', '$3', '$1', '$4'),
self.bar]) self.bar])
copy_propagation(block) self.assertTrue(copy_propagation(block))
self.assertEqual(block.statements, [self.foo, self.assertEqual(block.statements, [self.foo,
S('command', 'move', '$1', '$2'), S('command', 'move', '$1', '$2'),
self.foo, self.foo,
S('command', 'addu', '$3', '$2', '$4'), S('command', 'addu', '$3', '$2', '$4'),
self.bar]) self.bar])
print "Test true succesfull"
def test_copy_propagation_overwrite(self):
# def test_copy_propagation_false(self): block = B([self.foo, \
# print "Testing false" S('command', 'move', '$1', '$2'),
# arguments = [self.foo, S('command', 'move', '$1', '$5'),
# S('command', 'move', '$1', '$2'), S('command', 'addu', '$3', '$1', '$4'),
# S('command', 'move', '$10', '$20'), self.bar])
# S('command', 'addu', '$1', '$5', 1),
# S('command', 'addu', '$3', '$1', '$4'), self.assertTrue(copy_propagation(block))
# self.bar] self.assertEqual(block.statements, [self.foo,
# block = B(arguments) S('command', 'move', '$1', '$2'),
# copy_propagation(block) S('command', 'move', '$1', '$5'),
# self.assertEqual(block.statements, arguments) S('command', 'addu', '$3', '$5', '$4'),
self.bar])
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