@samitouri / QOS-React-2 / commits / bc0787fefb

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);