annotate python/transform.py @ 249:e41e4109addd

Added current position arrow
author Windel Bouwman
date Fri, 26 Jul 2013 20:26:05 +0200
parents 6259856841a0
children c4370696ccc7
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
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
5 from ir import *
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
6 # Standard passes:
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
7
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
8 class FunctionPass:
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
9 def run(self, ir):
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
10 """ Main entry point for the pass """
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
11 self.prepare()
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
12 for f in ir.Functions:
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
13 self.onFunction(f)
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
14 def onFunction(self, f):
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
15 """ Override this virtual method """
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
16 raise NotImplementedError()
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
17 def prepare(self):
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
18 pass
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
19
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
20
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
21 class BasicBlockPass(FunctionPass):
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
22 def onFunction(self, f):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
23 for bb in f.BasicBlocks:
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
24 self.onBasicBlock(bb)
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
25
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
26 def onBasicBlock(self, bb):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
27 """ Override this virtual method """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
28 raise NotImplementedError()
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
29
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
30
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
31 class InstructionPass(BasicBlockPass):
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
32 def onBasicBlock(self, bb):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
33 for ins in iter(bb.Instructions):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
34 self.onInstruction(ins)
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
35
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
36 def onInstruction(self, ins):
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
37 """ Override this virtual method """
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
38 raise NotImplementedError()
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
39
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
40 # Usefull transforms:
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
41 class ConstantFolder(InstructionPass):
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
42 def prepare(self):
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
43 self.constMap = {}
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
44 def onInstruction(self, i):
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
45 if type(i) is ImmLoad:
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
46 self.constMap[i.target] = i.value
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
47 elif type(i) is BinaryOperator:
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
48 if i.value1 in self.constMap and i.value2 in self.constMap:
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
49 op = i.operation
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
50 va = self.constMap[i.value1]
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
51 vb = self.constMap[i.value2]
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
52 if op == '+':
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
53 vr = va + vb
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
54 elif op == '*':
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
55 vr = va * vb
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
56 elif op == '-':
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
57 vr = va - vb
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
58 else:
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
59 vr = None
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
60 return
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
61 self.constMap[i.result] = vr
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
62 i.removeDef(i.result)
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
63 i2 = ImmLoad(i.result, vr)
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
64 i.Parent.replaceInstruction(i, i2)
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
65
237
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
66
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
67 class ConstantMerge(InstructionPass):
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
68 def prepare(self):
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
69 self.constMap = {}
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
70 def onInstruction(self, i):
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
71 if type(i) is ImmLoad:
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
72 v = i.value
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
73 if v in self.constMap:
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
74 # v is already defined, re-use the imm-load from elsewhere
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
75 pass
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
76 else:
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
77 self.constMap[v] = i
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
78 elif type(i) is BinaryOperator:
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
79 if i.value1 in self.constMap and i.value2 in self.constMap:
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
80 op = i.operation
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
81 va = self.constMap[i.value1]
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
82 vb = self.constMap[i.value2]
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
83 if op == '+':
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
84 vr = va + vb
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
85 elif op == '*':
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
86 vr = va * vb
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
87 elif op == '-':
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
88 vr = va - vb
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
89 else:
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
90 vr = None
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
91 return
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
92 self.constMap[i.result] = vr
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
93 i2 = ImmLoad(i.result, vr)
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
94 i.Parent.replaceInstruction(i, i2)
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
95
81752b0f85a5 Added burn led test program
Windel Bouwman
parents: 235
diff changeset
96
174
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
97 class DeadCodeDeleter(BasicBlockPass):
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
98 def onBasicBlock(self, bb):
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
99 def instructionUsed(ins):
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
100 if len(ins.defs) == 0:
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
101 # In case this instruction does not define any
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
102 # variables, assume it is usefull.
174
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
103 return True
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
104 for d in ins.defs:
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
105 if d.IsUsed:
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
106 return True
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
107 return False
3eb06f5fb987 Added memory alloc for locals
Windel Bouwman
parents: 173
diff changeset
108 bb.Instructions = list(filter(instructionUsed, bb.Instructions))
173
c1d2b6b9f9a7 Rework into passes
Windel Bouwman
parents:
diff changeset
109
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
110
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
111 class SameImmLoadDeletePass(BasicBlockPass):
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
112 def onBasicBlock(self, bb):
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
113 constMap = {}
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
114 imms = filter(lambda i: isinstance(i, ImmLoad), bb.Instructions)
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
115 for ins in list(imms):
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
116 if ins.value in constMap:
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
117 # remove this immload and update all references to the target
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
118 t_old = ins.target
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
119 if not t_old.onlyUsedInBlock(bb):
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
120 continue
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
121 # update all references:
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
122 t_new = constMap[ins.value]
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
123 for use in t_old.used_by:
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
124 use.replaceValue(t_old, t_new)
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
125 bb.removeInstruction(ins)
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
126 else:
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
127 constMap[ins.value] = ins.target
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
128
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
129
175
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
130 def isAllocPromotable(allocinst):
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
131 # Check if alloc value is only used by load and store operations.
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
132 assert type(allocinst) is Alloc
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
133 for use in ai.value.used_by:
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
134 if not type(use.user) in [Load, Store]:
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
135 # TODO: check volatile
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
136 return False
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
137 otherUse = True
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
138 return True
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
139
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
140
177
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
141 class CleanPass(FunctionPass):
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
142 def onFunction(self, f):
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
143 bbs = list(f.BasicBlocks)
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
144 for bb in bbs:
177
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
145 # TODO: determine check for 'empty'
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
146
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
147 # If a block only contains a branch, it can be removed:
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
148 if len(bb.Instructions) == 1 and type(bb.LastInstruction) is Branch:
177
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
149 # This block is empty.
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
150 # find predecessors of this block and replace this block reference with the jumped reference.
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
151 ins = bb.LastInstruction
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
152 preds = bb.Predecessors
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
153 if bb in preds:
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
154 # Do not remove if preceeded by itself
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
155 pass
239
63bb40758066 added check
Windel Bouwman
parents: 237
diff changeset
156 else:
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
157 for pred in bb.Predecessors:
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
158 pred.LastInstruction.changeTarget(bb, ins.target)
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 177
diff changeset
159 f.removeBasicBlock(bb)
177
460db5669efa Added clean pass for IR
Windel Bouwman
parents: 176
diff changeset
160
240
6259856841a0 Remove project
Windel Bouwman
parents: 239
diff changeset
161
175
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
162 class Mem2RegPromotor(FunctionPass):
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
163 def onFunction(self, f):
176
5fd02aa38b42 Added while loop code generation
Windel Bouwman
parents: 175
diff changeset
164 # TODO
235
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 225
diff changeset
165 pass
175
a51b3c956386 Added function call in expressions
Windel Bouwman
parents: 174
diff changeset
166