comparison python/ppci/irutils.py @ 312:2c9768114877

Added cool logging formatter
author Windel Bouwman
date Mon, 16 Dec 2013 17:58:15 +0100
parents 68b01c8abf8a
children e30a77ae359b
comparison
equal deleted inserted replaced
311:ff665880a6b0 312:2c9768114877
1 1
2 """ 2 """
3 Some utilities for ir-code. 3 Some utilities for ir-code.
4 """ 4 """
5 import re 5 import re
6 from .ir import Temp, Block, Function, Statement
7 from . import ir 6 from . import ir
8 7
9 def dumpgv(m, outf): 8 def dumpgv(m, outf):
10 print('digraph G ', file=outf) 9 print('digraph G ', file=outf)
11 print('{', file=outf) 10 print('{', file=outf)
23 .format(id(f), id(f.entry)), file=outf) 22 .format(id(f), id(f.entry)), file=outf)
24 print('}', file=outf) 23 print('}', file=outf)
25 24
26 25
27 class Writer: 26 class Writer:
27 def __init__(self, extra_indent=''):
28 self.extra_indent = extra_indent
29
28 def write(self, ir, f): 30 def write(self, ir, f):
29 """ Write ir-code to file f """ 31 """ Write ir-code to file f """
30 print(ir, file=f) 32 print('{}{}'.format(self.extra_indent, ir), file=f)
31 for v in ir.Variables: 33 for v in ir.Variables:
32 print(str(v), file=f) 34 print('{}{}'.format(self.extra_indent, v), file=f)
33 for fn in ir.Functions: 35 for function in ir.Functions:
34 args = ','.join('i32 ' + str(a) for a in fn.arguments) 36 self.write_function(function, f)
35 print('function i32 {}({})'.format(fn.name, args), file=f) 37
36 for bb in fn.Blocks: 38 def write_function(self, fn, f):
37 print(' ' + str(bb), file=f) 39 args = ','.join('i32 ' + str(a) for a in fn.arguments)
38 for ins in bb.Instructions: 40 print('{}function i32 {}({})'.format(self.extra_indent, fn.name, args), file=f)
39 print(' ' + str(ins), file=f) 41 for bb in fn.Blocks:
42 print('{} {}'.format(self.extra_indent, bb), file=f)
43 for ins in bb.Instructions:
44 print('{} {}'.format(self.extra_indent, ins), file=f)
40 45
41 46
42 class IrParseException(Exception): 47 class IrParseException(Exception):
43 pass 48 pass
44 49
192 """ Base class for ir code generators """ 197 """ Base class for ir code generators """
193 def __init__(self): 198 def __init__(self):
194 self.prepare() 199 self.prepare()
195 200
196 def prepare(self): 201 def prepare(self):
197 self.newTemp = NamedClassGenerator('reg', Temp).gen 202 self.newTemp = NamedClassGenerator('reg', ir.Temp).gen
198 self.newBlock2 = NamedClassGenerator('block', Block).gen 203 self.newBlock2 = NamedClassGenerator('block', ir.Block).gen
199 self.bb = None 204 self.bb = None
200 self.m = None 205 self.m = None
201 self.fn = None 206 self.fn = None
202 self.loc = None 207 self.loc = None
203 208
204 # Helpers: 209 # Helpers:
205 def setModule(self, m): 210 def setModule(self, m):
206 self.m = m 211 self.m = m
207 212
208 def newFunction(self, name): 213 def newFunction(self, name):
209 f = Function(name) 214 f = ir.Function(name)
210 self.m.add_function(f) 215 self.m.add_function(f)
211 return f 216 return f
212 217
213 def newBlock(self): 218 def newBlock(self):
214 assert self.fn 219 assert self.fn
225 230
226 def setLoc(self, l): 231 def setLoc(self, l):
227 self.loc = l 232 self.loc = l
228 233
229 def emit(self, i): 234 def emit(self, i):
230 assert isinstance(i, Statement) 235 assert isinstance(i, ir.Statement)
231 i.debugLoc = self.loc 236 i.debugLoc = self.loc
232 if not self.bb: 237 if not self.bb:
233 raise Exception('No basic block') 238 raise Exception('No basic block')
234 self.bb.addInstruction(i) 239 self.bb.addInstruction(i)
240
241
242 class Verifier:
243 def verify(self, module):
244 """ Verifies a module for some sanity """
245 assert isinstance(module, ir.Module)
246 for f in module.Functions:
247 self.verify_function(f)
248
249 def verify_function(self, function):
250 for b in function.Blocks:
251 self.verify_block_termination(b)
252
253 # Now we can build a dominator tree
254 for b in function.Blocks:
255 self.verify_block(b)
256
257 def verify_block_termination(self, block):
258 assert not block.Empty
259 assert block.LastInstruction.IsTerminator
260
261 def verify_block(self, block):
262 for instruction in block.Instructions:
263 self.verify_instruction(instruction)
264
265 def verify_instruction(self, instruction):
266 pass