Mercurial > lcfOS
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)