307
|
1
|
|
2 """
|
|
3 Some utilities for ir-code.
|
|
4 """
|
|
5 from .ir import Temp, Block, Function, Statement
|
|
6
|
|
7 def dumpgv(m, outf):
|
|
8 print('digraph G ', file=outf)
|
|
9 print('{', file=outf)
|
|
10 for f in m.Functions:
|
|
11 print('{} [label="{}" shape=box3d]'.format(id(f), f), file=outf)
|
|
12 for bb in f.Blocks:
|
|
13 contents = str(bb) + '\n'
|
|
14 contents += '\n'.join([str(i) for i in bb.Instructions])
|
|
15 print('{0} [shape=note label="{1}"];'
|
|
16 .format(id(bb), contents), file=outf)
|
|
17 for successor in bb.Successors:
|
|
18 print('"{}" -> "{}"'.format(id(bb), id(successor)), file=outf)
|
|
19
|
|
20 print('"{}" -> "{}" [label="entry"]'
|
|
21 .format(id(f), id(f.entry)), file=outf)
|
|
22 print('}', file=outf)
|
|
23
|
|
24
|
|
25 # Constructing IR:
|
|
26
|
|
27 class NamedClassGenerator:
|
|
28 def __init__(self, prefix, cls):
|
|
29 self.prefix = prefix
|
|
30 self.cls = cls
|
|
31
|
|
32 def NumGen():
|
|
33 a = 0
|
|
34 while True:
|
|
35 yield a
|
|
36 a = a + 1
|
|
37 self.nums = NumGen()
|
|
38
|
|
39 def gen(self, prefix=None):
|
|
40 if not prefix:
|
|
41 prefix = self.prefix
|
|
42 return self.cls('{0}{1}'.format(prefix, self.nums.__next__()))
|
|
43
|
|
44
|
|
45 class Builder:
|
|
46 """ Base class for ir code generators """
|
|
47 def __init__(self):
|
|
48 self.prepare()
|
|
49
|
|
50 def prepare(self):
|
|
51 self.newTemp = NamedClassGenerator('reg', Temp).gen
|
|
52 self.newBlock2 = NamedClassGenerator('block', Block).gen
|
|
53 self.bb = None
|
|
54 self.m = None
|
|
55 self.fn = None
|
|
56 self.loc = None
|
|
57
|
|
58 # Helpers:
|
|
59 def setModule(self, m):
|
|
60 self.m = m
|
|
61
|
|
62 def newFunction(self, name):
|
|
63 f = Function(name)
|
|
64 self.m.addFunc(f)
|
|
65 return f
|
|
66
|
|
67 def newBlock(self):
|
|
68 assert self.fn
|
|
69 b = self.newBlock2()
|
|
70 b.function = self.fn
|
|
71 return b
|
|
72
|
|
73 def setFunction(self, f):
|
|
74 self.fn = f
|
|
75 self.bb = f.entry if f else None
|
|
76
|
|
77 def setBlock(self, b):
|
|
78 self.bb = b
|
|
79
|
|
80 def setLoc(self, l):
|
|
81 self.loc = l
|
|
82
|
|
83 def emit(self, i):
|
|
84 assert isinstance(i, Statement)
|
|
85 i.debugLoc = self.loc
|
|
86 if not self.bb:
|
|
87 raise Exception('No basic block')
|
|
88 self.bb.addInstruction(i)
|