comparison python/ir/instruction.py @ 239:63bb40758066

added check
author Windel Bouwman
date Mon, 22 Jul 2013 17:57:25 +0200
parents 88a1e0baef65
children c4370696ccc7
comparison
equal deleted inserted replaced
238:90637d1bbfad 239:63bb40758066
3 3
4 4
5 class Value: 5 class Value:
6 """ Temporary SSA value (value that is assigned only once! """ 6 """ Temporary SSA value (value that is assigned only once! """
7 def __init__(self, name): 7 def __init__(self, name):
8 # TODO: add typing? for now only handle integers 8 # TODO: add typing? for now only handle integers
9 self.name = name 9 self.name = name
10 self.used_by = [] 10 self.used_by = []
11 self.Setter = None
11 12
12 def __repr__(self): 13 def __repr__(self):
13 return '{0}'.format(self.name) # + str(self.IsUsed) 14 return '{0}'.format(self.name) # + str(self.IsUsed)
14 15
15 @property 16 @property
16 def IsUsed(self): 17 def IsUsed(self):
17 return len(self.used_by) > 0 18 return len(self.used_by) > 0
19
20 def onlyUsedInBlock(self, bb):
21 for use in self.used_by:
22 ins = use
23 if ins.parent != bb:
24 return False
25 return True
26
18 27
19 class Variable(Value): 28 class Variable(Value):
20 pass 29 pass
21 30
31
22 class Use: 32 class Use:
23 def __init__(self, user, val): 33 def __init__(self, user, val):
24 self.user = user 34 self.user = user
25 assert isinstance(val, Value) 35 assert isinstance(val, Value)
26 self.val = val 36 self.val = val
27 self.val.used_by.append(self.user) 37 self.val.used_by.append(self.user)
28 def delete(self): 38
29 self.val.used_by.remove(self.user) 39 def delete(self):
40 self.val.used_by.remove(self.user)
41
30 42
31 class Instruction: 43 class Instruction:
32 """ Base class for all instructions. """ 44 """ Base class for all instructions. """
33 def __init__(self): 45 def __init__(self):
34 # live variables at this node: 46 # live variables at this node:
35 self.live_in = set() 47 self.live_in = set()
36 self.live_out = set() 48 self.live_out = set()
37 # What variables this instruction uses and defines: 49 # What variables this instruction uses and defines:
38 self.defs = [] 50 self.defs = []
39 self.uses = [] 51 self.uses = []
40 def delete(self): 52 def delete(self):
41 while self.uses: 53 while self.uses:
42 use = self.uses.pop() 54 use = self.uses.pop()
43 use.delete() 55 use.delete()
44 def addUse(self, val): 56 while self.defs:
45 self.uses.append(Use(self, val)) 57 d = self.defs.pop()
46 def addDef(self, v): 58 d.Setter = None
47 self.defs.append(v) 59
48 def getParent(self): 60 def addUse(self, val):
49 return self.parent 61 self.uses.append(Use(self, val))
50 def setParent(self, p): 62
51 self.parent = p 63 def removeUse(self, val):
52 Parent = property(getParent, setParent) 64 for u in self.uses:
65 if u.val is val:
66 theUse = u
67 theUse.delete()
68 self.uses.remove(theUse)
69
70 def addDef(self, v):
71 self.defs.append(v)
72 assert v.Setter == None
73 v.Setter = self
74
75 def removeDef(self, v):
76 assert v.Setter is self
77 v.Setter = None
78 self.defs.remove(v)
79
80 def getParent(self):
81 return self.parent
82
83 def setParent(self, p):
84 self.parent = p
85 Parent = property(getParent, setParent)
86
87 def replaceValue(self, old, new):
88 raise NotImplementedError()
89
90 @property
91 def Position(self):
92 return self.parent.Instructions.index(self)
93
94 def check(self):
95 # Check that the variables defined by this instruction
96 # are only used in the same block
97 for v in self.defs:
98 assert v.Setter is self
99 for ub in v.used_by:
100 assert ub.parent == self.parent
101
102 # Check that variables used are defined earlier:
103 for u in self.uses:
104 v = u.val
105 assert self.Position > v.Setter.Position
106
107
108
53 109
54 class Terminator(Instruction): 110 class Terminator(Instruction):
55 @property 111 @property
56 def Targets(self): 112 def Targets(self):
57 return self.getTargets() 113 return self.getTargets()
58 def changeTarget(self, tfrom, tto): 114
59 pass 115 def changeTarget(self, tfrom, tto):
116 pass
117
60 118
61 # Function calling: 119 # Function calling:
62 class Call(Instruction): 120 class Call(Instruction):
63 def __init__(self, callee, arguments, result=None): 121 def __init__(self, callee, arguments, result=None):
64 super().__init__() 122 super().__init__()
110 assert type(target) is Value 168 assert type(target) is Value
111 self.target = target 169 self.target = target
112 self.value = value 170 self.value = value
113 self.addDef(target) 171 self.addDef(target)
114 def __repr__(self): 172 def __repr__(self):
115 return '{0} = {1}'.format(self.target, self.value) 173 return '{} = {}'.format(self.target, self.value)
116 174
117 # Data operations 175 # Data operations
118 class BinaryOperator(Instruction): 176 class BinaryOperator(Instruction):
119 def __init__(self, result, operation, value1, value2): 177 def __init__(self, result, operation, value1, value2):
120 super().__init__() 178 super().__init__()
127 self.value1 = value1 185 self.value1 = value1
128 self.value2 = value2 186 self.value2 = value2
129 self.addUse(value1) 187 self.addUse(value1)
130 self.addUse(value2) 188 self.addUse(value2)
131 self.operation = operation 189 self.operation = operation
190
132 def __repr__(self): 191 def __repr__(self):
133 a, b = self.value1, self.value2 192 a, b = self.value1, self.value2
134 return '{} = {} {} {}'.format(self.result, a, self.operation, b) 193 return '{} = {} {} {}'.format(self.result, a, self.operation, b)
194
195 def replaceValue(self, old, new):
196 if old is self.value1:
197 self.value1 = new
198 elif old is self.value2:
199 self.value2 = new
200 elif old is self.result:
201 self.result = new
202 else:
203 raise Exception()
204 self.removeUse(old)
205 self.addUse(new)
135 206
136 # Memory functions: 207 # Memory functions:
137 class Load(Instruction): 208 class Load(Instruction):
138 def __init__(self, location, value): 209 def __init__(self, location, value):
139 super().__init__() 210 super().__init__()