annotate python/ir/module.py @ 171:3eb9b9e2958d

Improved IR code
author Windel Bouwman
date Wed, 03 Apr 2013 22:20:20 +0200
parents 4348da5ca307
children 5a7d37d615ee
rev   line source
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
1 # IR-Structures:
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
2 from .instruction import *
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
3 from .basicblock import BasicBlock
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 156
diff changeset
4
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 147
diff changeset
5 class Module:
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
6 """ Main container for a piece of code. """
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 147
diff changeset
7 def __init__(self, name):
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 147
diff changeset
8 self.name = name
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
9 self.bbs = []
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
10 def __repr__(self):
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
11 return 'IR-module [{0}]'.format(self.name)
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 147
diff changeset
12 def getInstructions(self):
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
13 ins = []
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
14 for bb in self.bbs:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
15 ins += bb.Instructions
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
16 return ins
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 147
diff changeset
17 Instructions = property(getInstructions)
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
18 def addBB(self, bb):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
19 self.bbs.append(bb)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
20 def getBBs(self):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
21 return self.bbs
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
22 BasicBlocks = property(getBBs)
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
23 def dump(self):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
24 print(self)
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
25 for i in self.Instructions:
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
26 print(i, 'live vars:', list(i.live_in), 'uses', list(i.uses), 'defs', list(i.defs))
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
27 print('END')
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
28 def dumpgv(self, outf):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
29 outf.write('digraph G \n{\n')
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
30 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
31 outf.write('{0} [label="{1}"];\n'.format(id(i), i))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
32 for succ in i.succ:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
33 outf.write('"{0}" -> "{1}" [label="{2}"];\n'.format(id(i), id(succ), succ.live_in))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
34 outf.write('}\n')
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 147
diff changeset
35
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
36 # Analysis functions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
37 def check(self):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
38 """ Perform sanity check on module """
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
39 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
40 for t in i.defs:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
41 assert type(t) is Value, "def must be Value, not {0}".format(type(t))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
42 for t in i.uses:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
43 assert type(t) is Value, "use must be Value, not {0}".format(type(t))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
44 def analyze(self):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
45 # Determine pred and succ:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
46 def link(a, b):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
47 a.succ.add(b)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
48 b.pred.add(a)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
49 for bb in self.bbs:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
50 if not bb.Empty:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
51 if len(bb.Instructions) > 1:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
52 for i1, i2 in zip(bb.Instructions[:-1], bb.Instructions[1:]):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
53 link(i1, i2)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
54 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
55 print('Only 1 long!', bb, bb.Instructions)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
56 if type(bb.LastIns) is ConditionalBranch:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
57 link(bb.LastIns, bb.LastIns.lab1.FirstIns)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
58 link(bb.LastIns, bb.LastIns.lab2.FirstIns)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
59 if type(bb.LastIns) is Branch:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
60 link(bb.LastIns, bb.LastIns.target.FirstIns)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
61 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
62 print('Empty!', bb)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
63 # We now have cfg
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
64
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
65 # Determine liveness:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
66 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
67 i.live_in = set()
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
68 i.live_out = set()
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
69 for z in range(50):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
70 # TODO iterate until converge
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
71 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
72 lo_mk = i.live_out.difference(i.defs)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
73 i.live_in = i.uses.union(lo_mk)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
74 lo = set()
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
75 for s in i.succ:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
76 lo = lo.union(s.live_in)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
77 i.live_out = lo
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
78 def constantProp(self):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
79 """ Constant propagation. Pre-calculate constant values """
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
80 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
81 if type(i) is ImmLoad:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
82 i.target.constval = i.value
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
83 elif type(i) is BinaryOperator:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
84 a = i.value1
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
85 b = i.value2
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
86 if i.value1.constval and i.value2.constval:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
87 op = i.operation
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
88 if op == '+':
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
89 i.result.constval = a + b
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
90 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
91 raise NotImplementedError(op)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
92 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
93 i.result.constval = None
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
94
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
95 def registerAllocate(self, regs):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
96 print(regs)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
97 allVals = []
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
98 # construct interference:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
99 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
100 for v in i.live_in:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
101 allVals.append(v)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
102 for v2 in i.live_in:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
103 if v != v2:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
104 v.interferes.add(v2)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
105 # assign random registers:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
106 print(allVals)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
107 regs = set(regs)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
108 for v in allVals:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
109 takenregs = set([iv.reg for iv in v.interferes])
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
110 r2 = list(regs.difference(takenregs))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
111 # Pick next available:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
112 v.reg = r2[0]
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
113