Mercurial > lcfOS
changeset 261:444b9df2ed99
try to split up code generation
author | Windel Bouwman |
---|---|
date | Fri, 09 Aug 2013 09:05:13 +0200 |
parents | b2f94b4951f1 |
children | ed14e077124c |
files | python/c3/codegenerator.py python/codegenarm.py python/cortexm3.py python/cortexm3desc.py python/grind.py python/ir/instruction.py python/irmach.py python/mem2reg.py python/transform.py |
diffstat | 9 files changed, 131 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/python/c3/codegenerator.py Tue Aug 06 18:29:53 2013 +0200 +++ b/python/c3/codegenerator.py Fri Aug 09 09:05:13 2013 +0200 @@ -9,9 +9,10 @@ '&':'and', '>>':'shl', '<<':'shr'} class CodeGenerator: + """ Generates intermediate code from a package """ def __init__(self): - self.logger = logging.getLogger('c3') - """ Generates intermediate code from a package """ + self.logger = logging.getLogger('c3cgen') + def gencode(self, pkg): assert type(pkg) is astnodes.Package self.logger.info('Generating ir-code for {}'.format(pkg.name)) @@ -101,6 +102,7 @@ self.builder.setBB(te) else: print('Unknown stmt:', code) + raise NotImplementedError() def genCondCode(self, expr, bbtrue, bbfalse): # Implement sequential logical operators @@ -130,6 +132,7 @@ self.builder.addIns(ir.Branch(bbfalse)) else: print('Unknown cond', expr) + raise NotImplementedError() def cast_to_rvalue(self, expr, loc): """ Cast lvalue to rvalue if required """
--- a/python/codegenarm.py Tue Aug 06 18:29:53 2013 +0200 +++ b/python/codegenarm.py Fri Aug 09 09:05:13 2013 +0200 @@ -3,6 +3,7 @@ from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo import cortexm3 as arm from ppci import CompilerError +import irmach class ArmCodeGenerator: """ @@ -19,7 +20,7 @@ def generate(self, ircode): assert isinstance(ircode, ir.Module) self.logger.info('Generating arm code for {}'.format(ircode.name)) - self.available_regs = {arm.r2, arm.r3, arm.r4, arm.r5, arm.r6, arm.r7} + self.available_regs = {arm.r3, arm.r4, arm.r5, arm.r6, arm.r7} self.regmap = {} # TODO: get these from linker descriptor? self.outs.getSection('code').address = 0x08000000 @@ -51,7 +52,7 @@ self.stack_frame = [] self.emit(Label(f.name)) # Save some registers: - self.emit(arm.push_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6,arm.r7,arm.lr}))) + self.emit(arm.push_ins(arm.RegisterSet({arm.r3, arm.r4, arm.r5, arm.r6,arm.r7,arm.lr}))) for bb in f.BasicBlocks: self.emit(Label(bb.name)) for ins in bb.Instructions: @@ -167,7 +168,7 @@ # TODO: prep parameters: self.emit(arm.bl_ins(LabelRef(ins.callee.name))) elif type(ins) is ir.Return: - self.emit(arm.pop_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6, arm.r7, arm.pc}))) + self.emit(arm.pop_ins(arm.RegisterSet({arm.r3, arm.r4, arm.r5, arm.r6, arm.r7, arm.pc}))) elif type(ins) is ir.ConditionalBranch: r0 = self.getreg(ins.a) r1 = self.getreg(ins.b)
--- a/python/cortexm3.py Tue Aug 06 18:29:53 2013 +0200 +++ b/python/cortexm3.py Fri Aug 09 09:05:13 2013 +0200 @@ -1,4 +1,5 @@ -import struct, types +import struct +import types from target import Register, Instruction, Target, Imm8, Label, Imm3, LabelRef, Imm32 from asmnodes import ASymbol, ANumber, AUnop, ABinop from ppci import CompilerError
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/cortexm3desc.py Fri Aug 09 09:05:13 2013 +0200 @@ -0,0 +1,17 @@ + +# Patterns + +import cortexm3 +import ir + + +{ +""" +v3 = const1 +v1 = v2 + v3 +[v1] = v3 +""": cortexm3. +} + + +
--- a/python/grind.py Tue Aug 06 18:29:53 2013 +0200 +++ b/python/grind.py Fri Aug 09 09:05:13 2013 +0200 @@ -7,5 +7,6 @@ suite = unittest.TestLoader().discover('.') def runtests(): unittest.TextTestRunner().run(suite) - s = cProfile.run('runtests()',sort='cumtime') + #s = cProfile.run('runtests()',sort='cumtime') + s = cProfile.run('runtests()',sort='tottime')
--- a/python/ir/instruction.py Tue Aug 06 18:29:53 2013 +0200 +++ b/python/ir/instruction.py Fri Aug 09 09:05:13 2013 +0200 @@ -32,6 +32,11 @@ assert ins in self.used_by return all(not ins.precedes(ub) for ub in self.used_by) + def replaceby(self, v2): + for use_ins in self.used_by: + use_ins.replaceValue(self, v2.value) + assert not self.Used + class Variable(Value): pass @@ -133,13 +138,6 @@ -class Terminator(Instruction): - @property - def Targets(self): - return self.getTargets() - - def changeTarget(self, tfrom, tto): - pass # Function calling: @@ -156,6 +154,7 @@ if result: assert type(result) is Value self.addDef(result) + def __repr__(self): if self.result: pfx = '{0} = '.format(self.result) @@ -164,55 +163,43 @@ args = ','.join([str(arg) for arg in self.arguments]) return pfx + '{0}({1})'.format(self.callee.name, args) -class Return(Terminator): - def __init__(self, value=None): - super().__init__() - self.value = value - if value: - self.addUse(value) - def __repr__(self): - if self.value: - return 'ret {0}'.format(self.value) - else: - return 'ret' - def getTargets(self): - return [] class Alloc(Instruction): - """ Allocates space on the stack """ - def __init__(self, value): - super().__init__() - assert isinstance(value, Value) - self.value = value - self.addDef(value) - def __repr__(self): - return '{0} = alloc'.format(self.value) + """ Allocates space on the stack """ + def __init__(self, value): + super().__init__() + assert isinstance(value, Value) + self.value = value + self.addDef(value) + + def __repr__(self): + return '{0} = alloc'.format(self.value) + class ImmLoad(Instruction): - def __init__(self, target, value): - super().__init__() - assert type(target) is Value - self.target = target - self.value = value - self.addDef(target) - def __repr__(self): - return '{} = {}'.format(self.target, self.value) + def __init__(self, target, value): + super().__init__() + assert type(target) is Value + self.target = target + self.value = value + self.addDef(target) + + def __repr__(self): + return '{} = {}'.format(self.target, self.value) # Data operations class BinaryOperator(Instruction): def __init__(self, result, operation, value1, value2): - super().__init__() - #print('operation is in binops:', operation in BinOps) - # Check types of the two operands: - assert type(value1) is Value, str(value1) + str(type(value1)) - assert type(value2) is Value, value2 - self.result = result - self.addDef(result) - self.value1 = value1 - self.value2 = value2 - self.addUse(value1) - self.addUse(value2) - self.operation = operation + super().__init__() + assert type(value1) is Value, str(value1) + str(type(value1)) + assert type(value2) is Value, value2 + self.result = result + self.addDef(result) + self.value1 = value1 + self.value2 = value2 + self.addUse(value1) + self.addUse(value2) + self.operation = operation def __repr__(self): a, b = self.value1, self.value2 @@ -230,6 +217,7 @@ self.removeUse(old) self.addUse(new) + # Memory functions: class Load(Instruction): def __init__(self, location, value): @@ -244,6 +232,7 @@ def __repr__(self): return '{} = [{}]'.format(self.value, self.location) + class Store(Instruction): def __init__(self, location, value): super().__init__() @@ -267,20 +256,34 @@ self.removeUse(old) self.addUse(new) + # Branching: +class Terminator(Instruction): + @property + def Targets(self): + return self.getTargets() + + def changeTarget(self, tfrom, tto): + pass + + class Branch(Terminator): def __init__(self, target): - super().__init__() - assert type(target) is BasicBlock - self.target = target + super().__init__() + assert type(target) is BasicBlock + self.target = target + def __repr__(self): return 'BRANCH {0}'.format(self.target) + def getTargets(self): return [self.target] + def changeTarget(self, tfrom, tto): assert tfrom is self.target self.target = tto + class ConditionalBranch(Terminator): def __init__(self, a, cond, b, lab1, lab2): super().__init__() @@ -296,10 +299,12 @@ self.lab1 = lab1 assert type(lab2) is BasicBlock self.lab2 = lab2 + def __repr__(self): return 'IF {0} {1} {2} THEN {3} ELSE {4}'.format(self.a, self.cond, self.b, self.lab1, self.lab2) def getTargets(self): return [self.lab1, self.lab2] + def changeTarget(self, tfrom, tto): assert tfrom is self.lab1 or tfrom is self.lab2 if tfrom is self.lab1: @@ -307,6 +312,24 @@ elif tfrom is self.lab2: self.lab2 = tto + +class Return(Terminator): + def __init__(self, value=None): + super().__init__() + self.value = value + if value: + self.addUse(value) + + def __repr__(self): + if self.value: + return 'ret {0}'.format(self.value) + else: + return 'ret' + + def getTargets(self): + return [] + + class PhiNode(Instruction): def __init__(self): super().__init__()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/irmach.py Fri Aug 09 09:05:13 2013 +0200 @@ -0,0 +1,23 @@ + + +class MachProgram: + pass + + +class MachFunction: + def __init__(self, name): + self.name = name + self.entry = None + + +class MachBlock: + def __init__(self): + self.instructions = [] + + +class MachIns: + """ Absract machine instruction """ + def __init__(self, mi): + self.mi = mi + +
--- a/python/mem2reg.py Tue Aug 06 18:29:53 2013 +0200 +++ b/python/mem2reg.py Fri Aug 09 09:05:13 2013 +0200 @@ -5,7 +5,7 @@ def isAllocPromotable(allocinst): # Check if alloc value is only used by load and store operations. assert type(allocinst) is Alloc - return all(type(use) in [Load,Store] for use in allocinst.value.used_by) + return all(type(use) in [Load, Store] for use in allocinst.value.used_by) class Mem2RegPromotor(FunctionPass): def promoteSingleBlock(self, ai): @@ -24,9 +24,7 @@ for store in stores: if store.Position < load.Position: break - for use_ins in load.value.used_by: - use_ins.replaceValue(load.value, store.value) - assert not load.value.Used + load.value.replaceby(store.value) logging.debug('replaced {} with {}'.format(load, store.value)) bb.removeInstruction(load)
--- a/python/transform.py Tue Aug 06 18:29:53 2013 +0200 +++ b/python/transform.py Fri Aug 09 09:05:13 2013 +0200 @@ -107,8 +107,7 @@ t_new = constMap[i.value] t_old = i.target logging.debug('Replacing {} with {}'.format(t_old, t_new)) - for ui in t_old.used_by: - ui.replaceValue(t_old, t_new) + t_old.replaceby(t_new) to_remove.append(i) else: constMap[i.value] = i.target @@ -118,8 +117,7 @@ t_old = i.result t_new = constMap[k] logging.debug('Replacing {} with {}'.format(t_old, t_new)) - for ui in t_old.used_by: - ui.replaceValue(t_old, t_new) + t_old.replaceby(t_new) to_remove.append(i) else: constMap[k] = i.result