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

[hir] Infer mutable ranges for terminals

Terminal operands are generally not mutating so this hasn't mattered so far. But in a lambda, a return terminal could return a captured context ref which needs to be treated as a mutation to correctly alias the returned context ref and the lvalue.

Sathya Gunasekaran committed Mar 29, 2023 at 15:48 UTC dd0476a1b5f0124d1a8def2cf8d53893e3b6a703
1 file changed +17 -14
compiler/forget/src/Inference/InferMutableLifetimes.ts
+17 -14
@@ -9,12 +9,16 @@ import invariant from "invariant";
9 import {
10 Effect,
11 HIRFunction,
12 - Instruction,
12 + InstructionId,
13 makeInstructionId,
14 Place,
15 } from "../HIR/HIR";
16 -import { printInstruction, printPlace } from "../HIR/PrintHIR";
17 -import { eachInstructionLValue, eachInstructionOperand } from "../HIR/visitors";
16 +import { printPlace } from "../HIR/PrintHIR";
17 +import {
18 + eachInstructionLValue,
19 + eachInstructionOperand,
20 + eachTerminalOperand,
21 +} from "../HIR/visitors";
22 import { assertExhaustive } from "../Utils/utils";
23
24 /**
@@ -60,22 +64,18 @@ import { assertExhaustive } from "../Utils/utils";
64 * ```
65 */
66
63 -function infer(place: Place, instr: Instruction): void {
64 - place.identifier.mutableRange.end = makeInstructionId(instr.id + 1);
67 +function infer(place: Place, instrId: InstructionId): void {
68 + place.identifier.mutableRange.end = makeInstructionId(instrId + 1);
69 }
70
71 function inferPlace(
72 place: Place,
69 - instr: Instruction,
73 + instrId: InstructionId,
74 inferMutableRangeForStores: boolean
75 ): void {
76 switch (place.effect) {
77 case Effect.Unknown: {
74 - throw new Error(
75 - `Found an unknown place ${printPlace(place)} at ${printInstruction(
76 - instr
77 - )}!`
78 - );
78 + throw new Error(`Found an unknown place ${printPlace(place)}}!`);
79 }
80 case Effect.Capture:
81 case Effect.Read:
@@ -83,11 +83,11 @@ function inferPlace(
83 return;
84 case Effect.Store:
85 if (inferMutableRangeForStores) {
86 - infer(place, instr);
86 + infer(place, instrId);
87 }
88 return;
89 case Effect.Mutate: {
90 - infer(place, instr);
90 + infer(place, instrId);
91 return;
92 }
93 default:
@@ -130,8 +130,11 @@ export function inferMutableLifetimes(
130 lvalueId.mutableRange.end = makeInstructionId(instr.id + 1);
131 }
132 for (const operand of eachInstructionOperand(instr)) {
133 - inferPlace(operand, instr, inferMutableRangeForStores);
133 + inferPlace(operand, instr.id, inferMutableRangeForStores);
134 }
135 }
136 + for (const operand of eachTerminalOperand(block.terminal)) {
137 + inferPlace(operand, block.terminal.id, inferMutableRangeForStores);
138 + }
139 }
140 }