18
Phi,
19
Place,
20
} from '../HIR/HIR';
21
-import {printIdentifier} from '../HIR/PrintHIR';
21
+import {printIdentifier, printPlace} from '../HIR/PrintHIR';
22
import {
23
eachTerminalSuccessor,
24
mapInstructionLValues,
27
} from '../HIR/visitors';
28
29
type IncompletePhi = {
30
- oldId: Identifier;
31
- newId: Identifier;
30
+ oldPlace: Place;
31
+ newPlace: Place;
32
};
33
34
type State = {
122
}
123
124
getPlace(oldPlace: Place): Place {
125
- const newId = this.getIdAt(oldPlace.identifier, this.#current!.id);
125
+ const newId = this.getIdAt(oldPlace, this.#current!.id);
126
return {
127
...oldPlace,
128
identifier: newId,
129
};
130
}
131
132
- getIdAt(oldId: Identifier, blockId: BlockId): Identifier {
132
+ getIdAt(oldPlace: Place, blockId: BlockId): Identifier {
133
// check if Place is defined locally
134
const block = this.#blocks.get(blockId)!;
135
const state = this.#states.get(block)!;
136
137
- if (state.defs.has(oldId)) {
138
- return state.defs.get(oldId)!;
137
+ if (state.defs.has(oldPlace.identifier)) {
138
+ return state.defs.get(oldPlace.identifier)!;
139
}
140
141
if (block.preds.size == 0) {
142
/*
143
* We're at the entry block and haven't found our defintion yet.
144
* console.log(
145
- * `Unable to find "${printIdentifier(
146
- * oldId
145
+ * `Unable to find "${printPlace(
146
+ * oldPlace
147
* )}" in bb${blockId}, assuming it's a global`
148
* );
149
*/
150
- this.#unknown.add(oldId);
151
- return oldId;
150
+ this.#unknown.add(oldPlace.identifier);
151
+ return oldPlace.identifier;
152
}
153
154
if (this.unsealedPreds.get(block)! > 0) {
156
* We haven't visited all our predecessors, let's place an incomplete phi
157
* for now.
158
*/
159
- const newId = this.makeId(oldId);
160
- state.incompletePhis.push({oldId, newId});
161
- state.defs.set(oldId, newId);
159
+ const newId = this.makeId(oldPlace.identifier);
160
+ state.incompletePhis.push({
161
+ oldPlace,
162
+ newPlace: {...oldPlace, identifier: newId},
163
+ });
164
+ state.defs.set(oldPlace.identifier, newId);
165
return newId;
166
}
167
168
// Only one predecessor, let's check there
169
if (block.preds.size == 1) {
170
const [pred] = block.preds;
168
- const newId = this.getIdAt(oldId, pred);
169
- state.defs.set(oldId, newId);
171
+ const newId = this.getIdAt(oldPlace, pred);
172
+ state.defs.set(oldPlace.identifier, newId);
173
return newId;
174
}
175
176
// There are multiple predecessors, we may need a phi.
174
- const newId = this.makeId(oldId);
177
+ const newId = this.makeId(oldPlace.identifier);
178
/*
179
* Adding a phi may loop back to our block if there is a loop in the CFG. We
180
* update our defs before adding the phi to terminate the recursion rather than
181
* looping infinitely.
182
*/
180
- state.defs.set(oldId, newId);
181
- return this.addPhi(block, oldId, newId);
183
+ state.defs.set(oldPlace.identifier, newId);
184
+ return this.addPhi(block, oldPlace, {...oldPlace, identifier: newId});
185
}
186
184
- addPhi(block: BasicBlock, oldId: Identifier, newId: Identifier): Identifier {
185
- const predDefs: Map<BlockId, Identifier> = new Map();
187
+ addPhi(block: BasicBlock, oldPlace: Place, newPlace: Place): Identifier {
188
+ const predDefs: Map<BlockId, Place> = new Map();
189
for (const predBlockId of block.preds) {
187
- const predId = this.getIdAt(oldId, predBlockId);
188
- predDefs.set(predBlockId, predId);
190
+ const predId = this.getIdAt(oldPlace, predBlockId);
191
+ predDefs.set(predBlockId, {...oldPlace, identifier: predId});
192
}
193
194
const phi: Phi = {
195
kind: 'Phi',
193
- id: newId,
196
+ place: newPlace,
197
operands: predDefs,
198
};
199
200
block.phis.add(phi);
198
- return newId;
201
+ return newPlace.identifier;
202
}
203
204
fixIncompletePhis(block: BasicBlock): void {
205
const state = this.#states.get(block)!;
206
for (const phi of state.incompletePhis) {
204
- this.addPhi(block, phi.oldId, phi.newId);
207
+ this.addPhi(block, phi.oldPlace, phi.newPlace);
208
}
209
}
210
226
227
for (const incompletePhi of state.incompletePhis) {
228
text.push(
226
- ` iphi \$${printIdentifier(
227
- incompletePhi.newId,
228
- )} = \$${printIdentifier(incompletePhi.oldId)}`,
229
+ ` iphi \$${printPlace(
230
+ incompletePhi.newPlace,
231
+ )} = \$${printPlace(incompletePhi.oldPlace)}`,
232
);
233
}
234
}