-
Notifications
You must be signed in to change notification settings - Fork 0
/
tigerliveness.sml
215 lines (178 loc) · 7.58 KB
/
tigerliveness.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
structure tigerliveness :> tigerliveness =
struct
open tigerassem
type node = tigerassem.instr * int
(* compareNodes : node * node -> order *)
fun compareNodes ((_, n1), (_, n2)) = Int.compare(n1, n2)
(* getLabelNodeNum : tigertemp.label -> node Splayset.set -> int
Where's the error? Couldn't find it...
fun getLabelNodeNum (labelTemp : string) (iGraph : node Splayset.set) =
let
val num = case Splayset.find (fn (instr, _) =>
case instr of
LABEL {lab = labelTemp, ...} => true
| _ => false) iGraph of
SOME (_, n) => n
| NONE => raise Fail "Error - liveness: LABEL no encontrado en el grafo de instrucciones"
in
num
end
*)
fun getInstrFromNode (instr, _) = instr
fun getNumFromNode (_, n) = n
(* createLabelsTableFromGraph : node Splayset.set -> (string * int) Splaymap.dict *)
fun createLabelsTableFromGraph iGraph =
let
val nodesList = Splayset.listItems iGraph
val labelNodes = List.filter (fn (instr, _) =>
case instr of
LABEL _ => true
| _ => false) nodesList
val labelNodes' : (string * int) list = List.map (fn (instr, n) =>
case instr of
LABEL {lab, ...} => (lab, n)
| _ => raise Fail "Error - liveness (createLabelsTableFromGraph()): no debería pasar") labelNodes
val table = Splaymap.mkDict String.compare
in
List.foldl (fn ((lab, n), table) =>
Splaymap.insert(table, lab, n)) table labelNodes' (* Supposing "lab's" are unique *)
end
(* getLabelNodeNum : tigertemp.label -> (string * int) Splaymap.dict -> int *)
fun getLabelNodeNum (labelTemp : string) labelsTable =
let
val num = case Splaymap.peek(labelsTable, labelTemp) of
SOME n => n
| NONE => raise Fail "Error - liveness: LABEL no encontrado en el grafo de instrucciones"
in
num
end
(* successors : node -> node Splayset.set -> int Splayset.set *)
fun successors node iGraph =
let
val resultSet = Splayset.empty(Int.compare)
val labelsTable = createLabelsTableFromGraph iGraph (* Hash table only containing labels "instructions" as keys,
mapping number of node *)
in
case node of
(OPER {jump = NONE, ...}, n) => Splayset.add(resultSet, n+1)
| (OPER {jump = SOME [], ...}, _) => raise Fail "Error - liveness: jump vacío"
| (OPER {jump = SOME [l], ...}, _) => Splayset.add(resultSet, getLabelNodeNum l labelsTable)
| (OPER {jump = SOME [t, f], ...}, _) => let
val resultSet' = Splayset.add(resultSet, getLabelNodeNum t labelsTable)
val resultSet'' = Splayset.add(resultSet', getLabelNodeNum f labelsTable)
in
Splayset.union(resultSet', resultSet'')
end
| (OPER {jump = SOME _, ...}, _) => raise Fail "Error - liveness: LABEL con más de dos etiquetas"
| (MOVE _, n) => Splayset.add(resultSet, n+1)
| (LABEL {lab, ...}, n) => case String.isPrefix "EXIT_LAB_" lab of
true => resultSet
| false => Splayset.add(resultSet, n+1)
end
(* fromNumToNode : int Splayset.set -> node Splayset.set -> node Splayset.set *)
fun fromNumToNode intSet iGraph =
let
fun toNode num = case Splayset.find (fn (_, n) =>
if n=num then true else false) iGraph of
SOME node => node
| NONE => raise Fail "Error - liveness: número de nodo no encontrado en el grafo de instrucciones"
in
utils.setMap toNode intSet compareNodes
end
(* calculateUseSet : tigerassem.instr -> tigertemp.temp Splayset.set *)
fun calculateUseSet instr =
let
val emptySet = Splayset.empty(String.compare)
in
case instr of
OPER {src, ...} => Splayset.addList(emptySet, src)
| MOVE {src ,...} => Splayset.add(emptySet, src)
| _ => emptySet
end
(* calculateDefSet : tigerassem.instr -> tigertemp.temp Splayset.set *)
fun calculateDefSet instr =
let
val emptySet = Splayset.empty(String.compare)
in
case instr of
OPER {dst, ...} => Splayset.addList(emptySet, dst)
| MOVE {dst ,...} => Splayset.add(emptySet, dst)
| _ => emptySet
end
(* calculateLiveOut : tigerassem.instr list -> tigertemp.temp Splayset.set list *)
fun calculateLiveOut instrList =
let
val tabs = List.tabulate(List.length instrList, fn x => x)
(* nodesList : node list *)
val nodesList : node list = ListPair.zip(instrList, tabs) (* Instructions numbered from 0 *)
val emptyGraph = Splayset.empty(compareNodes)
(* iGraph : node Splayset.set *)
val iGraph = Splayset.addList(emptyGraph, nodesList) (* Instructions graph. Every elem has type
node, where the integer
corresponds to the number of the node in the
graph. Every elem is a "node" for now on. *)
val emptyStringSet = Splayset.empty(String.compare)
val (liveInArray, liveOutArray) = (Array.array (List.length instrList, emptyStringSet),
Array.array (List.length instrList, emptyStringSet)) (* Init live-in and live-out arrays with empty temp-sets *)
(* computationByIteration : node list -> bool -> unit *)
fun computationByIteration [] false = computationByIteration nodesList true
| computationByIteration [] true = ()
| computationByIteration (((node as (instr, n)) :: nodes) : node list) flag =
let
(* insertSetFromArray : node -> tigertemp.temp Splayset.set *)
fun insertLiveInSetFromArray (_, n) = Array.sub (liveInArray, n)
val emptySet = Splayset.empty(String.compare)
val (liveInArrayAux, liveOutArrayAux) = (Array.sub (liveInArray, n),
Array.sub (liveOutArray, n))
(* succNodes : node Splayset.set. Set of successors nodes of input node *)
val succNodes : node Splayset.set = fromNumToNode (successors node iGraph) iGraph
val succNodesToList : node list = Splayset.listItems(succNodes)
(* succNodes' : tigertemp.temp Splayset.set list *)
val succNodes' : tigertemp.temp Splayset.set list = List.map insertLiveInSetFromArray succNodesToList
(* Begin iteration...
Update first out[n] and then in[n] *)
val genUnionSet : tigertemp.temp Splayset.set = List.foldl Splayset.union emptySet succNodes'
val _ = Array.update (liveOutArray, n, genUnionSet)
val diff = Splayset.difference(Array.sub (liveOutArray, n), calculateDefSet instr)
val union = Splayset.union(calculateUseSet instr, diff)
val _ = Array.update(liveInArray, n, union)
val flag' = (Splayset.equal (Array.sub (liveInArray, n), liveInArrayAux))
andalso
(Splayset.equal (Array.sub (liveOutArray, n), liveOutArrayAux))
in
computationByIteration nodes (flag andalso flag')
end
(* Compute liveness *)
val _ = computationByIteration nodesList true
in
(List.map (fn (_, n) =>
Array.sub(liveOutArray, n)) nodesList,
iGraph)
end
fun liveOutInfoToString instrList =
let
(* liveOutList : tigertemp.temp Splatset.set list
iGraph : node Splayset.set
*)
val (liveOutList, iGraph) = calculateLiveOut instrList
val iGraphList : node list = Splayset.listItems iGraph
val iGraphList' = List.map (fn (node as (instr, n)) =>
let
val instrStr : string = tigerassem.format tigertemp.makeString instr
val nStr : string = Int.toString n
val succSet : int Splayset.set = successors node iGraph
val succSetStr : string = utils.setToString succSet Int.toString
val liveOutSet : tigertemp.temp Splayset.set = List.nth(liveOutList, n)
val liveOutStr : string = utils.setToString liveOutSet (fn x => x)
(* Just deletes last \n char *)
val instrStr' : string = utils.deleteEnterFromString instrStr
in
(instrStr',
nStr,
succSetStr,
liveOutStr)
end) iGraphList
in
iGraphList'
end
end