annotate python/transform.py @ 253:74c6a20302d5

Added better logging
author Windel Bouwman
date Wed, 31 Jul 2013 17:57:03 +0200
parents c4370696ccc7
children 7416c923a02a
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
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
6 from ir import *
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:
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
10 def run(self, ir):
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
11 """ Main entry point for the pass """
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
12 logging.info('Running pass {}'.format(type(self)))
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
13 self.prepare()
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
14 for f in ir.Functions:
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
15 self.onFunction(f)
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
16
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
17 def onFunction(self, f):
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
18 """ Override this virtual method """
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
19 raise NotImplementedError()
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
20
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
21 def prepare(self):
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
22 pass
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
23
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
24
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
25 class BasicBlockPass(FunctionPass):
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
26 def onFunction(self, f):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
27 for bb in f.BasicBlocks:
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
28 self.onBasicBlock(bb)
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
29
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
30 def onBasicBlock(self, bb):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
31 """ Override this virtual method """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
32 raise NotImplementedError()
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
33
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
34
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
35 class InstructionPass(BasicBlockPass):
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
36 def onBasicBlock(self, bb):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
37 for ins in iter(bb.Instructions):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
38 self.onInstruction(ins)
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
39
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
40 def onInstruction(self, ins):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
41 """ Override this virtual method """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
42 raise NotImplementedError()
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
43
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
44 # Usefull transforms:
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
45 class ConstantFolder(InstructionPass):
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
46 def prepare(self):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
47 self.constMap = {}
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
48
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
49 def onInstruction(self, i):
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
50 if type(i) is ImmLoad:
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
51 self.constMap[i.target] = i.value
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
52 elif type(i) is BinaryOperator:
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
53 if i.value1 in self.constMap and i.value2 in self.constMap and i.operation in ['+', '-', '*', '<<']:
237
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
54 op = i.operation
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
55 va = self.constMap[i.value1]
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
56 vb = self.constMap[i.value2]
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
57 if op == '+':
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
58 vr = va + vb
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
59 elif op == '*':
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
60 vr = va * vb
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
61 elif op == '-':
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
62 vr = va - vb
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
63 elif op == '<<':
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
64 vr = va << vb
237
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
65 else:
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
66 vr = None
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
67 return
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
68 self.constMap[i.result] = vr
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
69 i.removeDef(i.result)
237
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
70 i2 = ImmLoad(i.result, vr)
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
71 logging.debug('Replacing {}'.format(i))
237
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
72 i.Parent.replaceInstruction(i, i2)
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
73
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
74
174
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
75 class DeadCodeDeleter(BasicBlockPass):
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
76 def onBasicBlock(self, bb):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
77 def instructionUsed(ins):
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
78 if not type(ins) in [ImmLoad, BinaryOperator]:
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
79 return True
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
80 if len(ins.defs) == 0:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
81 # In case this instruction does not define any
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
82 # variables, assume it is usefull.
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
83 return True
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
84 return any(d.Used for d in ins.defs)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
85
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
86 change = True
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
87 while change:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
88 change = False
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
89 for i in bb.Instructions:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
90 if instructionUsed(i):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
91 continue
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
92 bb.removeInstruction(i)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
93 change = True
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
94
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
95
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
96 class CommonSubexpressionElimination(BasicBlockPass):
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
97 def onBasicBlock(self, bb):
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
98 constMap = {}
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
99 to_remove = []
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
100 for i in bb.Instructions:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
101 if isinstance(i, ImmLoad):
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
102 if i.value in constMap:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
103 t_new = constMap[i.value]
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
104 t_old = i.target
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
105 logging.debug('Replacing {} with {}'.format(t_old, t_new))
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
106 for ui in t_old.used_by:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
107 ui.replaceValue(t_old, t_new)
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))
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
117 for ui in t_old.used_by:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
118 ui.replaceValue(t_old, t_new)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
119 to_remove.append(i)
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
120 else:
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
121 constMap[k] = i.result
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
122 for i in to_remove:
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
123 logging.debug('removing {}'.format(i))
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
124 bb.removeInstruction(i)
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
125
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
126
177
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
127 class CleanPass(FunctionPass):
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
128 def onFunction(self, f):
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
129 bbs = list(f.BasicBlocks)
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
130 for bb in bbs:
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
131 # If a block only contains a branch, it can be removed:
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
132 if len(bb.Instructions) == 1 and type(bb.LastInstruction) is Branch:
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
133 # This block is empty.
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
134 # find predecessors of this block and replace this block reference with the jumped reference.
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
135 ins = bb.LastInstruction
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
136 preds = bb.Predecessors
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
137 if bb in preds:
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
138 # Do not remove if preceeded by itself
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
139 pass
253
74c6a20302d5 Added better logging
Windel Bouwman
parents: 252
diff changeset
140 else:
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
141 for pred in bb.Predecessors:
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
142 pred.LastInstruction.changeTarget(bb, ins.target)
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
143 f.removeBasicBlock(bb)
177
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
144
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
145
252
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
146
c4370696ccc7 added optimize function
Windel Bouwman
parents: 240
diff changeset
147