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

Merge branch 'master' of github.com:taddeus/peephole

Richard Torenvliet 14 лет назад
Родитель
Сommit
e3caa5f91d
3 измененных файлов с 47 добавлено и 17 удалено
  1. 2 2
      src/optimize/__init__.py
  2. 42 12
      src/optimize/advanced.py
  3. 3 3
      src/statement.py

+ 2 - 2
src/optimize/__init__.py

@@ -31,9 +31,9 @@ def optimize_block(block):
     while remove_redundancies(block) \
     while remove_redundancies(block) \
             | eliminate_common_subexpressions(block) \
             | eliminate_common_subexpressions(block) \
             | fold_constants(block) \
             | fold_constants(block) \
-            | copy_propagation(block)\
-            | algebraic_transformations(block) \
+            | copy_propagation(block) \
             | eliminate_dead_code(block):
             | eliminate_dead_code(block):
+            #| algebraic_transformations(block) \
         pass
         pass
 
 
 
 

+ 42 - 12
src/optimize/advanced.py

@@ -149,22 +149,44 @@ def fold_constants(block):
             register[s[0]] = constants[s[1]]
             register[s[0]] = constants[s[1]]
         elif s.name == 'mflo':
         elif s.name == 'mflo':
             # Move of `Lo' register to another register
             # Move of `Lo' register to another register
-            register[s[0]] = register['Lo']
+            register[s[0]] = register['$lo']
         elif s.name == 'mfhi':
         elif s.name == 'mfhi':
             # Move of `Hi' register to another register
             # Move of `Hi' register to another register
-            register[s[0]] = register['Hi']
+            register[s[0]] = register['$hi']
         elif s.name in ['mult', 'div'] \
         elif s.name in ['mult', 'div'] \
-                and s[0] in register and s[1] in register:
+                and s[0]in register and s[1] in register:
             # Multiplication/division with constants
             # Multiplication/division with constants
             rs, rt = s
             rs, rt = s
+            a, b = register[rs], register[rt]
 
 
             if s.name == 'mult':
             if s.name == 'mult':
-                binary = bin(register[rs] * register[rt])[2:]
-                binary = '0' * (64 - len(binary)) + binary
-                register['Hi'] = int(binary[:32], base=2)
-                register['Lo'] = int(binary[32:], base=2)
+                if not a or not b:
+                    # Multiplication by 0
+                    hi = lo = to_hex(0)
+                elif a == 1:
+                    # Multiplication by 1
+                    hi = to_hex(0)
+                    lo = to_hex(b)
+                elif b == 1:
+                    # Multiplication by 1
+                    hi = to_hex(0)
+                    lo = to_hex(a)
+                else:
+                    # Calculate result and fill Hi/Lo registers
+                    binary = bin(a * b)[2:]
+                    binary = '0' * (64 - len(binary)) + binary
+                    hi = int(binary[:32], base=2)
+                    lo = int(binary[32:], base=2)
+
+                # Replace the multiplication with two immidiate loads to the
+                # Hi/Lo registers
+                block.replace(1, [S('command', 'li', '$hi', hi),
+                                S('command', 'li', '$lo', li)])
             elif s.name == 'div':
             elif s.name == 'div':
-                register['Lo'], register['Hi'] = divmod(rs, rt)
+                lo, hi = divmod(rs, rt)
+
+            register['$lo'], register['$hi'] = lo, hi
+            changed = True
         elif s.name in ['addu', 'subu']:
         elif s.name in ['addu', 'subu']:
             # Addition/subtraction with constants
             # Addition/subtraction with constants
             rd, rs, rt = s
             rd, rs, rt = s
@@ -187,7 +209,9 @@ def fold_constants(block):
                 block.replace(1, [S('command', 'li', rd, result)])
                 block.replace(1, [S('command', 'li', rd, result)])
                 register[rd] = result
                 register[rd] = result
                 changed = True
                 changed = True
-            elif rt_known:
+                continue
+
+            if rt_known:
                 # a = 10        ->  b = c + 10
                 # a = 10        ->  b = c + 10
                 # b = c + a
                 # b = c + a
                 s[2] = register[rt]
                 s[2] = register[rt]
@@ -198,9 +222,15 @@ def fold_constants(block):
                 s[1] = rt
                 s[1] = rt
                 s[2] = register[rs]
                 s[2] = register[rs]
                 changed = True
                 changed = True
-        elif len(s) and s[0] in register:
-            # Known register is overwritten, remove its value
-            del register[s[0]]
+
+            if s[2] == 0:
+                # Addition/subtraction with 0
+                block.replace(1, [S('command', 'move', rd, s[1])])
+        else:
+            for reg in s.get_def():
+                if reg in register:
+                    # Known register is overwritten, remove its value
+                    del register[reg]
 
 
     return changed
     return changed
 
 

+ 3 - 3
src/statement.py

@@ -111,8 +111,8 @@ class Statement:
         """Check if the statement is a logical operator."""
         """Check if the statement is a logical operator."""
         return self.is_command() and re.match('^(xor|or|and)i?$', self.name)
         return self.is_command() and re.match('^(xor|or|and)i?$', self.name)
     
     
-    def is_double_aritmethic(self):
-        """Check if the statement is a aritmethic .d operator."""
+    def is_double_arithmetic(self):
+        """Check if the statement is a arithmetic .d operator."""
         return self.is_command() and \
         return self.is_command() and \
                 re.match('^(add|sub|div|mul)\.d$', self.name)
                 re.match('^(add|sub|div|mul)\.d$', self.name)
                 
                 
@@ -153,7 +153,7 @@ class Statement:
         instr = ['move', 'addu', 'subu', 'li', 'mtc1', 'dmfc1', 'mov.d']
         instr = ['move', 'addu', 'subu', 'li', 'mtc1', 'dmfc1', 'mov.d']
         
         
         if self.is_load_non_immediate() or self.is_arith() \
         if self.is_load_non_immediate() or self.is_arith() \
-                or self.is_logical() or self.is_double_aritmethic() \
+                or self.is_logical() or self.is_double_arithmetic() \
                 or self.is_move_from_spec() or self.is_double_unary() \
                 or self.is_move_from_spec() or self.is_double_unary() \
                 or self.is_set_if_less() or self.is_convert() \
                 or self.is_set_if_less() or self.is_convert() \
                 or self.is_truncate() or self.is_load() \
                 or self.is_truncate() or self.is_load() \