Skip to content
Snippets Groups Projects
Commit 00d7bd2f authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Fixed existing unit tests and added tests for reaching definitions..

parent 19cebc60
No related branches found
No related tags found
No related merge requests found
...@@ -2,14 +2,12 @@ def create_gen_kill(block): ...@@ -2,14 +2,12 @@ def create_gen_kill(block):
# Get the last of each definition series and put in in the `def' set # Get the last of each definition series and put in in the `def' set
block.live_gen = set() block.live_gen = set()
block.live_kill = set() block.live_kill = set()
print 'block:', block
for s in block: for s in block:
# If a register is used without having been defined in this block, # If a register is used without having been defined in this block,
# yet, put it in the `gen' set # yet, put it in the `gen' set
for reg in s.get_use(): for reg in s.get_use():
if reg not in block.live_kill: if reg not in block.live_kill:
print ' add:', reg
block.live_gen.add(reg) block.live_gen.add(reg)
for reg in s.get_def(): for reg in s.get_def():
...@@ -17,4 +15,6 @@ def create_gen_kill(block): ...@@ -17,4 +15,6 @@ def create_gen_kill(block):
def create_in_out(blocks): def create_in_out(blocks):
pass for b in blocks:
b.live_in = set()
b.live_out = set()
from src.dataflow import find_basic_blocks, reaching_definitions from src.dataflow import find_basic_blocks
import src.liveness as liveness
import src.reaching_definitions as reaching_definitions
from redundancies import remove_redundant_jumps, move_1, move_2, move_3, \ from redundancies import remove_redundant_jumps, move_1, move_2, move_3, \
move_4, load, shift, add move_4, load, shift, add
from advanced import eliminate_common_subexpressions, fold_constants, \ from advanced import eliminate_common_subexpressions, fold_constants, \
copy_propagation, algebraic_transformations, eliminate_dead_code copy_propagation, eliminate_dead_code
def remove_redundancies(block): def remove_redundancies(block):
...@@ -48,8 +50,9 @@ def optimize(statements, verbose=0): ...@@ -48,8 +50,9 @@ def optimize(statements, verbose=0):
# Divide into basic blocks # Divide into basic blocks
blocks = find_basic_blocks(statements) blocks = find_basic_blocks(statements)
# Find reaching definitions # Perform dataflow analysis
reaching_definitions(blocks) liveness.create_in_out(blocks)
reaching_definitions.create_in_out(blocks)
# Optimize basic blocks # Optimize basic blocks
map(optimize_block, blocks) map(optimize_block, blocks)
......
...@@ -18,7 +18,7 @@ def reg_can_be_used_in(reg, block, start, end): ...@@ -18,7 +18,7 @@ def reg_can_be_used_in(reg, block, start, end):
elif s.defines(reg): elif s.defines(reg):
return True return True
return reg not in block.out_set return reg not in block.live_out
def find_free_reg(block, start, end): def find_free_reg(block, start, end):
......
...@@ -44,7 +44,6 @@ def create_in_out(blocks): ...@@ -44,7 +44,6 @@ def create_in_out(blocks):
# Create gen/kill sets # Create gen/kill sets
defs = get_defs(blocks) defs = get_defs(blocks)
print 'defs:', defs
for b in blocks: for b in blocks:
create_gen_kill(b, defs) create_gen_kill(b, defs)
...@@ -56,19 +55,13 @@ def create_in_out(blocks): ...@@ -56,19 +55,13 @@ def create_in_out(blocks):
change = False change = False
for b in blocks: for b in blocks:
print 'block:', b
b.reach_in = set() b.reach_in = set()
for pred in b.edges_from: for pred in b.edges_from:
print 'pred: ', pred
b.reach_in |= pred.reach_out b.reach_in |= pred.reach_out
print 'b.reach_in: ', b.reach_in
print 'b.reach_out: ', b.reach_out
new_out = b.reach_gen | (b.reach_in - b.reach_kill) new_out = b.reach_gen | (b.reach_in - b.reach_kill)
print 'new_out: ', new_out
if new_out != b.reach_out: if new_out != b.reach_out:
print 'changed'
b.reach_out = new_out b.reach_out = new_out
change = True change = True
...@@ -23,14 +23,14 @@ class TestLiveness(unittest.TestCase): ...@@ -23,14 +23,14 @@ class TestLiveness(unittest.TestCase):
create_gen_kill(block) create_gen_kill(block)
self.assertEqual(block.live_gen, set(['$1', '$2'])) self.assertEqual(block.live_gen, set(['$1', '$2']))
self.assertEqual(block.live_kill, set(['$3', '$1', '$1'])) self.assertEqual(block.live_kill, set(['$3', '$1', '$4']))
#def test_create_in_out(self): #def test_create_in_out(self):
# s11 = S('command', 'li', 'a', 3) # s11 = S('command', 'li', 'a', 3)
# s12 = S('command', 'li', 'b', 5) # s12 = S('command', 'li', 'b', 5)
# s13 = S('command', 'li', 'd', 4) # s13 = S('command', 'li', 'd', 4)
# s14 = S('command', 'li', 'x', 100) # s14 = S('command', 'li', 'x', 100)
# s15 = S('command', 'blt', 'a', 'b', 'L1') # s15 = S('command', 'beq', 'a', 'b', 'L1')
# b1 = B([s11, s12, s13, s14, s15]) # b1 = B([s11, s12, s13, s14, s15])
# s21 = S('command', 'addu', 'c', 'a', 'b') # s21 = S('command', 'addu', 'c', 'a', 'b')
......
...@@ -4,6 +4,7 @@ from copy import copy ...@@ -4,6 +4,7 @@ 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
from src.statement import Statement as S, Block as B from src.statement import Statement as S, Block as B
import src.liveness as liveness
class TestOptimizeAdvanced(unittest.TestCase): class TestOptimizeAdvanced(unittest.TestCase):
...@@ -22,6 +23,7 @@ class TestOptimizeAdvanced(unittest.TestCase): ...@@ -22,6 +23,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
e = [S('command', 'addu', '$8', '$regA', '$regB'), \ e = [S('command', 'addu', '$8', '$regA', '$regB'), \
S('command', 'move', '$regC', '$8'), \ S('command', 'move', '$regC', '$8'), \
S('command', 'move', '$regD', '$8')] S('command', 'move', '$regD', '$8')]
liveness.create_in_out([b])
eliminate_common_subexpressions(b) eliminate_common_subexpressions(b)
self.assertEqual(b.statements, e) self.assertEqual(b.statements, e)
...@@ -30,6 +32,7 @@ class TestOptimizeAdvanced(unittest.TestCase): ...@@ -30,6 +32,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
S('command', 'li', '$regA', '0x00000001'), S('command', 'li', '$regA', '0x00000001'),
S('command', 'addu', '$regD', '$regA', '$regB')]) S('command', 'addu', '$regD', '$regA', '$regB')])
e = copy(b.statements) e = copy(b.statements)
liveness.create_in_out([b])
eliminate_common_subexpressions(b) eliminate_common_subexpressions(b)
self.assertEqual(b.statements, e) self.assertEqual(b.statements, e)
...@@ -49,7 +52,7 @@ class TestOptimizeAdvanced(unittest.TestCase): ...@@ -49,7 +52,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
self.foo, self.foo,
S('command', 'addu', '$3', '$2', '$4'), S('command', 'addu', '$3', '$2', '$4'),
self.bar]) self.bar])
def test_copy_propagation_other_arg(self): def test_copy_propagation_other_arg(self):
block = B([self.foo, block = B([self.foo,
S('command', 'move', '$1', '$2'), S('command', 'move', '$1', '$2'),
......
import unittest import unittest
from src.statement import Statement as S from src.statement import Statement as S
from src.dataflow import BasicBlock as B from src.dataflow import BasicBlock as B, find_basic_blocks
from src.reaching_definitions import get_defs, create_gen_kill, create_in_out from src.reaching_definitions import get_defs, create_gen_kill, create_in_out
...@@ -26,7 +26,7 @@ class TestReachingDefinitions(unittest.TestCase): ...@@ -26,7 +26,7 @@ class TestReachingDefinitions(unittest.TestCase):
'$4': set([s4.sid]) '$4': set([s4.sid])
}) })
def test_create_gen_kill_simple(self): def test_create_gen_kill(self):
s1 = S('command', 'addu', '$3', '$1', '$2') s1 = S('command', 'addu', '$3', '$1', '$2')
s2 = S('command', 'addu', '$1', '$3', 10) s2 = S('command', 'addu', '$1', '$3', 10)
s3 = S('command', 'subu', '$3', '$1', 5) s3 = S('command', 'subu', '$3', '$1', 5)
...@@ -38,63 +38,44 @@ class TestReachingDefinitions(unittest.TestCase): ...@@ -38,63 +38,44 @@ class TestReachingDefinitions(unittest.TestCase):
self.assertEqual(block.reach_gen, set([s2.sid, s3.sid, s4.sid])) self.assertEqual(block.reach_gen, set([s2.sid, s3.sid, s4.sid]))
self.assertEqual(block.reach_kill, set([s1.sid])) self.assertEqual(block.reach_kill, set([s1.sid]))
#def test_create_gen_kill_between_blocks(self): def test_create_in_out(self):
# s11 = S('command', 'li', 'a', 3) s11 = S('command', 'li', 'a', 3)
# s12 = S('command', 'li', 'b', 5) s12 = S('command', 'li', 'b', 5)
# s13 = S('command', 'li', 'd', 4) s13 = S('command', 'li', 'd', 4)
# s14 = S('command', 'li', 'x', 100) s14 = S('command', 'li', 'x', 100)
# s15 = S('command', 'blt', 'a', 'b', 'L1') s15 = S('command', 'beq', 'a', 'b', 'L1')
# b1 = B([s11, s12, s13, s14, s15])
s21 = S('command', 'addu', 'c', 'a', 'b')
# s21 = S('command', 'addu', 'c', 'a', 'b') s22 = S('command', 'li', 'd', 2)
# s22 = S('command', 'li', 'd', 2)
# b2 = B([s21, s22]) s31 = S('label', 'L1')
s32 = S('command', 'li', 'c', 4)
# s31 = S('label', 'L1') s33 = S('command', 'mult', 'b', 'd')
# s32 = S('command', 'li', 'c', 4) s34 = S('command', 'mflo', 'temp')
# s33 = S('command', 'mult', 'b', 'd') s35 = S('command', 'addu', 'return', 'temp', 'c')
# s34 = S('command', 'mflo', 'temp')
# s35 = S('command', 'addu', 'return', 'temp', 'c') b1, b2, b3 = find_basic_blocks([s11, s12, s13, s14, s15, s21, s22, \
# b3 = B([s31, s32, s33, s34, s35]) s31, s32, s33, s34, s35])
# defs = get_defs([b1, b2, b3]) create_in_out([b1, b2, b3])
# create_gen_kill(b1, defs)
# create_gen_kill(b2, defs) self.assertEqual(b1.reach_gen, set([s11.sid, s12.sid, s13.sid,
# create_gen_kill(b3, defs) s14.sid]))
self.assertEqual(b1.reach_kill, set([s22.sid]))
# self.assertEqual(b1.reach_gen, set([s11.sid, s12.sid, s13.sid, s14.sid])) self.assertEqual(b2.reach_gen, set([s21.sid, s22.sid]))
# self.assertEqual(b1.reach_kill, set([s22.sid])) self.assertEqual(b2.reach_kill, set([s13.sid, s32.sid]))
self.assertEqual(b3.reach_gen, set([s32.sid, s34.sid, s35.sid]))
# self.assertEqual(b2.reach_gen, set([s21.sid, s22.sid])) self.assertEqual(b3.reach_kill, set([s21.sid]))
# self.assertEqual(b2.reach_kill, set([s13.sid, s32.sid]))
self.assertEqual(b1.reach_in, set())
# self.assertEqual(b3.reach_gen, set([s32.sid, s34.sid, s35.sid])) self.assertEqual(b1.reach_out, set([s11.sid, s12.sid, s13.sid,
# self.assertEqual(b3.reach_kill, set([s21.sid])) s14.sid]))
self.assertEqual(b2.reach_in, set([s11.sid, s12.sid, s13.sid,
#def test_create_in_out(self): s14.sid]))
# s11 = S('command', 'li', 'a', 3) self.assertEqual(b2.reach_out, set([s21.sid, s22.sid, s11.sid, \
# s12 = S('command', 'li', 'b', 5) s12.sid, s14.sid]))
# s13 = S('command', 'li', 'd', 4) self.assertEqual(b3.reach_in, set([s21.sid, s22.sid, s11.sid, \
# s14 = S('command', 'li', 'x', 100) s12.sid, s13.sid, s14.sid]))
# s15 = S('command', 'blt', 'a', 'b', 'L1') self.assertEqual(b3.reach_out, set([s32.sid, s34.sid, s35.sid, \
# b1 = B([s11, s12, s13, s14, s15]) s22.sid, s11.sid, s12.sid, \
s13.sid, s14.sid]))
# s21 = S('command', 'addu', 'c', 'a', 'b')
# s22 = S('command', 'li', 'd', 2)
# b2 = B([s21, s22])
# s31 = S('label', 'L1')
# s32 = S('command', 'li', 'c', 4)
# s33 = S('command', 'mult', 'b', 'd')
# s34 = S('command', 'mflo', 'temp')
# s35 = S('command', 'addu', 'return', 'temp', 'c')
# b3 = B([s31, s32, s33, s34, s35])
# create_in_out([b1, b2, b3])
# self.assertEqual(b1.reach_in, set())
# self.assertEqual(b1.reach_out, set([s11.sid, s12.sid, s13.sid]))
# self.assertEqual(b2.reach_in, set([s11.sid, s12.sid]))
# self.assertEqual(b2.reach_out, set([s12.sid, s22.sid]))
# self.assertEqual(b3.reach_in, set([s12.sid, s22.sid]))
# self.assertEqual(b3.reach_out, set())
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