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