Mercurial > lcfOS
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) +