Mercurial > lcfOS
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/irutils.py Thu Dec 12 20:42:56 2013 +0100 @@ -0,0 +1,88 @@ + +""" + Some utilities for ir-code. +""" +from .ir import Temp, Block, Function, Statement + +def dumpgv(m, outf): + print('digraph G ', file=outf) + print('{', file=outf) + for f in m.Functions: + print('{} [label="{}" shape=box3d]'.format(id(f), f), file=outf) + for bb in f.Blocks: + contents = str(bb) + '\n' + contents += '\n'.join([str(i) for i in bb.Instructions]) + print('{0} [shape=note label="{1}"];' + .format(id(bb), contents), file=outf) + for successor in bb.Successors: + print('"{}" -> "{}"'.format(id(bb), id(successor)), file=outf) + + print('"{}" -> "{}" [label="entry"]' + .format(id(f), id(f.entry)), file=outf) + print('}', file=outf) + + +# Constructing IR: + +class NamedClassGenerator: + def __init__(self, prefix, cls): + self.prefix = prefix + self.cls = cls + + def NumGen(): + a = 0 + while True: + yield a + a = a + 1 + self.nums = NumGen() + + def gen(self, prefix=None): + if not prefix: + prefix = self.prefix + return self.cls('{0}{1}'.format(prefix, self.nums.__next__())) + + +class Builder: + """ Base class for ir code generators """ + def __init__(self): + self.prepare() + + def prepare(self): + self.newTemp = NamedClassGenerator('reg', Temp).gen + self.newBlock2 = NamedClassGenerator('block', Block).gen + self.bb = None + self.m = None + self.fn = None + self.loc = None + + # Helpers: + def setModule(self, m): + self.m = m + + def newFunction(self, name): + f = Function(name) + self.m.addFunc(f) + return f + + def newBlock(self): + assert self.fn + b = self.newBlock2() + b.function = self.fn + return b + + def setFunction(self, f): + self.fn = f + self.bb = f.entry if f else None + + def setBlock(self, b): + self.bb = b + + def setLoc(self, l): + self.loc = l + + def emit(self, i): + assert isinstance(i, Statement) + i.debugLoc = self.loc + if not self.bb: + raise Exception('No basic block') + self.bb.addInstruction(i)