Преглед изворни кода

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

Jayke Meijer пре 14 година
родитељ
комит
158030a203
2 измењених фајлова са 51 додато и 10 уклоњено
  1. 23 0
      src/liveness.py
  2. 28 10
      src/optimize/advanced.py

+ 23 - 0
src/liveness.py

@@ -1,6 +1,29 @@
 from copy import copy
 
 
+RESERVED_REGISTERS = ['$fp', '$sp']
+
+
+def is_reg_dead_after(reg, block, index):
+    """Check if a register is dead after a certain point in a basic block."""
+    if reg in RESERVED_REGISTERS:
+        return False
+
+    if index < len(block) - 1:
+        for s in block[index + 1:]:
+            # If used, the previous definition is live
+            if s.uses(reg):
+                return False
+
+            # If redefined, the previous definition is dead
+            if s.defines(reg):
+                return True
+
+    # If dead within the same block, check if the register is in the block's
+    # live_out set
+    return reg not in block.live_out
+
+
 def create_use_def(block):
     used = set()
     defined = set()

+ 28 - 10
src/optimize/advanced.py

@@ -1,6 +1,8 @@
-from src.statement import Statement as S
 from math import log
 
+from src.statement import Statement as S
+from src.liveness import is_reg_dead_after
+
 
 def reg_can_be_used_in(reg, block, start, end):
     """Check if a register addres safely be used in a block section using local
@@ -393,25 +395,41 @@ def eliminate_dead_code(block):
       is not used in the rest of the block, and is not in the `out' set of the
       block.
     """
-    # TODO: Finish
     changed = False
-    unused = set()
 
-    for s in reversed(block):
+    for n, s in enumerate(block):
         for reg in s.get_def():
-            if reg in unused:
+            if is_reg_dead_after(reg, block, n):
                 # Statement is redefined later, so this statement is useless
                 if block.debug:
                     s.stype = 'comment'
                     s.options['block'] = False
-                    s.name = ' Dead code: %s %s' \
-                            % (s.name, ', '.join(map(str, s)))
+                    s.name = ' Dead:\t%s\t%s' \
+                            % (s.name, ','.join(map(str, s)))
                 else:
                     s.remove = True
-            else:
-                unused.add(reg)
 
-        unused -= set(s.get_use())
+                changed = True
+
+    #unused = set()
+
+    #for s in reversed(block):
+    #    for reg in s.get_def():
+    #        if reg in unused:
+    #            # Statement is redefined later, so this statement is useless
+    #            if block.debug:
+    #                s.stype = 'comment'
+    #                s.options['block'] = False
+    #                s.name = ' Dead:\t%s\t%s' \
+    #                        % (s.name, ','.join(map(str, s)))
+    #            else:
+    #                s.remove = True
+
+    #            changed = True
+    #        else:
+    #            unused.add(reg)
+
+    #    unused -= set(s.get_use())
 
     if not block.debug:
         block.apply_filter(lambda s: not hasattr(s, 'remove'))