Mercurial > lcfOS
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__() |