Răsfoiți Sursa

Added j-label optimization.

Jayke Meijer 14 ani în urmă
părinte
comite
ff70b6484d
2 a modificat fișierele cu 70 adăugiri și 30 ștergeri
  1. 18 1
      src/optimize/redundancies.py
  2. 52 29
      tests/test_optimize.py

+ 18 - 1
src/optimize/redundancies.py

@@ -123,8 +123,25 @@ 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)
+        
+        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, [])
+                        
+def remove_redundant_branch_jumps(statements):
     """Optimize statement sequences on a global level."""
     old_len = -1
 

+ 52 - 29
tests/test_optimize.py

@@ -172,72 +172,95 @@ class TestOptimize(unittest.TestCase):
         self.assertEquals(block.statements, arguments)
         self.assertEquals(block2.statements, arguments2)
         self.assertEquals(block3.statements, arguments3)
+        
+    def test_optimize_block_move_move_true(self):
+        block = B([self.foo,
+                   S('command', 'move', '$regA', '$regB'),
+                   S('command', 'move', '$regB', '$regA'),
+                   self.bar])
+        remove_redundancies(block)
+
+        self.assertEquals(block.statements, [self.foo,
+                   S('command', 'move', '$regA', '$regB'),
+                   self.bar])
+
+    def test_optimize_block_mov_mov_false(self):
+        arguments = [self.foo, \
+                     S('command', 'move', '$regA', '$regB'), \
+                     S('command', 'move', '$regB', '$regC'), \
+                     self.bar]
+        block = B(arguments)
+        remove_redundancies(block)
 
-    def test_remove_redundant_jumps_beq_j_true(self):
+        self.assertEquals(block.statements, arguments)
+        
+    def test_remove_redundant_jumps_true(self):
+        block = B([self.foo,
+                   S('command', 'j', '$L1'),
+                   S('label', '$L1'),
+                   self.bar])
+                   
+       remove_redundancies(block)
+       
+       self.assertEqual(block.statements, B([self.foo, 
+                                             S('command', 'j', '$L1'),
+                                             self.bar]))
+                                             
+    def test_remove_redundant_jumps_false(self):
+        arguments = [self.foo,
+                   S('command', 'j', '$L1'),
+                   S('label', '$L2'),
+                   self.bar]
+        block = B(arguments)
+                   
+       remove_redundancies(block)
+       
+       self.assertEqual(block.statements, arguments)
+        
+    def test_remove_redundant_branch_jumps_beq_j_true(self):
         block = B([self.foo,
                    S('command', 'beq', '$regA', '$regB', '$Lx'),
                    S('command', 'j', '$Ly'),
                    S('label', '$Lx'),
                    self.bar])
-        remove_redundant_jumps(block)
+        remove_redundant_branch_jumps(block)
 
         self.assertEquals(block.statements, [self.foo,
                    S('command', 'bne', '$regA', '$regB', '$Ly'),
                    S('label', '$Lx'),
                    self.bar])
 
-    def test_remove_redundant_jumps_beq_j_false(self):
+    def test_remove_redundant_branch_jumps_beq_j_false(self):
         arguments = [self.foo, \
                      S('command', 'beq', '$regA', '$regB', '$Lz'), \
                      S('command', 'j', '$Ly'), \
                      S('label', '$Lx'), \
                      self.bar]
         block = B(arguments)
-        remove_redundant_jumps(block)
+        remove_redundant_branch_jumps(block)
 
         self.assertEquals(block.statements, arguments)
 
-    def test_remove_redundant_jumps_bne_j_true(self):
+    def test_remove_redundant_branch_jumps_bne_j_true(self):
         block = B([self.foo,
                    S('command', 'bne', '$regA', '$regB', '$Lx'),
                    S('command', 'j', '$Ly'),
                    S('label', '$Lx'),
                    self.bar])
-        remove_redundant_jumps(block)
+        remove_redundant_branch_jumps(block)
 
         self.assertEquals(block.statements, [self.foo,
                    S('command', 'beq', '$regA', '$regB', '$Ly'),
                    S('label', '$Lx'),
                    self.bar])
 
-    def test_remove_redundant_jumps_bne_j_false(self):
+    def test_remove_redundant_branch_jumps_bne_j_false(self):
         arguments = [self.foo, \
                      S('command', 'bne', '$regA', '$regB', '$Lz'), \
                      S('command', 'j', '$Ly'), \
                      S('label', '$Lx'), \
                      self.bar]
         block = B(arguments)
-        remove_redundant_jumps(block)
-
-        self.assertEquals(block.statements, arguments)
-
-    def test_optimize_block_move_move_true(self):
-        block = B([self.foo,
-                   S('command', 'move', '$regA', '$regB'),
-                   S('command', 'move', '$regB', '$regA'),
-                   self.bar])
-        remove_redundancies(block)
-
-        self.assertEquals(block.statements, [self.foo,
-                   S('command', 'move', '$regA', '$regB'),
-                   self.bar])
-
-    def test_optimize_block_mov_mov_false(self):
-        arguments = [self.foo, \
-                     S('command', 'move', '$regA', '$regB'), \
-                     S('command', 'move', '$regB', '$regC'), \
-                     self.bar]
-        block = B(arguments)
-        remove_redundancies(block)
+        remove_redundant_branch_jumps(block)
 
         self.assertEquals(block.statements, arguments)