Przeglądaj źródła

Implemented all global optimizations from the practicum page (without tests).

Taddeus Kroes 14 lat temu
rodzic
commit
f2126f9004
2 zmienionych plików z 36 dodań i 9 usunięć
  1. 30 5
      src/optimize.py
  2. 6 4
      src/utils.py

+ 30 - 5
src/optimize.py

@@ -1,4 +1,4 @@
-from utils import Statement as S, find_basic_blocks
+from utils import find_basic_blocks
 
 
 def optimize_branch_jump_label(statements):
@@ -38,16 +38,19 @@ def optimize_global(statements):
             s = statements.read()
 
             # mov $regA,$regB           ->  --- remove it
-            if s.is_command() and s.name == 'move' and s[0] == s[1]:
+            if s.is_command('move') and s[0] == s[1]:
                 statements.replace(1, [])
+                continue
 
             # mov $regA,$regB           ->  instr $regA, $regB, ...
             # instr $regA, $regA, ...
-            if s.is_command() and s.name == 'move':
+            if s.is_command('move'):
                 ins = statements.peek()
 
                 if ins and len(ins) >= 2 and ins[0] == s[0] and ins[1] == s[0]:
                     ins[1] = s[1]
+                    statements.replace(2, [ins])
+                    continue
 
             # instr $regA, ...          ->  instr $4, ...
             # mov $4, $regA                 jal XX
@@ -62,22 +65,44 @@ def optimize_global(statements):
                             and jal.name == 'jal':
                         s[0] = mov[0]
                         statements.replace(1, [], start=statements.pointer + 1)
+                        continue
 
             # sw $regA, XX              ->  sw $regA, XX
             # ld $regA, XX
+            if s.is_command('sw'):
+                ld = statements.peek()
+
+                if ld.is_command('ld') and ld.args == s.args:
+                    statements.replace(2, [ld])
+                    continue
 
             # shift $regA, $regA, 0     ->  --- remove it
             if s.is_shift() and s[0] == s[1] and s[2] == 0:
                 statements.replace(1, [])
+                continue
 
             # add $regA, $regA, X       ->  lw ..., X($regA)
             # lw ..., 0($regA)
+            if s.is_command('add') and s[0] == s[1]:
+                lw = statements.peek()
+
+                if lw.is_command('lw') and lw[-1] == '0(%s)' % s[0]:
+                    lw[-1] = s[2] + lw[1:]
+                    statements.replace(2, [lw])
+                    continue
 
             #     beq ..., $Lx          ->      bne ..., $Ly
             #     j $Ly                     $Lx:
             # $Lx:
-            #if block.peek(3):
-            #    block.replace(3, [nieuwe statements])
+            if s.is_command('beq'):
+                following = statements.peek(2)
+
+                if len(following) == 2:
+                    j, label = following
+
+                    if j.is_command('s') and label.is_label(s[2]):
+                        s[2] = label.name
+                        statements.replace(3, [s, label])
 
     return statements
 

+ 6 - 4
src/utils.py

@@ -37,11 +37,13 @@ class Statement:
     def is_directive(self):
         return self.stype == 'directive'
 
-    def is_label(self):
-        return self.stype == 'label'
+    def is_label(self, name=None):
+        return self.stype == 'label' if name == None \
+                else self.stype == 'label' and self.name == name
 
-    def is_command(self):
-        return self.stype == 'command'
+    def is_command(self, name=None):
+        return self.stype == 'command' if name == None \
+                else self.stype == 'command' and self.name == name
 
     def is_jump(self):
         """Check if the statement is a jump."""