Mercurial > lcfOS
diff python/ir/instruction.py @ 239:63bb40758066
added check
author | Windel Bouwman |
---|---|
date | Mon, 22 Jul 2013 17:57:25 +0200 |
parents | 88a1e0baef65 |
children | c4370696ccc7 |
line wrap: on
line diff
--- a/python/ir/instruction.py Sat Jul 20 13:18:04 2013 +0200 +++ b/python/ir/instruction.py Mon Jul 22 17:57:25 2013 +0200 @@ -5,58 +5,116 @@ class Value: """ Temporary SSA value (value that is assigned only once! """ def __init__(self, name): - # TODO: add typing? for now only handle integers - self.name = name - self.used_by = [] + # TODO: add typing? for now only handle integers + self.name = name + self.used_by = [] + self.Setter = None def __repr__(self): return '{0}'.format(self.name) # + str(self.IsUsed) @property def IsUsed(self): - return len(self.used_by) > 0 + return len(self.used_by) > 0 + + def onlyUsedInBlock(self, bb): + for use in self.used_by: + ins = use + if ins.parent != bb: + return False + return True + class Variable(Value): pass + class Use: - def __init__(self, user, val): - self.user = user - assert isinstance(val, Value) - self.val = val - self.val.used_by.append(self.user) - def delete(self): - self.val.used_by.remove(self.user) + def __init__(self, user, val): + self.user = user + assert isinstance(val, Value) + self.val = val + self.val.used_by.append(self.user) + + def delete(self): + self.val.used_by.remove(self.user) + class Instruction: - """ Base class for all instructions. """ - def __init__(self): - # live variables at this node: - self.live_in = set() - self.live_out = set() - # What variables this instruction uses and defines: - self.defs = [] - self.uses = [] - def delete(self): + """ Base class for all instructions. """ + def __init__(self): + # live variables at this node: + self.live_in = set() + self.live_out = set() + # What variables this instruction uses and defines: + self.defs = [] + self.uses = [] + def delete(self): while self.uses: use = self.uses.pop() use.delete() - def addUse(self, val): - self.uses.append(Use(self, val)) - def addDef(self, v): - self.defs.append(v) - def getParent(self): - return self.parent - def setParent(self, p): - self.parent = p - Parent = property(getParent, setParent) + while self.defs: + d = self.defs.pop() + d.Setter = None + + def addUse(self, val): + self.uses.append(Use(self, val)) + + def removeUse(self, val): + for u in self.uses: + if u.val is val: + theUse = u + theUse.delete() + self.uses.remove(theUse) + + def addDef(self, v): + self.defs.append(v) + assert v.Setter == None + v.Setter = self + + def removeDef(self, v): + assert v.Setter is self + v.Setter = None + self.defs.remove(v) + + def getParent(self): + return self.parent + + def setParent(self, p): + self.parent = p + Parent = property(getParent, setParent) + + def replaceValue(self, old, new): + raise NotImplementedError() + + @property + def Position(self): + return self.parent.Instructions.index(self) + + def check(self): + # Check that the variables defined by this instruction + # are only used in the same block + for v in self.defs: + assert v.Setter is self + for ub in v.used_by: + assert ub.parent == self.parent + + # Check that variables used are defined earlier: + for u in self.uses: + v = u.val + assert self.Position > v.Setter.Position + + + class Terminator(Instruction): - @property - def Targets(self): - return self.getTargets() - def changeTarget(self, tfrom, tto): - pass + @property + def Targets(self): + return self.getTargets() + + def changeTarget(self, tfrom, tto): + pass + # Function calling: class Call(Instruction): @@ -112,7 +170,7 @@ self.value = value self.addDef(target) def __repr__(self): - return '{0} = {1}'.format(self.target, self.value) + return '{} = {}'.format(self.target, self.value) # Data operations class BinaryOperator(Instruction): @@ -129,10 +187,23 @@ self.addUse(value1) self.addUse(value2) self.operation = operation + def __repr__(self): a, b = self.value1, self.value2 return '{} = {} {} {}'.format(self.result, a, self.operation, b) + def replaceValue(self, old, new): + if old is self.value1: + self.value1 = new + elif old is self.value2: + self.value2 = new + elif old is self.result: + self.result = new + else: + raise Exception() + self.removeUse(old) + self.addUse(new) + # Memory functions: class Load(Instruction): def __init__(self, location, value):