Mercurial > lcfOS
comparison python/ppci/irutils.py @ 307:e609d5296ee9
Massive rewrite of codegenerator
author | Windel Bouwman |
---|---|
date | Thu, 12 Dec 2013 20:42:56 +0100 |
parents | |
children | 68b01c8abf8a |
comparison
equal
deleted
inserted
replaced
306:b145f8e6050b | 307:e609d5296ee9 |
---|---|
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) |