Răsfoiți Sursa

Added algebraic conversions and first unittest for those.

Jayke Meijer 14 ani în urmă
părinte
comite
45947974dc
2 a modificat fișierele cu 38 adăugiri și 1 ștergeri
  1. 27 0
      src/optimize/advanced.py
  2. 11 1
      tests/test_optimize_advanced.py

+ 27 - 0
src/optimize/advanced.py

@@ -208,3 +208,30 @@ def copy_propagation(block):
             changed = True
                           
     return changed
+    
+    
+def algebraic_transformations(block):
+    """
+    Change ineffective or useless algebraic transformations. Handled are:
+    - x = x + 0 -> remove
+    - x = x - 0 -> remove
+    - x = x * 1 -> remove
+    - x = x * 2 -> x = x << 1
+    """
+    changed = False
+    
+    while not block.end():
+        changed = True
+        s = block.read()
+        
+        if (s.is_command('addu') or s.is_command('subu')) and s[2] == 0:
+            block.replace(1, [])
+        elif s.is_command('mult') and s[2] == 1:
+            block.replace(1, [])
+        elif s.is_command('mult') and s[2] == 2:
+            new_command = S(['command', 'sll', s[0], s[1], 1])
+            block.replace(1, [new_command])
+        else:
+            changed = False
+            
+    return changed

+ 11 - 1
tests/test_optimize_advanced.py

@@ -1,7 +1,7 @@
 import unittest
 
 from src.optimize.advanced import eliminate_common_subexpressions, \
-        fold_constants, copy_propagation
+        fold_constants, copy_propagation, algebraic_transformations
 from src.statement import Statement as S, Block as B
 
 
@@ -63,3 +63,13 @@ class TestOptimizeAdvanced(unittest.TestCase):
         block = B(arguments)
         self.assertFalse(copy_propagation(block))
         self.assertEqual(block.statements, arguments)
+        
+    def test_algebraic_transforms_add0(self):
+        block = B([self.foo,
+                   S('command', 'addu', '$1', '$2', 0),
+                   self.bar])
+                   
+#        self.assertTrue(copy_propagation(block))
+        algebraic_transformations(block)
+        self.assertEqual(block.statements, [self.foo,
+                   self.bar])