Mercurial > lcfOS
comparison python/ir/module.py @ 173:c1d2b6b9f9a7
Rework into passes
author | Windel Bouwman |
---|---|
date | Fri, 19 Apr 2013 12:42:21 +0200 |
parents | 5a7d37d615ee |
children | 3eb06f5fb987 |
comparison
equal
deleted
inserted
replaced
172:5a7d37d615ee | 173:c1d2b6b9f9a7 |
---|---|
35 for ins in bb.Instructions: | 35 for ins in bb.Instructions: |
36 print(' ', ins) | 36 print(' ', ins) |
37 print('END') | 37 print('END') |
38 def dumpgv(self, outf): | 38 def dumpgv(self, outf): |
39 outf.write('digraph G \n{\n') | 39 outf.write('digraph G \n{\n') |
40 for i in self.Instructions: | 40 for f in self.Functions: |
41 outf.write('{0} [label="{1}"];\n'.format(id(i), i)) | 41 outf.write('{0} [label="{1}"]\n'.format(id(f), f)) |
42 for succ in i.succ: | 42 for bb in f.BasicBlocks: |
43 outf.write('"{0}" -> "{1}" [label="{2}"];\n'.format(id(i), id(succ), succ.live_in)) | 43 contents = str(bb) + '\n' |
44 contents += '\n'.join([str(i) for i in bb.Instructions]) | |
45 outf.write('{0} [label="{1}"];\n'.format(id(bb), contents)) | |
46 for successor in bb.Successors: | |
47 outf.write('"{0}" -> "{1}"\n'.format(id(bb), id(successor))) | |
48 outf.write('"{0}" -> "{1}" [label="entry"]\n'.format(id(f), id(f.entry))) | |
44 outf.write('}\n') | 49 outf.write('}\n') |
45 | 50 |
46 # Analysis functions: | 51 # Analysis functions: |
47 def check(self): | 52 def check(self): |
48 """ Perform sanity check on module """ | 53 """ Perform sanity check on module """ |
49 for i in self.Instructions: | 54 for i in self.Instructions: |
50 for t in i.defs: | 55 for t in i.defs: |
51 assert type(t) is Value, "def must be Value, not {0}".format(type(t)) | 56 assert type(t) is Value, "def must be Value, not {0}".format(type(t)) |
52 for t in i.uses: | 57 for t in i.uses: |
53 assert type(t) is Value, "use must be Value, not {0}".format(type(t)) | 58 assert type(t) is Value, "use must be Value, not {0}".format(type(t)) |
54 def analyze(self): | |
55 # Determine pred and succ: | |
56 def link(a, b): | |
57 a.succ.add(b) | |
58 b.pred.add(a) | |
59 for bb in self.BasicBlocks: | |
60 if not bb.Empty: | |
61 if len(bb.Instructions) > 1: | |
62 for i1, i2 in zip(bb.Instructions[:-1], bb.Instructions[1:]): | |
63 link(i1, i2) | |
64 else: | |
65 print('Only 1 long!', bb, bb.Instructions) | |
66 if type(bb.LastIns) is ConditionalBranch: | |
67 link(bb.LastIns, bb.LastIns.lab1.FirstIns) | |
68 link(bb.LastIns, bb.LastIns.lab2.FirstIns) | |
69 if type(bb.LastIns) is Branch: | |
70 link(bb.LastIns, bb.LastIns.target.FirstIns) | |
71 else: | |
72 print('Empty!', bb) | |
73 # We now have cfg | |
74 | 59 |
75 # Determine liveness: | |
76 for i in self.Instructions: | |
77 i.live_in = set() | |
78 i.live_out = set() | |
79 for z in range(50): | |
80 # TODO iterate until converge | |
81 for i in self.Instructions: | |
82 lo_mk = i.live_out.difference(i.defs) | |
83 i.live_in = i.uses.union(lo_mk) | |
84 lo = set() | |
85 for s in i.succ: | |
86 lo = lo.union(s.live_in) | |
87 i.live_out = lo | |
88 def constantProp(self): | |
89 """ Constant propagation. Pre-calculate constant values """ | |
90 for i in self.Instructions: | |
91 if type(i) is ImmLoad: | |
92 i.target.constval = i.value | |
93 elif type(i) is BinaryOperator: | |
94 a = i.value1 | |
95 b = i.value2 | |
96 if i.value1.constval and i.value2.constval: | |
97 op = i.operation | |
98 if op == '+': | |
99 i.result.constval = a + b | |
100 else: | |
101 raise NotImplementedError(op) | |
102 else: | |
103 i.result.constval = None | |
104 | |
105 def registerAllocate(self, regs): | |
106 print(regs) | |
107 allVals = [] | |
108 # construct interference: | |
109 for i in self.Instructions: | |
110 for v in i.live_in: | |
111 allVals.append(v) | |
112 for v2 in i.live_in: | |
113 if v != v2: | |
114 v.interferes.add(v2) | |
115 # assign random registers: | |
116 print(allVals) | |
117 regs = set(regs) | |
118 for v in allVals: | |
119 takenregs = set([iv.reg for iv in v.interferes]) | |
120 r2 = list(regs.difference(takenregs)) | |
121 # Pick next available: | |
122 v.reg = r2[0] | |
123 |