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