comparison python/codegenarm.py @ 277:046017431c6a

Started register allocator
author Windel Bouwman
date Thu, 26 Sep 2013 21:14:25 +0200
parents 56d37ed4b4d2
children 2ccd57b1d78c
comparison
equal deleted inserted replaced
276:56d37ed4b4d2 277:046017431c6a
1 import logging 1 import logging
2 import ir 2 import ir
3 from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo 3 from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo
4 import cortexm3 as arm 4 import cortexm3 as arm
5 from ppci import CompilerError 5 from ppci import CompilerError
6 import flowgraph
7 import registerallocator 6 import registerallocator
8 from instructionselector import InstructionSelector 7 from instructionselector import InstructionSelector
9 import irmach 8 import irmach
10 from irmach import makeIns 9 from irmach import makeIns
11 import canon 10 import canon
208 class ArmCodeGenerator: 207 class ArmCodeGenerator:
209 def __init__(self, outs): 208 def __init__(self, outs):
210 # TODO: schedule traces in better order. 209 # TODO: schedule traces in better order.
211 # This is optional! 210 # This is optional!
212 self.ins_sel = ArmInstructionSelector() 211 self.ins_sel = ArmInstructionSelector()
212 self.ra = registerallocator.RegisterAllocator()
213 self.outs = outs 213 self.outs = outs
214 self.outs.getSection('code').address = 0x08000000 214 self.outs.getSection('code').address = 0x08000000
215 self.outs.getSection('data').address = 0x20000000 215 self.outs.getSection('data').address = 0x20000000
216 216
217 def useUnused(self, inslist):
218 # Use unused temporaries at the end of the list
219 defTemps = []
220 useTemps = []
221 for i in inslist:
222 for d in iter(i.dst):
223 defTemps.append(d)
224 for s in iter(i.src):
225 useTemps.append(s)
226 defTemps = set(defTemps)
227 useTemps = set(useTemps)
228 unUsed = defTemps - useTemps
229 assert not unUsed
230 for uu in unUsed:
231 inslist.append(irmach.AbstractInstruction('use %s0', src=[uu]))
232 #print(useTemps)
233
234 def allocFrame(self, f):
235 """
236 Do register allocation for a single stack frame.
237 """
238 ilist = f.instructions
239 self.useUnused(ilist)
240 cfg = flowgraph.FlowGraph(ilist)
241 f.cfg = cfg
242 ig = registerallocator.InterferenceGraph(cfg)
243 f.ig = ig
244
245 ra = registerallocator.RegisterAllocator()
246 regMap = ra.registerAllocate(ig, f.regs, f.tempMap)
247 # Use allocated registers:
248 for i in ilist:
249 i.src = tuple(regMap[t] for t in i.src)
250 i.dst = tuple(regMap[t] for t in i.dst)
251
252 def generateFunc(self, irfunc): 217 def generateFunc(self, irfunc):
253 # Create a frame for this function: 218 # Create a frame for this function:
254 frame = ArmFrame(irfunc.name) 219 frame = ArmFrame(irfunc.name)
220
255 # Canonicalize the intermediate language: 221 # Canonicalize the intermediate language:
256 canon.make(irfunc, frame) 222 canon.make(irfunc, frame)
257 # print('after canonicalize:') 223 print('after canonicalize:')
258 # irfunc.dump() 224 irfunc.dump()
259 self.ins_sel.munchFunction(irfunc, frame) 225 self.ins_sel.munchFunction(irfunc, frame)
260 # print('Selected instructions:') 226 print('Selected instructions:')
261 #for i in frame.instructions: 227 for i in frame.instructions:
262 # print(i) 228 print(i)
263 229
264 # Do register allocation: 230 # Do register allocation:
265 self.allocFrame(frame) 231 self.ra.allocFrame(frame)
266 # TODO: Peep-hole here? 232 # TODO: Peep-hole here?
267 233
268 # Add label and return and stack adjustment: 234 # Add label and return and stack adjustment:
269 frame.EntryExitGlue3() 235 frame.EntryExitGlue3()
270 return frame 236 return frame