Commit c8dba202 authored by Taddeus Kroes's avatar Taddeus Kroes

Debugged Dead Code Elimination.

parent 74461223
from src.statement import Statement as S from src.statement import Statement as S
def create_variable(): def reg_dead_in(var, context):
return '$15' """Check if a register is `dead' in a given list of statements."""
# TODO: Finish
for s in context:
if s.defines(var) or s.uses(var):
return False
return True
def find_free_reg(context):
"""Find a temporary register that is free in a given list of statements."""
for i in xrange(8):
tmp = '$t%d' % i
if reg_dead_in(tmp, context):
return tmp
raise Exception('No temporary register is available.')
def eliminate_common_subexpressions(block): def eliminate_common_subexpressions(block):
...@@ -44,19 +61,22 @@ def eliminate_common_subexpressions(block): ...@@ -44,19 +61,22 @@ def eliminate_common_subexpressions(block):
# Replace a similar expression by a move instruction # Replace a similar expression by a move instruction
if s2.name == s.name and s2[1:] == args: if s2.name == s.name and s2[1:] == args:
if not new_reg: if not new_reg:
new_reg = create_variable() new_reg = find_free_reg(block[:pointer])
block.replace(1, [S('command', 'move', s2[0], new_reg)]) block.replace(1, [S('command', 'move', s2[0], new_reg)])
last = block.pointer last = block.pointer
# Insert an additional expression with a new destination address
if last:
block.insert(S('command', s.name, [new_reg] + args), last)
found = True
# Reset pointer to and continue from the original statement # Reset pointer to and continue from the original statement
block.pointer = pointer block.pointer = pointer
if last:
# Insert an additional expression with a new destination address
block.insert(S('command', s.name, *([new_reg] + args)), last)
# Replace the original expression with a move statement
block.replace(1, [S('command', 'move', s[0], new_reg)])
found = True
block.reverse_statements() block.reverse_statements()
return found return found
...@@ -139,7 +159,7 @@ def fold_constants(block): ...@@ -139,7 +159,7 @@ def fold_constants(block):
if s.name == 'div': if s.name == 'div':
result = to_hex(rs_val / rt_val) result = to_hex(rs_val / rt_val)
block.replace(1, [S('command', 'li', result)]) block.replace(1, [S('command', 'li', rd, result)])
register[rd] = result register[rd] = result
found = True found = True
elif rt_known: elif rt_known:
......
...@@ -88,6 +88,16 @@ class Statement: ...@@ -88,6 +88,16 @@ class Statement:
return self[-1] return self[-1]
def defines(self, reg):
"""Check if this statement defines the given register."""
# TODO: Finish
return (self.is_load() or self.is_arith()) and self[0] == reg
def uses(self, reg):
"""Check if this statement uses the given register."""
# TODO: Finish
return (self.is_load() or self.is_arith()) and reg in self[1:]
class Block: class Block:
def __init__(self, statements=[]): def __init__(self, statements=[]):
......
import unittest import unittest
from copy import copy
from src.optimize.advanced import eliminate_common_subexpressions, \ from src.optimize.advanced import eliminate_common_subexpressions, \
fold_constants, copy_propagation, algebraic_transformations fold_constants, copy_propagation, algebraic_transformations
...@@ -15,8 +16,22 @@ class TestOptimizeAdvanced(unittest.TestCase): ...@@ -15,8 +16,22 @@ class TestOptimizeAdvanced(unittest.TestCase):
del self.foo del self.foo
del self.bar del self.bar
def test_eliminate_common_subexpressions(self): def test_eliminate_common_subexpressions_simple(self):
pass b = B([S('command', 'addu', '$regC', '$regA', '$regB'),
S('command', 'addu', '$regD', '$regA', '$regB')])
e = [S('command', 'addu', '$t0', '$regA', '$regB'), \
S('command', 'move', '$regC', '$t0'), \
S('command', 'move', '$regD', '$t0')]
eliminate_common_subexpressions(b)
self.assertEqual(b.statements, e)
def test_eliminate_common_subexpressions_assigned(self):
b = B([S('command', 'addu', '$regC', '$regA', '$regB'),
S('command', 'li', '$regA', '0x00000001'),
S('command', 'addu', '$regD', '$regA', '$regB')])
e = copy(b.statements)
eliminate_common_subexpressions(b)
self.assertEqual(b.statements, e)
def test_fold_constants(self): def test_fold_constants(self):
pass pass
......
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