annotate python/ir/module.py @ 172:5a7d37d615ee

Added function to IR
author Windel Bouwman
date Thu, 04 Apr 2013 17:58:37 +0200
parents 3eb9b9e2958d
children c1d2b6b9f9a7
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
172
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
9 self.funcs = []
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 = []
172
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
14 for bb in self.BasicBlocks:
171
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 getBBs(self):
172
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
19 bbs = []
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
20 for f in self.Functions:
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
21 bbs += f.BasicBlocks
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
22 return bbs
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
23 BasicBlocks = property(getBBs)
172
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
24 def addFunc(self, f):
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
25 self.funcs.append(f)
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
26 def getFuncs(self):
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
27 return self.funcs
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
28 Functions = property(getFuncs)
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
29 def dump(self):
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
30 print(self)
172
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
31 for fn in self.Functions:
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
32 print(fn)
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
33 for bb in fn.BasicBlocks:
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
34 print(' ', bb)
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
35 for ins in bb.Instructions:
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
36 print(' ', ins)
170
4348da5ca307 Cleanup of ir dir
Windel Bouwman
parents: 158
diff changeset
37 print('END')
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
38 def dumpgv(self, outf):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
39 outf.write('digraph G \n{\n')
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
40 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
41 outf.write('{0} [label="{1}"];\n'.format(id(i), i))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
42 for succ in i.succ:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
43 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
44 outf.write('}\n')
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 147
diff changeset
45
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
46 # Analysis functions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
47 def check(self):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
48 """ Perform sanity check on module """
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
49 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
50 for t in i.defs:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
51 assert type(t) is Value, "def must be Value, not {0}".format(type(t))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
52 for t in i.uses:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
53 assert type(t) is Value, "use must be Value, not {0}".format(type(t))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
54 def analyze(self):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
55 # Determine pred and succ:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
56 def link(a, b):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
57 a.succ.add(b)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
58 b.pred.add(a)
172
5a7d37d615ee Added function to IR
Windel Bouwman
parents: 171
diff changeset
59 for bb in self.BasicBlocks:
171
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
60 if not bb.Empty:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
61 if len(bb.Instructions) > 1:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
62 for i1, i2 in zip(bb.Instructions[:-1], bb.Instructions[1:]):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
63 link(i1, i2)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
64 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
65 print('Only 1 long!', bb, bb.Instructions)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
66 if type(bb.LastIns) is ConditionalBranch:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
67 link(bb.LastIns, bb.LastIns.lab1.FirstIns)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
68 link(bb.LastIns, bb.LastIns.lab2.FirstIns)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
69 if type(bb.LastIns) is Branch:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
70 link(bb.LastIns, bb.LastIns.target.FirstIns)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
71 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
72 print('Empty!', bb)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
73 # We now have cfg
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
74
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
75 # Determine liveness:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
76 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
77 i.live_in = set()
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
78 i.live_out = set()
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
79 for z in range(50):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
80 # TODO iterate until converge
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
81 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
82 lo_mk = i.live_out.difference(i.defs)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
83 i.live_in = i.uses.union(lo_mk)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
84 lo = set()
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
85 for s in i.succ:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
86 lo = lo.union(s.live_in)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
87 i.live_out = lo
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
88 def constantProp(self):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
89 """ Constant propagation. Pre-calculate constant values """
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
90 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
91 if type(i) is ImmLoad:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
92 i.target.constval = i.value
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
93 elif type(i) is BinaryOperator:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
94 a = i.value1
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
95 b = i.value2
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
96 if i.value1.constval and i.value2.constval:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
97 op = i.operation
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
98 if op == '+':
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
99 i.result.constval = a + b
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
100 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
101 raise NotImplementedError(op)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
102 else:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
103 i.result.constval = None
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
104
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
105 def registerAllocate(self, regs):
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
106 print(regs)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
107 allVals = []
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
108 # construct interference:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
109 for i in self.Instructions:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
110 for v in i.live_in:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
111 allVals.append(v)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
112 for v2 in i.live_in:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
113 if v != v2:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
114 v.interferes.add(v2)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
115 # assign random registers:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
116 print(allVals)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
117 regs = set(regs)
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
118 for v in allVals:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
119 takenregs = set([iv.reg for iv in v.interferes])
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
120 r2 = list(regs.difference(takenregs))
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
121 # Pick next available:
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
122 v.reg = r2[0]
3eb9b9e2958d Improved IR code
Windel Bouwman
parents: 170
diff changeset
123