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)