Răsfoiți Sursa

Fixed infinite loop in optimization phase.

Taddeus Kroes 14 ani în urmă
părinte
comite
fd60f13d5f
6 a modificat fișierele cu 32 adăugiri și 20 ștergeri
  1. 1 1
      main.py
  2. 12 1
      src/optimize/__init__.py
  3. 3 3
      src/optimize/advanced.py
  4. 9 7
      src/optimize/redundancies.py
  5. 3 4
      src/program.py
  6. 4 4
      src/statement.py

+ 1 - 1
main.py

@@ -13,7 +13,7 @@ if __name__ == '__main__':
 
     # Parse file
     program = parse_file(argv[1])
-    program.debug = True
+    program.verbose = 1
 
     if len(argv) > 3:
         # Save input assembly in new file for easy comparison

+ 12 - 1
src/optimize/__init__.py

@@ -12,13 +12,21 @@ def optimize(program, verbose=0):
     o = program.count_instructions()
 
     changed = True
+    iterations = 0
 
     while changed:
-        print 'main iteration'
+        iterations += 1
+
+        if verbose > 1:
+            print 'main iteration %d', iterations
+
         changed = False
 
         # Optimize on a global level
         if program.optimize_global():
+            if verbose > 1:
+                print 'changed on global level'
+
             changed = True
 
         # Perform dataflow analysis on new blocks
@@ -26,6 +34,9 @@ def optimize(program, verbose=0):
 
         # Optimize basic blocks
         if program.optimize_blocks():
+            if verbose > 1:
+                print 'changed on block level'
+
             changed = True
 
     # Count number of instructions after optimization

+ 3 - 3
src/optimize/advanced.py

@@ -274,7 +274,7 @@ def fold_constants(block):
                     del register[reg]
                     known.append((reg, 'unknown'))
 
-        if block.debug and len(known):
+        if block.verbose and len(known):
             s.set_inline_comment(','.join([' %s = %s' % k for k in known]))
 
     return changed
@@ -401,7 +401,7 @@ def eliminate_dead_code(block):
         for reg in s.get_def():
             if is_reg_dead_after(reg, block, n):
                 # Statement is redefined later, so this statement is useless
-                if block.debug:
+                if block.verbose:
                     s.stype = 'comment'
                     s.options['block'] = False
                     s.set_inline_comment(' dead register %s' % reg)
@@ -411,7 +411,7 @@ def eliminate_dead_code(block):
 
                 changed = True
 
-    if not block.debug:
+    if not block.verbose:
         block.apply_filter(lambda s: not hasattr(s, 'remove'))
 
     return changed

+ 9 - 7
src/optimize/redundancies.py

@@ -3,7 +3,7 @@ import re
 
 def remove_redundancies(block):
     """Execute all functions that remove redundant statements."""
-    callbacks = [move_aa, move_inst, instr_move_jal, move_move, sw_ld, shift, 
+    callbacks = [move_aa, move_inst, instr_move_jal, move_move, sw_ld, shift,
                  add_lw]
     old_len = -1
     changed = False
@@ -126,8 +126,9 @@ def add_lw(add, statements):
 def remove_redundant_jumps(statements):
     """Remove jump if label follows immediately."""
     changed = False
-        
+
     statements.reset()
+
     while not statements.end():
         s = statements.read()
 
@@ -135,18 +136,19 @@ def remove_redundant_jumps(statements):
         # $Lx:
         if s.is_command('j'):
             following = statements.peek()
-            
+
             if following.is_label(s[0]):
                 statements.replace(1, [])
                 changed = True
-                    
-    return True
-                        
+
+    return changed
+
 def remove_redundant_branch_jumps(statements):
     """Optimize statement sequences on a global level."""
     changed = False
 
     statements.reset()
+
     while not statements.end():
         s = statements.read()
 
@@ -164,5 +166,5 @@ def remove_redundant_branch_jumps(statements):
                     s[2] = j[0]
                     statements.replace(3, [s, label])
                     changed = True
-                        
+
     return changed

+ 3 - 4
src/program.py

@@ -21,8 +21,8 @@ class Program(Block):
         if hasattr(self, 'statements'):
             return self.statements
 
-        # Only add block start and end comments when in debug mode
-        if add_block_comments and self.debug:
+        # Only add block start and end comments when in verbose mode
+        if add_block_comments and self.verbose:
             get_id = lambda b: b.bid
             statements = []
 
@@ -75,7 +75,6 @@ class Program(Block):
         changed = False
 
         for block in self.blocks:
-            print 'block iteration'
             if remove_redundancies(block) \
                     | eliminate_common_subexpressions(block) \
                     | fold_constants(block) \
@@ -90,7 +89,7 @@ class Program(Block):
         self.blocks = find_basic_blocks(self.statements)
 
         for b in self.blocks:
-            b.debug = self.debug
+            b.verbose = self.verbose
 
         # Remove the old statement list, since it will probably change
         del self.statements

+ 4 - 4
src/statement.py

@@ -231,7 +231,7 @@ class Statement:
 class Block:
     bid = 1
 
-    def __init__(self, statements=[], debug=False):
+    def __init__(self, statements=[], verbose=False):
         self.statements = statements
         self.pointer = 0
 
@@ -239,7 +239,7 @@ class Block:
         self.bid = Block.bid
         Block.bid += 1
 
-        self.debug = debug
+        self.verbose = verbose
 
     def __str__(self):
         return '<Block bid=%d statements=%d>' % (self.bid, len(self))
@@ -288,7 +288,7 @@ class Block:
             start = self.pointer - 1
 
         # Add a message in inline comments
-        if self.debug:
+        if self.verbose:
             if len(message):
                 message = ' ' + message
 
@@ -313,7 +313,7 @@ class Block:
         if index == None:
             index = self.pointer
 
-        if self.debug and len(message):
+        if self.verbose and len(message):
             statement.set_inline_comment(' ' + message)
 
         self.statements.insert(index, statement)