diff 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
line wrap: on
line diff
--- a/python/ppci/irutils.py	Mon Dec 16 12:49:24 2013 +0100
+++ b/python/ppci/irutils.py	Mon Dec 16 17:58:15 2013 +0100
@@ -3,7 +3,6 @@
     Some utilities for ir-code.
 """
 import re
-from .ir import Temp, Block, Function, Statement
 from . import ir
 
 def dumpgv(m, outf):
@@ -25,18 +24,24 @@
 
 
 class Writer:
+    def __init__(self, extra_indent=''):
+        self.extra_indent = extra_indent
+
     def write(self, ir, f):
         """ Write ir-code to file f """
-        print(ir, file=f)
+        print('{}{}'.format(self.extra_indent, ir), file=f)
         for v in ir.Variables:
-            print(str(v), file=f)
-        for fn in ir.Functions:
-            args = ','.join('i32 ' + str(a) for a in fn.arguments)
-            print('function i32 {}({})'.format(fn.name, args), file=f)
-            for bb in fn.Blocks:
-                print(' ' + str(bb), file=f)
-                for ins in bb.Instructions:
-                    print('  ' + str(ins), file=f)
+            print('{}{}'.format(self.extra_indent, v), file=f)
+        for function in ir.Functions:
+            self.write_function(function, f)
+
+    def write_function(self, fn, f):
+        args = ','.join('i32 ' + str(a) for a in fn.arguments)
+        print('{}function i32 {}({})'.format(self.extra_indent, fn.name, args), file=f)
+        for bb in fn.Blocks:
+            print('{} {}'.format(self.extra_indent, bb), file=f)
+            for ins in bb.Instructions:
+                print('{}  {}'.format(self.extra_indent, ins), file=f)
 
 
 class IrParseException(Exception):
@@ -194,8 +199,8 @@
         self.prepare()
 
     def prepare(self):
-        self.newTemp = NamedClassGenerator('reg', Temp).gen
-        self.newBlock2 = NamedClassGenerator('block', Block).gen
+        self.newTemp = NamedClassGenerator('reg', ir.Temp).gen
+        self.newBlock2 = NamedClassGenerator('block', ir.Block).gen
         self.bb = None
         self.m = None
         self.fn = None
@@ -206,7 +211,7 @@
         self.m = m
 
     def newFunction(self, name):
-        f = Function(name)
+        f = ir.Function(name)
         self.m.add_function(f)
         return f
 
@@ -227,8 +232,35 @@
         self.loc = l
 
     def emit(self, i):
-        assert isinstance(i, Statement)
+        assert isinstance(i, ir.Statement)
         i.debugLoc = self.loc
         if not self.bb:
             raise Exception('No basic block')
         self.bb.addInstruction(i)
+
+
+class Verifier:
+    def verify(self, module):
+        """ Verifies a module for some sanity """
+        assert isinstance(module, ir.Module)
+        for f in module.Functions:
+            self.verify_function(f)
+
+    def verify_function(self, function):
+        for b in function.Blocks:
+            self.verify_block_termination(b)
+
+        # Now we can build a dominator tree
+        for b in function.Blocks:
+            self.verify_block(b)
+
+    def verify_block_termination(self, block):
+        assert not block.Empty
+        assert block.LastInstruction.IsTerminator
+        
+    def verify_block(self, block):
+        for instruction in block.Instructions:
+            self.verify_instruction(instruction)
+
+    def verify_instruction(self, instruction):
+        pass