annotate python/ppci/transform.py @ 355:c2ddc8a36f5e

Enabled optimization
author Windel Bouwman
date Fri, 14 Mar 2014 10:30:13 +0100
parents d1ecc493384e
children c49459768aaa
rev   line source
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
1 """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
2 Transformation to optimize IR-code
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
3 """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
4
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
5 import logging
301
6753763d3bec merge codegen into ppci package
Windel Bouwman
parents: 300
diff changeset
6 from . import ir
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
7 # Standard passes:
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
8
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
9 class FunctionPass:
255
7416c923a02a Added more logging
Windel Bouwman
parents: 253
diff changeset
10 def __init__(self):
316
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
11 self.logger = logging.getLogger(str(self.__class__.__name__))
255
7416c923a02a Added more logging
Windel Bouwman
parents: 253
diff changeset
12
355
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
13 def run(self, ir_module):
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
14 """ Main entry point for the pass """
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 317
diff changeset
15 self.logger.debug('Running pass {}'.format(self.__class__.__name__))
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
16 self.prepare()
355
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
17 if isinstance(ir_module, ir.Module):
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
18 for f in ir_module.Functions:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
19 self.onFunction(f)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
20 elif isinstance(ir_module, ir.Function):
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
21 self.onFunction(ir_module)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
22 else:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
23 raise Exception()
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
24
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
25 def onFunction(self, f):
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
26 """ Override this virtual method """
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
27 raise NotImplementedError()
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
28
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
29 def prepare(self):
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
30 pass
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
31
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
32
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
33 class BasicBlockPass(FunctionPass):
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
34 def onFunction(self, f):
274
ea93e0a7a31e Move docs
Windel Bouwman
parents: 261
diff changeset
35 for bb in f.Blocks:
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
36 self.onBasicBlock(bb)
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
37
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
38 def onBasicBlock(self, bb):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
39 """ Override this virtual method """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
40 raise NotImplementedError()
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
41
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
42
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
43 class InstructionPass(BasicBlockPass):
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
44 def onBasicBlock(self, bb):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
45 for ins in iter(bb.Instructions):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
46 self.onInstruction(ins)
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
47
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
48 def onInstruction(self, ins):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
49 """ Override this virtual method """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
50 raise NotImplementedError()
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
51
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
52
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
53 class BasePass(BasicBlockPass):
255
7416c923a02a Added more logging
Windel Bouwman
parents: 253
diff changeset
54 def onBasicBlock(self, bb):
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
55 pass
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
56
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
57
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
58 # Usefull transforms:
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
59 class ConstantFolder(BasePass):
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
60 def __init__(self):
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
61 super().__init__()
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
62 self.ops = {}
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
63 self.ops['+'] = lambda x, y: x + y
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
64 self.ops['-'] = lambda x, y: x - y
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
65 self.ops['*'] = lambda x, y: x * y
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
66 self.ops['<<'] = lambda x, y: x << y
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
67
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
68 def postExpr(self, expr):
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
69 if type(i) is BinaryOperator and i.operation in self.ops.keys() and type(i.a) is Const and type(i.b) is Const:
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
70 vr = self.ops[i.operation](i.a.value, i.b.value)
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
71 return Const(vr)
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
72 else:
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 274
diff changeset
73 return expr
237
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
74
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
75
174
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
76 class DeadCodeDeleter(BasicBlockPass):
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
77 def onBasicBlock(self, bb):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
78 def instructionUsed(ins):
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
79 if not type(ins) in [ImmLoad, BinaryOperator]:
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
80 return True
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
81 if len(ins.defs) == 0:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
82 # In case this instruction does not define any
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
83 # variables, assume it is usefull.
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
84 return True
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
85 return any(d.Used for d in ins.defs)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
86
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
87 change = True
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
88 while change:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
89 change = False
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
90 for i in bb.Instructions:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
91 if instructionUsed(i):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
92 continue
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
93 bb.removeInstruction(i)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
94 change = True
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
95
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
96
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
97 class CommonSubexpressionElimination(BasicBlockPass):
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
98 def onBasicBlock(self, bb):
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
99 constMap = {}
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
100 to_remove = []
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
101 for i in bb.Instructions:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
102 if isinstance(i, ImmLoad):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
103 if i.value in constMap:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
104 t_new = constMap[i.value]
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
105 t_old = i.target
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
106 logging.debug('Replacing {} with {}'.format(t_old, t_new))
261
444b9df2ed99 try to split up code generation
Windel Bouwman
parents: 255
diff changeset
107 t_old.replaceby(t_new)
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
108 to_remove.append(i)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
109 else:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
110 constMap[i.value] = i.target
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
111 elif isinstance(i, BinaryOperator):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
112 k = (i.value1, i.operation, i.value2)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
113 if k in constMap:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
114 t_old = i.result
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
115 t_new = constMap[k]
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
116 logging.debug('Replacing {} with {}'.format(t_old, t_new))
261
444b9df2ed99 try to split up code generation
Windel Bouwman
parents: 255
diff changeset
117 t_old.replaceby(t_new)
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
118 to_remove.append(i)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
119 else:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
120 constMap[k] = i.result
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
121 for i in to_remove:
316
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
122 self.logger.debug('removing {}'.format(i))
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
123 bb.removeInstruction(i)
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
124
355
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
125
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
126 child_nodes = {}
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
127 child_nodes[ir.Binop] = ['a', 'b']
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
128 child_nodes[ir.Const] = []
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
129 child_nodes[ir.Temp] = []
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
130 child_nodes[ir.Exp] = ['e']
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
131 child_nodes[ir.Mem] = ['e']
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
132 child_nodes[ir.Addr] = ['e']
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
133 child_nodes[ir.LocalVariable] = []
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
134 child_nodes[ir.Parameter] = []
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
135 child_nodes[ir.Jump] = []
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
136 child_nodes[ir.Terminator] = []
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
137 child_nodes[ir.Call] = ['arguments']
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
138 child_nodes[ir.CJump] = ['a', 'b']
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
139 child_nodes[ir.Move] = ['src', 'dst']
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
140
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
141
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
142 def apply_function(x, f):
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
143 """ Recursively apply function """
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
144 # Handle list:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
145 if type(x) is list:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
146 for i in range(len(x)):
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
147 x[i] = apply_function(x[i], f)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
148 return x
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
149
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
150 # Normal node:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
151 for child in child_nodes[type(x)]:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
152 v = getattr(x, child)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
153 v = apply_function(v, f)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
154 assert not (v is None)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
155 setattr(x, child, v)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
156 # Apply function!
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
157 return f(x)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
158
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
159
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
160 class ExpressionFixer(InstructionPass):
317
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
161 def onInstruction(self, i):
355
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
162 apply_function(i, self.grok)
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
163
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
164
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
165 class RemoveAddZero(ExpressionFixer):
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
166 def grok(self, v):
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
167 if type(v) is ir.Binop:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
168 if v.operation == '+':
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
169 if type(v.b) is ir.Const and v.b.value == 0:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
170 self.logger.debug('Folding {} to {}'.format(v, v.a))
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
171 return v.a
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
172 elif v.operation == '*':
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
173 if type(v.b) is ir.Const and v.b.value == 1:
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
174 self.logger.debug('Multiple 1 {} to {}'.format(v, v.a))
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
175 return v.a
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
176 return v
c2ddc8a36f5e Enabled optimization
Windel Bouwman
parents: 336
diff changeset
177
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
178
177
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
179 class CleanPass(FunctionPass):
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
180 def onFunction(self, f):
316
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
181 self.remove_empty_blocks(f)
317
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
182 self.remove_one_preds(f)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
183
316
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
184 def remove_empty_blocks(self, f):
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
185 """ Remove empty basic blocks from function. """
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
186 # If a block only contains a branch, it can be removed:
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
187 empty = lambda b: type(b.FirstInstruction) is ir.Jump
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
188 empty_blocks = list(filter(empty, f.Blocks))
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
189 for b in empty_blocks:
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
190 # Update predecessors
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
191 preds = b.Predecessors
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
192 if b not in preds + [f.entry]:
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
193 # Do not remove if preceeded by itself
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
194 tgt = b.LastInstruction.target
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
195 for pred in preds:
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
196 pred.LastInstruction.changeTarget(b, tgt)
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
197 self.logger.debug('Removing empty block: {}'.format(b))
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 301
diff changeset
198 f.removeBlock(b)
317
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
199
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
200 def remove_one_preds(self, f):
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
201 """ Remove basic blocks with only one predecessor """
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
202 change = True
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
203 while change:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
204 change = False
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
205 for block in f.Blocks:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
206 preds = block.Predecessors
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
207 if len(preds) == 1 and block not in preds and type(preds[0].LastInstruction) is ir.Jump and block is not f.epiloog:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
208 self.glue_blocks(preds[0], block, f)
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
209 change = True
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
210
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
211 def glue_blocks(self, block1, block2, f):
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
212 """ Glue two blocks together into the first block """
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 334
diff changeset
213 self.logger.debug('Merging {} and {}'.format(block1.name, block2.name))
317
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
214
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
215 # Remove the last jump:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
216 block1.removeInstruction(block1.LastInstruction)
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
217
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
218 # Copy all instructions to block1:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
219 for instruction in block2.Instructions:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
220 block1.addInstruction(instruction)
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
221 # This does not work somehow:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 316
diff changeset
222 #block2.parent.removeBlock(block2)