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):