Mercurial > lcfOS
view python/ir/module.py @ 272:e64bae57cda8
refactor ir
author | Windel Bouwman |
---|---|
date | Sat, 31 Aug 2013 17:58:54 +0200 |
parents | cf7d5fb7d9c8 |
children | ea93e0a7a31e |
line wrap: on
line source
# IR-Structures: class Module: """ Main container for a piece of code. """ def __init__(self, name): self.name = name self.funcs = [] self.variables = [] def __repr__(self): return 'IR-module [{0}]'.format(self.name) def addFunc(self, f): self.funcs.append(f) addFunction = addFunc def addVariable(self, v): self.variables.append(v) def getVariables(self): return self.variables Variables = property(getVariables) def getFunctions(self): return self.funcs Functions = property(getFunctions) def findFunction(self, name): for f in self.funcs: if f.name == name: return f raise KeyError(name) getFunction = findFunction def dump(self): print(self) for v in self.Variables: print(' ', v) for fn in self.Functions: print(fn) for bb in fn.BasicBlocks: print(' ', bb) for ins in bb.Instructions: print(' ', ins) def dumpgv(self, outf): outf.write('digraph G \n{\n') for f in self.Functions: outf.write('{0} [label="{1}" shape=box3d]\n'.format(id(f), f)) for bb in f.BasicBlocks: contents = str(bb) + '\n' contents += '\n'.join([str(i) for i in bb.Instructions]) outf.write('{0} [shape=note label="{1}"];\n'.format(id(bb), contents)) for successor in bb.Successors: outf.write('"{0}" -> "{1}"\n'.format(id(bb), id(successor))) outf.write('"{0}" -> "{1}" [label="entry"]\n'.format(id(f), id(f.entry))) outf.write('}\n') # Analysis functions: def check(self): """ Perform sanity check on module """ for f in self.Functions: f.check() class Function: def __init__(self, name): self.name = name self.entry = Block('{}_entry'.format(name)) self.epiloog = Block('{}_epilog'.format(name)) self.arguments = [] def __repr__(self): return 'Function {0}'.format(self.name) def addBB(self, bb): self.bbs.append(bb) bb.parent = self addBasicBlock = addBB def removeBasicBlock(self, bb): self.bbs.remove(bb) bb.parent = None def getBBs(self): bbs = [self.entry] worklist = [self.entry] while worklist: b = worklist.pop() for sb in b.Successors: if sb not in bbs: bbs.append(sb) worklist.append(sb) bbs.remove(self.entry) if self.epiloog in bbs: bbs.remove(self.epiloog) bbs.insert(0, self.entry) bbs.append(self.epiloog) return bbs def findBasicBlock(self, name): for bb in self.bbs: if bb.name == name: return bb raise KeyError(name) BasicBlocks = property(getBBs) @property def Entry(self): return self.entry def check(self): pass def call(self, *args): varmap = {} bb = self.Entry ip = 0 while True: i = bb.Instructions[ip] ip += 1 return class Block: """ Uninterrupted sequence of instructions with a label at the start. """ def __init__(self, name): self.name = name self.instructions = [] def __repr__(self): return 'Block {0}'.format(self.name) def addInstruction(self, i): i.parent = self self.instructions.append(i) def replaceInstruction(self, i1, i2): idx = self.instructions.index(i1) i1.parent = None i1.delete() i2.parent = self self.instructions[idx] = i2 def removeInstruction(self, i): i.parent = None i.delete() self.instructions.remove(i) def getInstructions(self): return self.instructions Instructions = property(getInstructions) def getLastIns(self): return self.instructions[-1] LastInstruction = property(getLastIns) @property def Empty(self): return len(self.instructions) == 0 @property def FirstInstruction(self): return self.instructions[0] def getSuccessors(self): if not self.Empty: return self.LastInstruction.Targets return [] Successors = property(getSuccessors) def getPredecessors(self): preds = [] for bb in self.parent.BasicBlocks: if self in bb.Successors: preds.append(bb) return preds Predecessors = property(getPredecessors) def precedes(self, other): raise NotImplementedError() def check(self): pass