Kaynağa Gözat

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

Taddeus Kroes 14 yıl önce
ebeveyn
işleme
00d7bd2f57

+ 3 - 3
src/liveness.py

@@ -2,14 +2,12 @@ def create_gen_kill(block):
     # Get the last of each definition series and put in in the `def' set
     block.live_gen = set()
     block.live_kill = set()
-    print 'block:', block
 
     for s in block:
         # If a register is used without having been defined in this block,
         # yet, put it in the `gen' set
         for reg in s.get_use():
             if reg not in block.live_kill:
-                print '  add:', reg
                 block.live_gen.add(reg)
 
         for reg in s.get_def():
@@ -17,4 +15,6 @@ def create_gen_kill(block):
 
 
 def create_in_out(blocks):
-    pass
+    for b in blocks:
+        b.live_in = set()
+        b.live_out = set()

+ 7 - 4
src/optimize/__init__.py

@@ -1,9 +1,11 @@
-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, \
         move_4, load, shift, add
 from advanced import eliminate_common_subexpressions, fold_constants, \
-        copy_propagation, algebraic_transformations, eliminate_dead_code
+        copy_propagation, eliminate_dead_code
 
 
 def remove_redundancies(block):
@@ -48,8 +50,9 @@ def optimize(statements, verbose=0):
     # Divide into basic blocks
     blocks = find_basic_blocks(statements)
 
-    # Find reaching definitions
-    reaching_definitions(blocks)
+    # Perform dataflow analysis
+    liveness.create_in_out(blocks)
+    reaching_definitions.create_in_out(blocks)
 
     # Optimize basic blocks
     map(optimize_block, blocks)

+ 1 - 1
src/optimize/advanced.py

@@ -18,7 +18,7 @@ def reg_can_be_used_in(reg, block, start, end):
         elif s.defines(reg):
             return True
 
-    return reg not in block.out_set
+    return reg not in block.live_out
 
 
 def find_free_reg(block, start, end):

+ 0 - 7
src/reaching_definitions.py

@@ -44,7 +44,6 @@ def create_in_out(blocks):
 
     # Create gen/kill sets
     defs = get_defs(blocks)
-    print 'defs:', defs
 
     for b in blocks:
         create_gen_kill(b, defs)
@@ -56,19 +55,13 @@ def create_in_out(blocks):
         change = False
 
         for b in blocks:
-            print 'block:', b
             b.reach_in = set()
 
             for pred in b.edges_from:
-                print 'pred:      ', pred
                 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)
-            print 'new_out:   ', new_out
 
             if new_out != b.reach_out:
-                print 'changed'
                 b.reach_out = new_out
                 change = True

+ 2 - 2
tests/test_liveness.py

@@ -23,14 +23,14 @@ class TestLiveness(unittest.TestCase):
         create_gen_kill(block)
 
         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):
     #    s11 = S('command', 'li', 'a', 3)
     #    s12 = S('command', 'li', 'b', 5)
     #    s13 = S('command', 'li', 'd', 4)
     #    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')

+ 4 - 1
tests/test_optimize_advanced.py

@@ -4,6 +4,7 @@ from copy import copy
 from src.optimize.advanced import eliminate_common_subexpressions, \
         fold_constants, copy_propagation, algebraic_transformations
 from src.statement import Statement as S, Block as B
+import src.liveness as liveness
 
 
 class TestOptimizeAdvanced(unittest.TestCase):
@@ -22,6 +23,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
         e = [S('command', 'addu', '$8', '$regA', '$regB'), \
              S('command', 'move', '$regC', '$8'), \
              S('command', 'move', '$regD', '$8')]
+        liveness.create_in_out([b])
         eliminate_common_subexpressions(b)
         self.assertEqual(b.statements, e)
 
@@ -30,6 +32,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
                S('command', 'li', '$regA', '0x00000001'),
                S('command', 'addu', '$regD', '$regA', '$regB')])
         e = copy(b.statements)
+        liveness.create_in_out([b])
         eliminate_common_subexpressions(b)
         self.assertEqual(b.statements, e)
 
@@ -49,7 +52,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
                    self.foo,
                    S('command', 'addu', '$3', '$2', '$4'),
                    self.bar])
-                   
+
     def test_copy_propagation_other_arg(self):
         block = B([self.foo,
                    S('command', 'move', '$1', '$2'),

+ 43 - 62
tests/test_reaching_definitions.py

@@ -1,7 +1,7 @@
 import unittest
 
 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
 
 
@@ -26,7 +26,7 @@ class TestReachingDefinitions(unittest.TestCase):
             '$4': set([s4.sid])
         })
 
-    def test_create_gen_kill_simple(self):
+    def test_create_gen_kill(self):
         s1 = S('command', 'addu', '$3', '$1', '$2')
         s2 = S('command', 'addu', '$1', '$3', 10)
         s3 = S('command', 'subu', '$3', '$1', 5)
@@ -38,63 +38,44 @@ class TestReachingDefinitions(unittest.TestCase):
         self.assertEqual(block.reach_gen, set([s2.sid, s3.sid, s4.sid]))
         self.assertEqual(block.reach_kill, set([s1.sid]))
 
-    #def test_create_gen_kill_between_blocks(self):
-    #    s11 = S('command', 'li', 'a', 3)
-    #    s12 = S('command', 'li', 'b', 5)
-    #    s13 = S('command', 'li', 'd', 4)
-    #    s14 = S('command', 'li', 'x', 100)
-    #    s15 = S('command', 'blt', 'a', 'b', 'L1')
-    #    b1 = B([s11, s12, s13, s14, s15])
-
-    #    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])
-
-    #    defs = get_defs([b1, b2, b3])
-    #    create_gen_kill(b1, defs)
-    #    create_gen_kill(b2, defs)
-    #    create_gen_kill(b3, defs)
-
-    #    self.assertEqual(b1.reach_gen, set([s11.sid, s12.sid, s13.sid, s14.sid]))
-    #    self.assertEqual(b1.reach_kill, set([s22.sid]))
-
-    #    self.assertEqual(b2.reach_gen, set([s21.sid, 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(b3.reach_kill, set([s21.sid]))
-
-    #def test_create_in_out(self):
-    #    s11 = S('command', 'li', 'a', 3)
-    #    s12 = S('command', 'li', 'b', 5)
-    #    s13 = S('command', 'li', 'd', 4)
-    #    s14 = S('command', 'li', 'x', 100)
-    #    s15 = S('command', 'blt', 'a', 'b', 'L1')
-    #    b1 = B([s11, s12, s13, s14, s15])
-
-    #    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())
+    def test_create_in_out(self):
+        s11 = S('command', 'li', 'a', 3)
+        s12 = S('command', 'li', 'b', 5)
+        s13 = S('command', 'li', 'd', 4)
+        s14 = S('command', 'li', 'x', 100)
+        s15 = S('command', 'beq', 'a', 'b', 'L1')
+
+        s21 = S('command', 'addu', 'c', 'a', 'b')
+        s22 = S('command', 'li', 'd', 2)
+
+        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')
+
+        b1, b2, b3 = find_basic_blocks([s11, s12, s13, s14, s15, s21, s22, \
+                                        s31, s32, s33, s34, s35])
+
+        create_in_out([b1, b2, b3])
+
+        self.assertEqual(b1.reach_gen, set([s11.sid, s12.sid, s13.sid,
+                                            s14.sid]))
+        self.assertEqual(b1.reach_kill, set([s22.sid]))
+        self.assertEqual(b2.reach_gen, set([s21.sid, 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(b3.reach_kill, set([s21.sid]))
+
+        self.assertEqual(b1.reach_in, set())
+        self.assertEqual(b1.reach_out, set([s11.sid, s12.sid, s13.sid,
+                                            s14.sid]))
+        self.assertEqual(b2.reach_in, set([s11.sid, s12.sid, s13.sid,
+                                            s14.sid]))
+        self.assertEqual(b2.reach_out, set([s21.sid, s22.sid, s11.sid, \
+                                            s12.sid, s14.sid]))
+        self.assertEqual(b3.reach_in, set([s21.sid, s22.sid, s11.sid, \
+                                            s12.sid, s13.sid, s14.sid]))
+        self.assertEqual(b3.reach_out, set([s32.sid, s34.sid, s35.sid, \
+                                            s22.sid, s11.sid, s12.sid, \
+                                            s13.sid, s14.sid]))