More precise handling of const/reassign in ssa form
Addressed a TODO from the previous PR. When we enter SSA form, when we rewrite variable reassignments we currently change the identifier but leave the kind of the lvalue alone; technically we should convert from Reassign to Const. After doing that, it's easier to correctly update when we leave SSA form, we can convert just a subset back into let/reassign (but leave most things alone as const).
Joe Savona committed
Dec 20, 2022 at 16:09 UTC
bc0787fefb637395c17c90558f9d22d6fcd89281
2 files changed
+13
-12
compiler/forget/src/SSA/EnterSSA.ts
+2
@@ -3,6 +3,7 @@ import {
3
HIRFunction,
4
Identifier,
5
IdentifierId,
6
+ InstructionKind,
7
makeInstructionId,
8
makeType,
9
Phi,
@@ -202,6 +203,7 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
203
newPlace = builder.getPlace(oldPlace);
204
} else {
205
newPlace = builder.definePlace(oldPlace);
206
+ instr.lvalue.kind = InstructionKind.Const;
207
}
208
instr.lvalue.place = newPlace;
209
}
compiler/forget/src/SSA/LeaveSSA.ts
+11
-12
@@ -291,23 +291,22 @@ export function leaveSSA(fn: HIRFunction) {
291
// Finally, iterate the instructions and perform any rewrites as well as converting
292
// SSA variables to `const` where possible
293
for (const instr of block.instructions) {
294
- const { lvalue, value } = instr;
294
+ const { lvalue } = instr;
295
if (lvalue !== null) {
296
- rewritePlace(lvalue.place, rewrites);
296
if (
298
- lvalue.kind !== InstructionKind.Const &&
297
+ lvalue.kind === InstructionKind.Const &&
298
lvalue.place.memberPath === null &&
300
- !rewrites.has(lvalue.place.identifier) &&
301
- (!reassignments.has(lvalue.place.identifier) ||
302
- reassignments.get(lvalue.place.identifier) !==
303
- lvalue.place.identifier)
299
+ rewrites.has(lvalue.place.identifier)
300
) {
305
- // Convert individual SSA reassignments into const declarations
306
- // otherwise the code would be invalid, since the SSA identifiers
307
- // aren't otherwise declared.
308
- // TODO @josephsavona: do this in EnterSSA instead?
309
- lvalue.kind = InstructionKind.Const;
301
+ // For rewrites, the declaration of the canonical identifier has to be `let`,
302
+ // all other assignments are reassignments (which we annotate for codegen
303
+ // purposes).
304
+ lvalue.kind =
305
+ rewrites.get(lvalue.place.identifier) === lvalue.place.identifier
306
+ ? InstructionKind.Let
307
+ : InstructionKind.Reassign;
308
}
309
+ rewritePlace(lvalue.place, rewrites);
310
}
311
for (const operand of eachInstructionValueOperand(instr.value)) {
312
rewritePlace(operand, rewrites);