changeset 175:a51b3c956386

Added function call in expressions
author Windel Bouwman
date Fri, 19 Apr 2013 22:15:54 +0200
parents 3eb06f5fb987
children 5fd02aa38b42
files python/c3/codegenerator.py python/c3/semantics.py python/ir/instruction.py python/registerallocator.py python/testir.py python/transform.py
diffstat 6 files changed, 68 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/python/c3/codegenerator.py	Fri Apr 19 19:22:52 2013 +0200
+++ b/python/c3/codegenerator.py	Fri Apr 19 22:15:54 2013 +0200
@@ -7,6 +7,7 @@
    def gencode(self, pkg):
       assert type(pkg) is astnodes.Package
       self.varMap = {} # Maps variables to storage locations.
+      self.funcMap = {}
       self.builder = ir.Builder()
       m = ir.Module(pkg.name)
       self.builder.setModule(m)
@@ -15,13 +16,18 @@
 
    # inner helpers:
    def genModule(self, pkg):
+      # Take care of forward declarations:
+      for s in pkg.scope:
+         if type(s) is astnodes.Function:
+            f = self.builder.newFunc(s.name)
+            self.funcMap[s] = f
       for s in pkg.scope:
          if type(s) is astnodes.Variable:
             # TODO
             pass
          elif type(s) is astnodes.Function:
             # TODO: handle arguments
-            f = self.builder.newFunc(s.name)
+            f = self.funcMap[s]
             self.builder.setFunc(f)
             bb = self.builder.newBB()
             f.entry = bb
@@ -29,6 +35,8 @@
             # generate room for locals:
 
             for sym in s.scope:
+               #print(sym, sym.isParameter)
+               # TODO: handle parameters different
                v = self.builder.newTmp(sym.name)
                self.builder.addIns(ir.Alloc(v))
                self.varMap[sym] = v
@@ -46,7 +54,6 @@
             self.genCode(s)
       elif type(code) is astnodes.Assignment:
          re = self.genExprCode(code.rval)
-         print(code.lval)
          loc = self.varMap[code.lval.target]
          self.builder.addIns(ir.Store(loc, re))
       elif type(code) is astnodes.IfStatement:
@@ -131,6 +138,16 @@
          ins = ir.ImmLoad(tmp, expr.val)
          self.builder.addIns(ins)
          return tmp
+      elif type(expr) is astnodes.FunctionCall:
+         tmp = self.builder.newTmp("res")
+         args = []
+         for arg in expr.args:
+            ar = self.genExprCode(arg)
+            args.append(ar)
+         fn = self.funcMap[expr.proc]
+         ins = ir.Call(fn, args, tmp)
+         self.builder.addIns(ins)
+         return tmp
       else:
          print('Unknown expr:', code)
 
--- a/python/c3/semantics.py	Fri Apr 19 19:22:52 2013 +0200
+++ b/python/c3/semantics.py	Fri Apr 19 22:15:54 2013 +0200
@@ -34,8 +34,8 @@
       self.curScope = self.curFunc.scope = Scope(self.curScope)
    def actOnParameter(self, name, loc, t):
       p = astnodes.Variable(name, t)
+      p.isParameter = True
       p.loc = loc
-      p.parameter = True
       self.addSymbol(p)
       return p
    def actOnFuncDef2(self, parameters, returntype, body):
--- a/python/ir/instruction.py	Fri Apr 19 19:22:52 2013 +0200
+++ b/python/ir/instruction.py	Fri Apr 19 22:15:54 2013 +0200
@@ -1,4 +1,5 @@
 from .basicblock import BasicBlock
+from .function import Function
 
 class Value:
    """ Temporary SSA value (value that is assigned only once! """
@@ -54,12 +55,25 @@
 
 # Function calling:
 class Call(Instruction):
-   def __init__(self, callee, arguments):
+   def __init__(self, callee, arguments, result=None):
       super().__init__()
       self.callee = callee
+      assert type(callee) is Function
       self.arguments = arguments
+      for arg in arguments:
+         assert type(arg) is Value
+         self.addUse(arg)
+      self.result = result
+      if result:
+         assert type(result) is Value
+         self.addDef(result)
    def __repr__(self):
-      return 'CALL {0}'.format(self.callee)
+      if self.result:
+         pfx = '{0} = '.format(self.result)
+      else:
+         pfx = ''
+      args = ','.join([str(arg) for arg in self.arguments])
+      return pfx + '{0}({1})'.format(self.callee.name, args)
 
 class Return(Instruction):
    def __init__(self, value=None):
@@ -130,6 +144,7 @@
       self.location = location
       self.value = value
       self.addUse(value)
+      self.addUse(location)
    def __repr__(self):
       return '[{0}] = {1}'.format(self.location, self.value)
 
--- a/python/registerallocator.py	Fri Apr 19 19:22:52 2013 +0200
+++ b/python/registerallocator.py	Fri Apr 19 22:15:54 2013 +0200
@@ -15,7 +15,6 @@
                lo = lo.union(s.live_in)
             i.live_out = lo
    def registerAllocate(self, ir, regs):
-      print(regs)
       allVals = []
       # construct interference:
       for i in ir.Instructions:
@@ -25,7 +24,6 @@
                if v != v2:
                   v.interferes.add(v2)
       # assign random registers:
-      print(allVals)
       regs = set(regs)
       for v in allVals:
          takenregs = set([iv.reg for iv in v.interferes])
--- a/python/testir.py	Fri Apr 19 19:22:52 2013 +0200
+++ b/python/testir.py	Fri Apr 19 22:15:54 2013 +0200
@@ -4,21 +4,22 @@
 testsrc = """
 package test2;
 
-function void tst()
+function void tesssst(int henkie)
 {
-   var int a, b;
+   var int a, b, cee;
    a = 2 * 33 - 12;
    b = a * 2 + 13;
    a = b + a;
+   cee = a;
    if (a > b and b *3 - a+8*b== 3*6-b)
    {
       var int x = a;
       x = b * 2 - a;
-      a = x * x;
+      a = x * x * add2(x, 22 - a);
    }
    else
    {
-      a = b + a;
+      a = b + a + add2(a, b);
    }
    var int y;
    y = a - b * 53;
@@ -28,6 +29,11 @@
 {
    var int res;
    res = x + y + 2 -  7 + 2;
+   //if (y < 2)
+   //{
+   //   return y - 33;
+   //}
+
    if (x > 13)
    {
       res = res + 2;
@@ -46,14 +52,15 @@
    #ir.dump()
    cf = transform.ConstantFolder()
    dcd = transform.DeadCodeDeleter()
+   m2r = transform.Mem2RegPromotor()
    ir.check()
    cf.run(ir)
-   cf.run(ir)
-   #dcd.run(ir)
-   ir.dump()
+   dcd.run(ir)
+   m2r.run(ir)
+   #ir.dump()
    asm = cgenx86.genBin(ir)
-   for a in asm:
-      print(a)
+   #for a in asm:
+   #   print(a)
    with open('out.asm', 'w') as f:
       f.write('BITS 64\n')
       for a in asm:
--- a/python/transform.py	Fri Apr 19 19:22:52 2013 +0200
+++ b/python/transform.py	Fri Apr 19 22:15:54 2013 +0200
@@ -31,7 +31,6 @@
    def onInstruction(self, i):
       if type(i) is ImmLoad:
          i.target.constval = i.value
-         print(type(i.value), i.value)
       elif type(i) is BinaryOperator:
          a = i.value1
          b = i.value2
@@ -39,15 +38,12 @@
             op = i.operation
             if op == '+':
                i2 = ImmLoad(i.result, a.constval + b.constval)
-               print(i2)
                i.Parent.replaceInstruction(i, i2)
             elif op == '*':
                i2 = ImmLoad(i.result, a.constval * b.constval)
-               print(i2)
                i.Parent.replaceInstruction(i, i2)
             elif op == '-':
                i2 = ImmLoad(i.result, a.constval - b.constval)
-               print(i2)
                i.Parent.replaceInstruction(i, i2)
 
 class DeadCodeDeleter(BasicBlockPass):
@@ -62,3 +58,18 @@
          return False
       bb.Instructions = list(filter(instructionUsed, bb.Instructions))
 
+def isAllocPromotable(allocinst):
+   # Check if alloc value is only used by load and store operations.
+   assert type(allocinst) is Alloc
+   for use in ai.value.used_by:
+      print(use.user, use)
+      if not type(use.user) in [Load, Store]:
+         # TODO: check volatile
+         return False
+         otherUse = True
+   return True
+
+class Mem2RegPromotor(FunctionPass):
+   def onFunction(self, f):
+      print(f)
+