comparison 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
comparison
equal deleted inserted replaced
316:56e6ff84f646 317:e30a77ae359b
11 self.logger = logging.getLogger(str(self.__class__.__name__)) 11 self.logger = logging.getLogger(str(self.__class__.__name__))
12 12
13 def run(self, ir): 13 def run(self, ir):
14 """ Main entry point for the pass """ 14 """ Main entry point for the pass """
15 self.logger.info('Running pass {}'.format(type(self))) 15 self.logger.info('Running pass {}'.format(type(self)))
16 ir.check()
17 self.prepare() 16 self.prepare()
18 for f in ir.Functions: 17 for f in ir.Functions:
19 self.onFunction(f) 18 self.onFunction(f)
20 ir.check()
21 19
22 def onFunction(self, f): 20 def onFunction(self, f):
23 """ Override this virtual method """ 21 """ Override this virtual method """
24 raise NotImplementedError() 22 raise NotImplementedError()
25 23
117 constMap[k] = i.result 115 constMap[k] = i.result
118 for i in to_remove: 116 for i in to_remove:
119 self.logger.debug('removing {}'.format(i)) 117 self.logger.debug('removing {}'.format(i))
120 bb.removeInstruction(i) 118 bb.removeInstruction(i)
121 119
120 class RemoveAddZero(InstructionPass):
121 def onInstruction(self, i):
122 if type(i) is ir.Binop:
123 print(i)
124 pass
122 125
123 class CleanPass(FunctionPass): 126 class CleanPass(FunctionPass):
124 def onFunction(self, f): 127 def onFunction(self, f):
125 self.remove_empty_blocks(f) 128 self.remove_empty_blocks(f)
129 self.remove_one_preds(f)
126 130
127 def remove_empty_blocks(self, f): 131 def remove_empty_blocks(self, f):
128 """ Remove empty basic blocks from function. """ 132 """ Remove empty basic blocks from function. """
129 # If a block only contains a branch, it can be removed: 133 # If a block only contains a branch, it can be removed:
130 empty = lambda b: type(b.FirstInstruction) is ir.Jump 134 empty = lambda b: type(b.FirstInstruction) is ir.Jump
137 tgt = b.LastInstruction.target 141 tgt = b.LastInstruction.target
138 for pred in preds: 142 for pred in preds:
139 pred.LastInstruction.changeTarget(b, tgt) 143 pred.LastInstruction.changeTarget(b, tgt)
140 self.logger.debug('Removing empty block: {}'.format(b)) 144 self.logger.debug('Removing empty block: {}'.format(b))
141 f.removeBlock(b) 145 f.removeBlock(b)
146
147 def remove_one_preds(self, f):
148 """ Remove basic blocks with only one predecessor """
149 change = True
150 while change:
151 change = False
152 for block in f.Blocks:
153 preds = block.Predecessors
154 if len(preds) == 1 and block not in preds and type(preds[0].LastInstruction) is ir.Jump and block is not f.epiloog:
155 self.glue_blocks(preds[0], block, f)
156 change = True
157
158 def glue_blocks(self, block1, block2, f):
159 """ Glue two blocks together into the first block """
160 self.logger.info('Glueing {} and {}'.format(block1, block2))
161
162 # Remove the last jump:
163 block1.removeInstruction(block1.LastInstruction)
164
165 # Copy all instructions to block1:
166 for instruction in block2.Instructions:
167 block1.addInstruction(instruction)
168 # This does not work somehow:
169 #block2.parent.removeBlock(block2)