171
|
1 from .basicblock import BasicBlock
|
|
2
|
|
3 class Value:
|
|
4 """ Temporary SSA value (value that is assigned only once! """
|
|
5 def __init__(self, name):
|
|
6 # TODO: add typing? for now only handle integers
|
|
7 self.name = name
|
|
8 self.interferes = set()
|
|
9 self.reg = None
|
|
10 def __repr__(self):
|
|
11 if self.reg:
|
|
12 n = self.reg
|
|
13 else:
|
|
14 n = self.name
|
|
15 return '{0}'.format(n)
|
110
|
16
|
155
|
17 class Instruction:
|
104
|
18 """ Base class for all instructions. """
|
171
|
19 def __init__(self):
|
|
20 # live variables at this node:
|
|
21 self.live_in = set()
|
|
22 self.live_out = set()
|
|
23 # What variables this instruction uses and defines:
|
|
24 self.defs = set()
|
|
25 self.uses = set()
|
173
|
26 def getParent(self):
|
|
27 return self.parent
|
|
28 Parent = property(getParent)
|
|
29 @property
|
|
30 def Targets(self):
|
|
31 return self.getTargets()
|
170
|
32
|
158
|
33 # Function calling:
|
171
|
34 class Call(Instruction):
|
110
|
35 def __init__(self, callee, arguments):
|
|
36 super().__init__()
|
|
37 self.callee = callee
|
|
38 self.arguments = arguments
|
158
|
39 def __repr__(self):
|
|
40 return 'CALL {0}'.format(self.callee)
|
110
|
41
|
171
|
42 class Return(Instruction):
|
158
|
43 def __repr__(self):
|
|
44 return 'RET'
|
173
|
45 def getTargets(self):
|
|
46 return []
|
70
|
47
|
171
|
48 class ImmLoad(Instruction):
|
|
49 def __init__(self, target, value):
|
|
50 super().__init__()
|
|
51 self.target = target
|
170
|
52 self.value = value
|
171
|
53 self.defs.add(target)
|
170
|
54 def __repr__(self):
|
171
|
55 return '{0} = {1}'.format(self.target, self.value)
|
170
|
56
|
171
|
57 # Data operations
|
70
|
58 class BinaryOperator(Instruction):
|
171
|
59 def __init__(self, result, operation, value1, value2):
|
|
60 super().__init__()
|
157
|
61 #print('operation is in binops:', operation in BinOps)
|
104
|
62 # Check types of the two operands:
|
171
|
63 self.result = result
|
|
64 self.defs.add(result)
|
104
|
65 self.value1 = value1
|
|
66 self.value2 = value2
|
171
|
67 self.uses.add(value1)
|
|
68 self.uses.add(value2)
|
104
|
69 self.operation = operation
|
158
|
70 def __repr__(self):
|
171
|
71 return '{0} = {2} {1} {3}'.format(self.result, self.operation, self.value1, self.value2)
|
70
|
72
|
170
|
73 # Memory functions:
|
171
|
74 class Load(Instruction):
|
158
|
75 def __init__(self, name, value):
|
171
|
76 super().__init__()
|
157
|
77 self.value = value
|
171
|
78 self.defs.add(value)
|
158
|
79 self.name = name
|
|
80 def __repr__(self):
|
170
|
81 return '{1} = [{0}]'.format(self.name, self.value)
|
157
|
82
|
171
|
83 class Store(Instruction):
|
160
|
84 def __init__(self, name, value):
|
171
|
85 super().__init__()
|
160
|
86 self.name = name
|
|
87 self.value = value
|
171
|
88 self.uses.add(value)
|
160
|
89 def __repr__(self):
|
170
|
90 return '[{0}] = {1}'.format(self.name, self.value)
|
160
|
91
|
171
|
92 # Branching:
|
|
93 class Branch(Instruction):
|
170
|
94 def __init__(self, target):
|
171
|
95 super().__init__()
|
|
96 assert type(target) is BasicBlock
|
|
97 self.target = target
|
158
|
98 def __repr__(self):
|
171
|
99 return 'BRANCH {0}'.format(self.target)
|
173
|
100 def getTargets(self):
|
|
101 return [self.target]
|
170
|
102
|
171
|
103 class ConditionalBranch(Instruction):
|
|
104 def __init__(self, a, cond, b, lab1, lab2):
|
|
105 super().__init__()
|
|
106 self.a = a
|
|
107 assert type(a) is Value
|
170
|
108 self.cond = cond
|
171
|
109 self.b = b
|
|
110 self.uses.add(a)
|
|
111 self.uses.add(b)
|
|
112 assert type(b) is Value
|
|
113 assert type(lab1) is BasicBlock
|
170
|
114 self.lab1 = lab1
|
171
|
115 assert type(lab2) is BasicBlock
|
170
|
116 self.lab2 = lab2
|
|
117 def __repr__(self):
|
171
|
118 return 'IF {0} {1} {2} THEN {3} ELSE {4}'.format(self.a, self.cond, self.b, self.lab1, self.lab2)
|
173
|
119 def getTargets(self):
|
|
120 return [self.lab1, self.lab2]
|
170
|
121
|
171
|
122 class PhiNode(Instruction):
|
|
123 def __init__(self):
|
|
124 super().__init__()
|
|
125 self.incBB = []
|
|
126 def addIncoming(self, bb):
|
|
127 self.incBB.append(bb)
|
|
128
|