Taddeus Kroes 14 лет назад
Родитель
Сommit
e0b4e598c5
5 измененных файлов с 108 добавлено и 77 удалено
  1. 1 0
      src/optimize/__init__.py
  2. 36 36
      src/optimize/redundancies.py
  3. 16 33
      src/program.py
  4. 46 0
      tests/test_liveness.py
  5. 9 8
      tests/test_optimize.py

+ 1 - 0
src/optimize/__init__.py

@@ -14,6 +14,7 @@ def optimize(program, verbose=0):
     changed = True
 
     while changed:
+        print 'main iteration'
         changed = False
 
         # Optimize on a global level

+ 36 - 36
src/optimize/redundancies.py

@@ -124,45 +124,45 @@ def add_lw(add, statements):
             return True
 
 def remove_redundant_jumps(statements):
-    """Remove jump if label follows immediatly."""
-    old_len = -1
-
-    while old_len != len(statements):
-        old_len = len(statements)
+    """Remove jump if label follows immediately."""
+    changed = False
         
-        while not statements.end():
-            s = statements.read()
-
-            #     j $Lx     ->             $Lx:
-            # $Lx:
-            if s.is_command('j'):
-                following = statements.peek(2)
-
-                if following.is_label(s[0]):
-                    statements.replace(1, [])
+    statements.reset()
+    while not statements.end():
+        s = statements.read()
+
+        #     j $Lx     ->             $Lx:
+        # $Lx:
+        if s.is_command('j'):
+            following = statements.peek()
+            
+            if following.is_label(s[0]):
+                statements.replace(1, [])
+                changed = True
+                    
+    return True
                         
 def remove_redundant_branch_jumps(statements):
     """Optimize statement sequences on a global level."""
-    old_len = -1
-
-    while old_len != len(statements):
-        old_len = len(statements)
-
-        while not statements.end():
-            s = statements.read()
-
-            #     beq/bne ..., $Lx      ->      bne/beq ..., $Ly
-            #     j $Ly                     $Lx:
-            # $Lx:
-            if s.is_command('beq', 'bne'):
-                following = statements.peek(2)
-
-                if len(following) == 2:
-                    j, label = following
-
-                    if j.is_command('j') and label.is_label(s[2]):
-                        s.name = 'bne' if s.is_command('beq') else 'beq'
-                        s[2] = j[0]
-                        statements.replace(3, [s, label])
+    changed = False
 
     statements.reset()
+    while not statements.end():
+        s = statements.read()
+
+        #     beq/bne ..., $Lx      ->      bne/beq ..., $Ly
+        #     j $Ly                     $Lx:
+        # $Lx:
+        if s.is_command('beq', 'bne'):
+            following = statements.peek(2)
+
+            if len(following) == 2:
+                j, label = following
+
+                if j.is_command('j') and label.is_label(s[2]):
+                    s.name = 'bne' if s.is_command('beq') else 'beq'
+                    s[2] = j[0]
+                    statements.replace(3, [s, label])
+                    changed = True
+                        
+    return changed

+ 16 - 33
src/program.py

@@ -1,6 +1,7 @@
 from statement import Statement as S, Block
 from dataflow import find_basic_blocks, generate_flow_graph
-from optimize.redundancies import remove_redundant_jumps, remove_redundancies
+from optimize.redundancies import remove_redundant_jumps, remove_redundancies,\
+        remove_redundant_branch_jumps
 from optimize.advanced import eliminate_common_subexpressions, \
         fold_constants, copy_propagation, eliminate_dead_code
 from writer import write_statements
@@ -65,42 +66,24 @@ class Program(Block):
         if not hasattr(self, 'statements'):
             self.statements = self.get_statements()
 
-        return remove_redundant_jumps(self)
+        return remove_redundant_jumps(self) \
+               | remove_redundant_branch_jumps(self)
 
     def optimize_blocks(self):
         """Optimize on block level. Keep executing all optimizations until no
         more changes occur."""
-        self.program_iterations = self.block_iterations = 0
-        program_changed = True
-
-        while program_changed:
-            self.program_iterations += 1
-            program_changed = False
-
-            for block in self.blocks:
-                self.block_iterations += 1
-                block_changed = True
-
-                while block_changed:
-                    block_changed = False
-
-                    if remove_redundancies(block):
-                        block_changed = True
-
-                    if eliminate_common_subexpressions(block):
-                        block_changed = True
-
-                    if fold_constants(block):
-                        block_changed = True
-
-                    if copy_propagation(block):
-                        block_changed = True
-
-                    if eliminate_dead_code(block):
-                        block_changed = True
-
-                    if block_changed:
-                        program_changed = True
+        changed = False
+
+        for block in self.blocks:
+            print 'block iteration'
+            if remove_redundancies(block) \
+                    | eliminate_common_subexpressions(block) \
+                    | fold_constants(block) \
+                    | copy_propagation(block) \
+                    | eliminate_dead_code(block):
+                changed = True
+
+        return changed
 
     def find_basic_blocks(self):
         """Divide the statement list into basic blocks."""

+ 46 - 0
tests/test_liveness.py

@@ -63,3 +63,49 @@ class TestLiveness(unittest.TestCase):
         self.assertEqual(b2.live_out, set(['b', 'd']))
         self.assertEqual(b3.live_in, set(['b', 'd']))
         self.assertEqual(b3.live_out, set())
+        
+#    def test_create_in_out_two(self):    
+#        s11 = S('command', 'subu', 'i', 'm', '0x00000001')
+#        s12 = S('command', 'move', 'j', 'n')
+#        s13 = S('command', 'move', 'a', 'u1')
+#        s14 = S('command', 'subu', 'i', 'm', '0x00000001')
+#        s15 = S('command', 'j', 'L1')
+#        s16 = S('')
+#        
+#        s21 = S('label', 'L1')
+#        s22 = S('command', 'addi', 'i', '0x00000001')
+#        s23 = S('command', 'subi', 'j', '0x00000001')
+#        s24 = S('command', 'j', 'L2')
+#        
+#        s31 = S('label', 'L2')
+#        s32 = S('command', 'move', 'a', 'u2')
+#        s33 = S('command', 'j', 'L1')        
+
+#        s41 = S('label', 'L3')
+#        s42 = S('command', 'move', 'i', 'u3')
+#        s43 = S('command', 'beq', 'g', 'd', 'L4')
+#        
+#        s51 = S('label', 'L4')
+#        s52 = S('command', 'addu', 'b', 'i', 'a')
+#        
+#        b1, b2, b3, b4 = find_basic_blocks([s11, s12, s13, s14, s15, s21, s22,\
+#                                s31, s32, s33, s41, s42, s43, s51])
+
+#        generate_flow_graph([b1, b2, b3, b4, b5])
+#        create_in_out([b1, b2, b3, b4, b5])
+#        
+#        
+        
+        #self.assertEqual(b1.)
+
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        

+ 9 - 8
tests/test_optimize.py

@@ -1,6 +1,7 @@
 import unittest
 
-from src.optimize.redundancies import remove_redundancies, remove_redundant_jumps
+from src.optimize.redundancies import remove_redundancies, \
+    remove_redundant_jumps, remove_redundant_branch_jumps
 from src.program import Program
 from src.statement import Statement as S, Block as B
 
@@ -199,12 +200,12 @@ class TestOptimize(unittest.TestCase):
                    S('command', 'j', '$L1'),
                    S('label', '$L1'),
                    self.bar])
-                   
-       remove_redundancies(block)
+        
+        remove_redundant_jumps(block)
        
-       self.assertEqual(block.statements, B([self.foo, 
-                                             S('command', 'j', '$L1'),
-                                             self.bar]))
+        self.assertEqual(block.statements, [self.foo, 
+                                             S('label', '$L1'),
+                                             self.bar])
                                              
     def test_remove_redundant_jumps_false(self):
         arguments = [self.foo,
@@ -213,9 +214,9 @@ class TestOptimize(unittest.TestCase):
                    self.bar]
         block = B(arguments)
                    
-       remove_redundancies(block)
+        remove_redundant_jumps(block)
        
-       self.assertEqual(block.statements, arguments)
+        self.assertEqual(block.statements, arguments)
         
     def test_remove_redundant_branch_jumps_beq_j_true(self):
         block = B([self.foo,