Просмотр исходного кода

Algebraic transformations unittested.

Jayke Meijer 14 лет назад
Родитель
Сommit
b279082a6d
2 измененных файлов с 85 добавлено и 5 удалено
  1. 10 5
      src/optimize/advanced.py
  2. 75 0
      tests/test_optimize_advanced.py

+ 10 - 5
src/optimize/advanced.py

@@ -1,5 +1,5 @@
 from src.statement import Statement as S
 from src.statement import Statement as S
-
+from math import log
 
 
 def create_variable():
 def create_variable():
     return '$15'
     return '$15'
@@ -223,6 +223,7 @@ def algebraic_transformations(block):
     - x = x + 0 -> remove
     - x = x + 0 -> remove
     - x = x - 0 -> remove
     - x = x - 0 -> remove
     - x = x * 1 -> remove
     - x = x * 1 -> remove
+    - x = x * 0 -> x = 0
     - x = x * 2 -> x = x << 1
     - x = x * 2 -> x = x << 1
     """
     """
     changed = False
     changed = False
@@ -236,10 +237,14 @@ def algebraic_transformations(block):
         elif s.is_command('mult') and s[2] == 1:
         elif s.is_command('mult') and s[2] == 1:
             block.replace(1, [])
             block.replace(1, [])
             changed = True
             changed = True
-        elif s.is_command('mult') and s[2] == 2:
-            new_command = S(['command', 'sll', 
-            s[0], s[1], 1])
-            block.replace(1, [new_command])
+        elif s.is_command('mult') and s[2] == 0:
+            block.replace(1, [S('command', 'li', '$1', to_hex(0))])
             changed = True
             changed = True
+        elif s.is_command('mult'):   
+            shift_amount = log(s[2], 2)
+            if shift_amount.is_integer():
+                new_command = S('command', 'sll', s[0], s[1], shift_amount)
+                block.replace(1, [new_command])
+                changed = True
             
             
     return changed
     return changed

+ 75 - 0
tests/test_optimize_advanced.py

@@ -79,3 +79,78 @@ class TestOptimizeAdvanced(unittest.TestCase):
         self.assertTrue(algebraic_transformations(block))
         self.assertTrue(algebraic_transformations(block))
         self.assertEqual(block.statements, [self.foo,
         self.assertEqual(block.statements, [self.foo,
                    self.bar])
                    self.bar])
+                   
+    def test_algebraic_transforms_add1(self):
+        arguments = [self.foo,
+                   S('command', 'addu', '$1', '$2', 1),
+                   self.bar]
+        block = B(arguments)
+                   
+        self.assertFalse(algebraic_transformations(block))
+        self.assertEqual(block.statements, arguments)
+        
+    def test_algebraic_transforms_sub0(self):
+        block = B([self.foo,
+                   S('command', 'subu', '$1', '$2', 0),
+                   self.bar])
+                   
+        self.assertTrue(algebraic_transformations(block))
+        self.assertEqual(block.statements, [self.foo,
+                   self.bar])
+                   
+    def test_algebraic_transforms_sub1(self):
+        arguments = [self.foo,
+                   S('command', 'subu', '$1', '$2', 1),
+                   self.bar]
+        block = B(arguments)
+                   
+        self.assertFalse(algebraic_transformations(block))
+        self.assertEqual(block.statements, arguments)
+    
+    def test_algebraic_transforms_mult0(self):
+        block = B([self.foo,
+                   S('command', 'mult', '$1', '$2', 0),
+                   self.bar])
+                   
+        self.assertTrue(algebraic_transformations(block))
+        self.assertEqual(block.statements, [self.foo,
+                         S('command', 'li', '$1', '0x00000000'),
+                         self.bar])
+    
+    def test_algebraic_transforms_mult1(self):
+        block = B([self.foo,
+                   S('command', 'mult', '$1', '$2', 1),
+                   self.bar])
+                   
+        self.assertTrue(algebraic_transformations(block))
+        self.assertEqual(block.statements, [self.foo,
+                   self.bar])
+                   
+    def test_algebraic_transforms_mult2(self):
+        block = B([self.foo,
+                   S('command', 'mult', '$1', '$2', 2),
+                   self.bar])
+                   
+        self.assertTrue(algebraic_transformations(block))
+        self.assertEqual(block.statements, [self.foo,
+                         S('command', 'sll', '$1', '$2', 1),
+                         self.bar])
+                         
+    def test_algebraic_transforms_mult16(self):
+        block = B([self.foo,
+                   S('command', 'mult', '$1', '$2', 16),
+                   self.bar])
+                   
+        self.assertTrue(algebraic_transformations(block))
+        self.assertEqual(block.statements, [self.foo,
+                         S('command', 'sll', '$1', '$2', 4),
+                         self.bar])
+
+    def test_algebraic_transforms_mult3(self):
+        arguments = [self.foo,
+                     S('command', 'mult', '$1', '$2', 3),
+                     self.bar]
+        block = B(arguments)
+                   
+        self.assertFalse(algebraic_transformations(block))
+        self.assertEqual(block.statements, arguments)