Taddeüs Kroes пре 14 година
родитељ
комит
5cb0ae4b44
3 измењених фајлова са 49 додато и 15 уклоњено
  1. 9 4
      src/basic_block.py
  2. 9 11
      src/optimize.py
  3. 31 0
      src/optimizer.py

+ 9 - 4
src/basic_block.py

@@ -1,5 +1,6 @@
-# TODO: Get all jump commands
-JUMP_COMMANDS = ['j', 'jal']
+# TODO: JALR & JR
+JUMP_COMMANDS = ['j', 'jal', 'beq', 'bne', 'blez', 'bgtz', 'bltz', 'bgez', \
+                 'bc1f', 'bc1t']
 
 def is_jump(statement):
     '''Check if a statement is a jump command.'''
@@ -17,10 +18,12 @@ def find_leaders(statements):
     for i, statement in enumerate(statements[1:]):
         if is_jump(statement):
             leaders.append(i + 2)
-            jump_target_labels.append(statement[2]['args'][0])
+            print statement[2]['args'][-1]
+            jump_target_labels.append(statement[2]['args'][-1])
             #print 'found jump:', i, statement
 
-    #print 'target labels:', jump_target_labels
+    print 'target labels:', jump_target_labels
+    print 'leaders:', leaders
 
     # Append jump targets
     for i, statement in enumerate(statements[1:]):
@@ -41,4 +44,6 @@ def find_basic_blocks(statements):
     for i in range(len(leaders) - 1):
         blocks.append(statements[leaders[i]:leaders[i + 1]])
 
+    blocks.append(statements[leaders[-1]:])
+
     return blocks

+ 9 - 11
src/optimize.py

@@ -1,6 +1,7 @@
 #!/usr/bin/python
 from parser import parse_file
 from basic_block import find_basic_blocks
+from optimizer import optimize_blocks
 from writer import write_statements
 
 if __name__ == '__main__':
@@ -10,23 +11,20 @@ if __name__ == '__main__':
         print 'Usage: python %s FILE' % argv[0]
         exit(1)
 
+    # Parse File
     statements = parse_file(argv[1])
-    blocks = find_basic_blocks(statements)
-    out = write_statements(statements)
-
-    statement_no = 1
 
-    for i, block in enumerate(blocks):
-        #print 'basic block %d:' % i
+    # Create basic blocks
+    blocks = find_basic_blocks(statements)
 
-        for statement in block:
-            #print statement_no, statement
-            statement_no += 1
+    # Optimize basic blocks
+    statements = optimize_blocks(blocks)
 
-    #print '\nOut:'
-    #print out
+    # Rewrite to assembly
+    out = write_statements(statements)
 
     if len(argv) > 2:
+        # Save output assembly
         f = open(argv[2], 'w+')
         f.write(out)
         f.close()

+ 31 - 0
src/optimizer.py

@@ -0,0 +1,31 @@
+def optimize_blocks(blocks):
+    '''Call the optimizer for each basic block. Do this several times until
+    no more optimizations are achieved.'''
+    changed = True
+    
+    while changed:
+        changed = False
+        optimized = []
+        
+        for block in blocks:
+            block_changed, b = optimize_block(block)
+            optimized.append(b)
+            
+            if block_changed:
+                changed = True
+            
+        blocks = optimized
+    
+    return reduce(lambda a, b: a + b, blocks, [])
+
+def optimize_block(statements):
+    '''Optimize a basic block.'''
+    changed = False
+    output_statements = []
+    
+    for statement in statements:
+        new_statement = statement
+        
+        output_statements.append(new_statement)
+
+    return changed, output_statements