diff python/ppci/transform.py @ 317:e30a77ae359b

Added glue blocks
author Windel Bouwman
date Sun, 22 Dec 2013 15:50:59 +0100
parents 56e6ff84f646
children 6f4753202b9a
line wrap: on
line diff
--- a/python/ppci/transform.py	Sat Dec 21 13:13:26 2013 +0100
+++ b/python/ppci/transform.py	Sun Dec 22 15:50:59 2013 +0100
@@ -13,11 +13,9 @@
     def run(self, ir):
         """ Main entry point for the pass """
         self.logger.info('Running pass {}'.format(type(self)))
-        ir.check()
         self.prepare()
         for f in ir.Functions:
             self.onFunction(f)
-        ir.check()
 
     def onFunction(self, f):
         """ Override this virtual method """
@@ -119,10 +117,16 @@
             self.logger.debug('removing {}'.format(i))
             bb.removeInstruction(i)
 
+class RemoveAddZero(InstructionPass):
+    def onInstruction(self, i):
+        if type(i) is ir.Binop:
+            print(i)
+            pass
 
 class CleanPass(FunctionPass):
     def onFunction(self, f):
         self.remove_empty_blocks(f)
+        self.remove_one_preds(f)
 
     def remove_empty_blocks(self, f):
         """ Remove empty basic blocks from function. """
@@ -139,3 +143,27 @@
                       pred.LastInstruction.changeTarget(b, tgt)
                 self.logger.debug('Removing empty block: {}'.format(b))
                 f.removeBlock(b)
+
+    def remove_one_preds(self, f):
+        """ Remove basic blocks with only one predecessor """
+        change = True
+        while change:
+            change = False
+            for block in f.Blocks:
+                preds = block.Predecessors
+                if len(preds) == 1 and block not in preds and type(preds[0].LastInstruction) is ir.Jump and block is not f.epiloog:
+                    self.glue_blocks(preds[0], block, f)
+                    change = True
+
+    def glue_blocks(self, block1, block2, f):
+        """ Glue two blocks together into the first block """
+        self.logger.info('Glueing {} and {}'.format(block1, block2))
+
+        # Remove the last jump:
+        block1.removeInstruction(block1.LastInstruction)
+
+        # Copy all instructions to block1:
+        for instruction in block2.Instructions:
+            block1.addInstruction(instruction)
+        # This does not work somehow:
+        #block2.parent.removeBlock(block2)