changeset 176:5fd02aa38b42

Added while loop code generation
author Windel Bouwman
date Sat, 20 Apr 2013 12:00:51 +0200
parents a51b3c956386
children 460db5669efa
files python/c3/astnodes.py python/c3/codegenerator.py python/c3/visitor.py python/ir/instruction.py python/testir.py python/transform.py
diffstat 6 files changed, 48 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/python/c3/astnodes.py	Fri Apr 19 22:15:54 2013 +0200
+++ b/python/c3/astnodes.py	Sat Apr 20 12:00:51 2013 +0200
@@ -156,9 +156,9 @@
       return 'IF-statement'
 
 class WhileStatement(Node):
-   def __init__(self, condition, statements):
+   def __init__(self, condition, statement):
       self.condition = condition
-      self.dostatements = statements
+      self.dostatement = statement
    def __repr__(self):
       return 'WHILE-statement'
 
--- a/python/c3/codegenerator.py	Fri Apr 19 22:15:54 2013 +0200
+++ b/python/c3/codegenerator.py	Sat Apr 20 12:00:51 2013 +0200
@@ -69,6 +69,7 @@
          self.builder.addIns(ir.Branch(te))
          self.builder.setBB(te)
       elif type(code) is astnodes.FunctionCall:
+         print('TODO')
          pass
       elif type(code) is astnodes.EmptyStatement:
          pass
@@ -78,6 +79,17 @@
             self.builder.addIns(ir.Return(re))
          else:
             self.builder.addIns(ir.Return())
+      elif type(code) is astnodes.WhileStatement:
+         bbdo = self.builder.newBB()
+         bbtest = self.builder.newBB()
+         te = self.builder.newBB()
+         self.builder.addIns(ir.Branch(bbtest))
+         self.builder.setBB(bbtest)
+         self.genCondCode(code.condition, bbdo, te)
+         self.builder.setBB(bbdo)
+         self.genCode(code.dostatement)
+         self.builder.addIns(ir.Branch(bbtest))
+         self.builder.setBB(te)
       else:
          print('Unknown stmt:', code)
    def genCondCode(self, expr, bbtrue, bbfalse):
--- a/python/c3/visitor.py	Fri Apr 19 22:15:54 2013 +0200
+++ b/python/c3/visitor.py	Sat Apr 20 12:00:51 2013 +0200
@@ -40,6 +40,9 @@
       elif type(node) in [EmptyStatement, VariableUse, Variable, Literal, FunctionType]:
          # Those nodes do not have child nodes.
          pass
+      elif type(node) is WhileStatement:
+         self.visit(node.condition)
+         self.visit(node.dostatement)
       else:
          print('UNK visit "{0}"'.format(node))
       self.f2(node)
--- a/python/ir/instruction.py	Fri Apr 19 22:15:54 2013 +0200
+++ b/python/ir/instruction.py	Sat Apr 20 12:00:51 2013 +0200
@@ -6,15 +6,9 @@
    def __init__(self, name):
       # TODO: add typing? for now only handle integers
       self.name = name
-      self.interferes = set()
-      self.reg = None
       self.used_by = []
    def __repr__(self):
-      if self.reg:
-         n = self.reg
-      else:
-         n = self.name
-      return '{0}'.format(n) # + str(self.IsUsed)
+      return '{0}'.format(self.name) # + str(self.IsUsed)
    @property
    def IsUsed(self):
       return len(self.used_by) > 0
--- a/python/testir.py	Fri Apr 19 22:15:54 2013 +0200
+++ b/python/testir.py	Sat Apr 20 12:00:51 2013 +0200
@@ -36,7 +36,11 @@
 
    if (x > 13)
    {
-      res = res + 2;
+      while (y > 1337)
+      {
+         res = res + 2;
+         y = y - 12;
+      }
    }
    return res;
 }
@@ -58,6 +62,12 @@
    dcd.run(ir)
    m2r.run(ir)
    #ir.dump()
+
+   # Dump a graphiz file:
+   with open('graaf.gv', 'w') as f:
+      ir.dumpgv(f)
+   os.system('dot -Tpdf -ograaf.pdf graaf.gv')
+
    asm = cgenx86.genBin(ir)
    #for a in asm:
    #   print(a)
@@ -65,9 +75,3 @@
       f.write('BITS 64\n')
       for a in asm:
          f.write(str(a) + '\n')
-
-   # Dump a graphiz file:
-   with open('graaf.gv', 'w') as f:
-      ir.dumpgv(f)
-   os.system('dot -Tpdf -ograaf.pdf graaf.gv')
-
--- a/python/transform.py	Fri Apr 19 22:15:54 2013 +0200
+++ b/python/transform.py	Sat Apr 20 12:00:51 2013 +0200
@@ -4,11 +4,14 @@
 class FunctionPass:
    def run(self, ir):
       """ Main entry point for the pass """
+      self.prepare()
       for f in ir.Functions:
          self.onFunction(f)
    def onFunction(self, f):
       """ Override this virtual method """
       raise NotImplementedError()
+   def prepare(self):
+      pass
 
 class BasicBlockPass(FunctionPass):
    def onFunction(self, f):
@@ -28,23 +31,28 @@
 
 # Usefull transforms:
 class ConstantFolder(InstructionPass):
+   def prepare(self):
+      self.constMap = {}
    def onInstruction(self, i):
       if type(i) is ImmLoad:
-         i.target.constval = i.value
+         self.constMap[i.target] = i.value
       elif type(i) is BinaryOperator:
-         a = i.value1
-         b = i.value2
-         if hasattr(a, 'constval') and hasattr(b,'constval'):
+         if i.value1 in self.constMap and i.value2 in self.constMap:
             op = i.operation
+            va = self.constMap[i.value1]
+            vb = self.constMap[i.value2]
             if op == '+':
-               i2 = ImmLoad(i.result, a.constval + b.constval)
-               i.Parent.replaceInstruction(i, i2)
+               vr = va + vb
             elif op == '*':
-               i2 = ImmLoad(i.result, a.constval * b.constval)
-               i.Parent.replaceInstruction(i, i2)
+               vr = va * vb
             elif op == '-':
-               i2 = ImmLoad(i.result, a.constval - b.constval)
-               i.Parent.replaceInstruction(i, i2)
+               vr = va - vb
+            else:
+               vr = None
+               return
+            self.constMap[i.result] = vr
+            i2 = ImmLoad(i.result, vr)
+            i.Parent.replaceInstruction(i, i2)
 
 class DeadCodeDeleter(BasicBlockPass):
    def onBasicBlock(self, bb):
@@ -71,5 +79,6 @@
 
 class Mem2RegPromotor(FunctionPass):
    def onFunction(self, f):
+      # TODO
       print(f)