269
|
1
|
|
2 import ir
|
|
3 import irmach
|
|
4
|
|
5 def genTemps():
|
|
6 n = 900
|
|
7 while True:
|
|
8 yield 't{}'.format(n)
|
|
9 n = n + 1
|
|
10
|
|
11 class InstructionSelector:
|
|
12 """
|
|
13 Base instruction selector. This class must be overridden by
|
|
14 backends.
|
|
15 """
|
|
16 def newTmp(self):
|
|
17 return self.temps.__next__()
|
|
18
|
|
19 def getTempReg(self, tmp):
|
|
20 if tmp not in self.tempMap:
|
|
21 self.tempMap[tmp] = self.newTmp()
|
|
22 return self.tempMap[tmp]
|
|
23
|
|
24 def munchProgram(self, p):
|
|
25 # Entry point for instruction selection
|
|
26 self.temps = genTemps()
|
|
27 assert isinstance(p, ir.Module)
|
274
|
28 self.frames = []
|
269
|
29 self.targets = {}
|
|
30 self.tempMap = {} # Mapping from temporaries to infinite register
|
|
31 for f in p.Functions:
|
274
|
32 # Enter a frame per function:
|
|
33 self.frame = self.newFrame(f.name)
|
|
34 self.frames.append(self.frame)
|
269
|
35 # First define labels:
|
274
|
36 for bb in f.Blocks:
|
269
|
37 itgt = self.makeIns('{}:'.format(bb.name))
|
|
38 self.targets[bb] = itgt
|
274
|
39 for bb in f.Blocks:
|
269
|
40 self.emit2(self.targets[bb])
|
|
41 for i in bb.Instructions:
|
|
42 self.munchStm(i)
|
274
|
43 #bb.machIns = self.result
|
|
44 return self.frames
|
269
|
45
|
|
46 def makeIns(self, *args, **kwargs):
|
|
47 return irmach.AbstractInstruction(*args, **kwargs)
|
|
48
|
|
49 def emit(self, *args, **kwargs):
|
|
50 """ Abstract instruction emitter """
|
|
51 i = self.makeIns(*args, **kwargs)
|
|
52 return self.emit2(i)
|
|
53
|
|
54 def emit2(self, i):
|
274
|
55 self.frame.instructions.append(i)
|
269
|
56 return i
|
|
57
|
274
|
58 def newFrame(self, name):
|
|
59 raise NotImplementedError()
|
|
60
|
269
|
61 def munchStm(self, s):
|
274
|
62 """ Implement this in the target specific back-end """
|
269
|
63 raise NotImplementedError()
|
|
64
|
|
65 def munchExpr(self, e):
|
274
|
66 """ Implement this in the target specific back-end """
|
269
|
67 raise NotImplementedError()
|
|
68
|