@samitouri / QOS-React / commits / 71db40c6ff

LoadLocal instruction

Changes InstructionValue::Place to InstructionValue::LoadLocal for clarity, this is intended as the only instruction where a variable can appear as an operand. All other instructions operands will be temporaries.

Joe Savona committed Mar 1, 2023 at 16:27 UTC 71db40c6ff97514fd54ea48c23370ebf4bab2e63
26 files changed +152 -129
compiler/forget/src/HIR/BuildHIR.ts
+48 -30
@@ -110,7 +110,7 @@ export function lower(
110 param.node.loc ?? GeneratedSource,
111 InstructionKind.Let,
112 param,
113 - place
113 + { kind: "LoadLocal", place, loc: place.loc }
114 );
115 } else {
116 builder.errors.push({
@@ -628,7 +628,7 @@ function lowerStatement(
628 const stmt = stmtPath as NodePath<t.ExpressionStatement>;
629 const expression = stmt.get("expression");
630 const value = lowerExpression(builder, expression);
631 - if (expression.isAssignmentExpression() && value.kind === "Identifier") {
631 + if (expression.isAssignmentExpression() && value.kind === "LoadLocal") {
632 // already lowered to a place
633 return;
634 }
@@ -721,7 +721,12 @@ function lowerExpression(
721 switch (exprNode.type) {
722 case "Identifier": {
723 const expr = exprPath as NodePath<t.Identifier>;
724 - return lowerIdentifier(builder, expr);
724 + const place = lowerIdentifier(builder, expr);
725 + return {
726 + kind: "LoadLocal",
727 + place,
728 + loc: exprLoc,
729 + };
730 }
731 case "NullLiteral": {
732 return {
@@ -958,7 +963,11 @@ function lowerExpression(
963 });
964 return { kind: "UnsupportedNode", node: expr.node, loc: exprLoc };
965 }
961 - return last;
966 + return {
967 + kind: "LoadLocal", // TODO: LoadTemp
968 + place: last,
969 + loc: last.loc,
970 + };
971 }
972 case "ConditionalExpression": {
973 const expr = exprPath as NodePath<t.ConditionalExpression>;
@@ -974,7 +983,7 @@ function lowerExpression(
983 builder.push({
984 id: makeInstructionId(0),
985 lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
977 - value: lowerExpressionToTemporary(builder, expr.get("consequent")),
986 + value: lowerExpression(builder, expr.get("consequent")),
987 loc: exprLoc,
988 });
989 return {
@@ -989,7 +998,7 @@ function lowerExpression(
998 builder.push({
999 id: makeInstructionId(0),
1000 lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
992 - value: lowerExpressionToTemporary(builder, expr.get("alternate")),
1001 + value: lowerExpression(builder, expr.get("alternate")),
1002 loc: exprLoc,
1003 });
1004 return {
@@ -1021,7 +1030,7 @@ function lowerExpression(
1030 },
1031 continuationBlock
1032 );
1024 - return place;
1033 + return { kind: "LoadLocal", place, loc: place.loc };
1034 }
1035 case "LogicalExpression": {
1036 const expr = exprPath as NodePath<t.LogicalExpression>;
@@ -1037,7 +1046,11 @@ function lowerExpression(
1046 builder.push({
1047 id: makeInstructionId(0),
1048 lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
1040 - value: { ...leftPlace },
1049 + value: {
1050 + kind: "LoadLocal",
1051 + place: { ...leftPlace },
1052 + loc: leftPlace.loc,
1053 + },
1054 loc: exprLoc,
1055 });
1056 return {
@@ -1051,7 +1064,7 @@ function lowerExpression(
1064 builder.push({
1065 id: makeInstructionId(0),
1066 lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
1054 - value: lowerExpressionToTemporary(builder, expr.get("right")),
1067 + value: lowerExpression(builder, expr.get("right")),
1068 loc: exprLoc,
1069 });
1070 return {
@@ -1075,7 +1088,7 @@ function lowerExpression(
1088 builder.push({
1089 id: makeInstructionId(0),
1090 lvalue: { kind: InstructionKind.Reassign, place: { ...leftPlace } },
1078 - value: lowerExpressionToTemporary(builder, expr.get("left")),
1091 + value: lowerExpression(builder, expr.get("left")),
1092 loc: exprLoc,
1093 });
1094 builder.terminateWithContinuation(
@@ -1088,7 +1101,7 @@ function lowerExpression(
1101 },
1102 continuationBlock
1103 );
1091 - return place;
1104 + return { kind: "LoadLocal", place, loc: place.loc };
1105 }
1106 case "AssignmentExpression": {
1107 const expr = exprPath as NodePath<t.AssignmentExpression>;
@@ -1096,7 +1109,7 @@ function lowerExpression(
1109
1110 if (builder.currentBlockKind() === "value") {
1111 // try lowering the RHS in case it also contains errors
1099 - lowerExpressionToTemporary(builder, expr.get("right"));
1112 + lowerExpression(builder, expr.get("right"));
1113 builder.errors.push({
1114 reason: `(BuildHIR::lowerExpression) Handle AssignmentExpression within a LogicalExpression or ConditionalExpression`,
1115 severity: ErrorSeverity.Todo,
@@ -1112,8 +1125,7 @@ function lowerExpression(
1125 left.node.loc ?? GeneratedSource,
1126 InstructionKind.Reassign,
1127 left,
1115 - // NOTE: it's okay not to lower to a temporary here because this is the entire RHS value, not a single operand
1116 - lowerExpressionToPlace(builder, expr.get("right"))
1128 + lowerExpression(builder, expr.get("right"))
1129 );
1130 }
1131
@@ -1159,7 +1171,7 @@ function lowerExpression(
1171 },
1172 loc: exprLoc,
1173 });
1162 - return place;
1174 + return { kind: "LoadLocal", place, loc: exprLoc };
1175 }
1176 case "MemberExpression": {
1177 // a.b.c += <right>
@@ -1243,7 +1255,7 @@ function lowerExpression(
1255 value,
1256 loc: exprLoc,
1257 });
1246 - return place;
1258 + return { kind: "LoadLocal", place, loc: place.loc };
1259 }
1260 case "JSXElement": {
1261 const expr = exprPath as NodePath<t.JSXElement>;
@@ -1496,21 +1508,27 @@ function lowerExpression(
1508 },
1509 loc: expr.node.loc ?? GeneratedSource,
1510 });
1499 - const identifier = argument as NodePath<t.Identifier>;
1500 - const place = lowerIdentifier(builder, identifier);
1511 + const identifier = lowerIdentifier(
1512 + builder,
1513 + argument as NodePath<t.Identifier>
1514 + );
1515 builder.push({
1516 id: makeInstructionId(0),
1503 - lvalue: { place: { ...place }, kind: InstructionKind.Reassign },
1517 + lvalue: { place: { ...identifier }, kind: InstructionKind.Reassign },
1518 value: {
1519 kind: "BinaryExpression",
1520 operator: expr.node.operator === "++" ? "+" : "-",
1507 - left: { ...place },
1521 + left: { ...identifier },
1522 right: { ...temp },
1523 loc: exprLoc,
1524 },
1525 loc: exprLoc,
1526 });
1513 - return place;
1527 + return {
1528 + kind: "LoadLocal",
1529 + place: { ...identifier },
1530 + loc: exprLoc,
1531 + };
1532 }
1533 default: {
1534 builder.errors.push({
@@ -1703,8 +1721,8 @@ function lowerExpressionToTemporary(
1721 exprPath: NodePath<t.Expression>
1722 ): Place {
1723 const value = lowerExpression(builder, exprPath);
1706 - if (value.kind === "Identifier" && value.identifier.name === null) {
1707 - return value;
1724 + if (value.kind === "LoadLocal" && value.place.identifier.name === null) {
1725 + return value.place;
1726 }
1727 const exprLoc = exprPath.node.loc ?? GeneratedSource;
1728 const place: Place = buildTemporaryPlace(builder, exprLoc);
@@ -1722,8 +1740,8 @@ function lowerExpressionToPlace(
1740 exprPath: NodePath<t.Expression>
1741 ): Place {
1742 const value = lowerExpression(builder, exprPath);
1725 - if (value.kind === "Identifier") {
1726 - return value;
1743 + if (value.kind === "LoadLocal") {
1744 + return value.place;
1745 }
1746 const exprLoc = exprPath.node.loc ?? GeneratedSource;
1747 const place: Place = buildTemporaryPlace(builder, exprLoc);
@@ -1855,15 +1873,15 @@ function lowerAssignment(
1873 value,
1874 loc,
1875 });
1858 - return place;
1876 + return { kind: "LoadLocal", place, loc: place.loc };
1877 }
1878 case "MemberExpression": {
1879 const lvalue = lvaluePath as NodePath<t.MemberExpression>;
1880 const property = lvalue.get("property");
1881 const object = lowerExpressionToTemporary(builder, lvalue.get("object"));
1882 let valuePlace: Place;
1865 - if (value.kind === "Identifier") {
1866 - valuePlace = value;
1883 + if (value.kind === "LoadLocal") {
1884 + valuePlace = value.place;
1885 } else {
1886 valuePlace = buildTemporaryPlace(builder, loc);
1887 builder.push({
@@ -1958,7 +1976,7 @@ function lowerAssignment(
1976 }
1977 return hasError
1978 ? { kind: "UnsupportedNode", node: lvalueNode, loc }
1961 - : arrayPlace;
1979 + : { kind: "LoadLocal", place: arrayPlace, loc: arrayPlace.loc };
1980 }
1981 case "ObjectPattern": {
1982 const lvalue = lvaluePath as NodePath<t.ObjectPattern>;
@@ -2013,7 +2031,7 @@ function lowerAssignment(
2031 }
2032 return hasError
2033 ? { kind: "UnsupportedNode", node: lvalueNode, loc }
2016 - : objectPlace;
2034 + : { kind: "LoadLocal", place: objectPlace, loc: objectPlace.loc };
2035 }
2036 default: {
2037 builder.errors.push({
compiler/forget/src/HIR/HIR.ts
+5 -1
@@ -396,7 +396,11 @@ export type Phi = {
396 * Operands are therefore always a Place.
397 */
398 export type InstructionValue =
399 - | Place
399 + | {
400 + kind: "LoadLocal";
401 + place: Place;
402 + loc: SourceLocation;
403 + }
404 | {
405 kind: "Primitive";
406 value: number | boolean | string | null | undefined;
compiler/forget/src/HIR/MergeConsecutiveBlocks.ts
+7 -3
@@ -69,9 +69,13 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void {
69 kind: InstructionKind.Const,
70 },
71 value: {
72 - kind: "Identifier",
73 - identifier: operand,
74 - effect: Effect.Read,
72 + kind: "LoadLocal",
73 + place: {
74 + kind: "Identifier",
75 + identifier: operand,
76 + effect: Effect.Read,
77 + loc: GeneratedSource,
78 + },
79 loc: GeneratedSource,
80 },
81 loc: GeneratedSource,
compiler/forget/src/HIR/PrintHIR.ts
+2 -2
@@ -304,8 +304,8 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
304 value = `UnsupportedNode(${generate(instrValue.node).code})`;
305 break;
306 }
307 - case "Identifier": {
308 - value = printPlace(instrValue);
307 + case "LoadLocal": {
308 + value = `LoadLocal ${printPlace(instrValue.place)}`;
309 break;
310 }
311 case "PropertyLoad": {
compiler/forget/src/HIR/visitors.ts
+4 -4
@@ -48,8 +48,8 @@ export function* eachInstructionValueOperand(
48 yield* instrValue.args;
49 break;
50 }
51 - case "Identifier": {
52 - yield instrValue;
51 + case "LoadLocal": {
52 + yield instrValue.place;
53 break;
54 }
55 case "PropertyLoad": {
@@ -177,8 +177,8 @@ export function mapInstructionOperands(
177 instrValue.value = fn(instrValue.value);
178 break;
179 }
180 - case "Identifier": {
181 - instr.value = fn(instrValue);
180 + case "LoadLocal": {
181 + instrValue.place = fn(instrValue.place);
182 break;
183 }
184 case "NewExpression":
compiler/forget/src/Inference/AnalyseFunctions.ts
+2 -2
@@ -62,9 +62,9 @@ export default function analyseFunctions(func: HIRFunction) {
62 );
63 break;
64 }
65 - case "Identifier": {
65 + case "LoadLocal": {
66 if (instr.lvalue.place.identifier.name === null) {
67 - state.declareTemporary(instr.lvalue.place, instr.value);
67 + state.declareTemporary(instr.lvalue.place, instr.value.place);
68 }
69 break;
70 }
compiler/forget/src/Inference/DropMemoCalls.ts
+7 -3
@@ -40,9 +40,13 @@ export default function (func: HIRFunction) {
40 // after:
41 // foo = $19
42 instr.value = {
43 - kind: "Identifier",
44 - identifier: fn.identifier,
45 - effect: Effect.Unknown,
43 + kind: "LoadLocal",
44 + place: {
45 + kind: "Identifier",
46 + identifier: fn.identifier,
47 + effect: Effect.Unknown,
48 + loc: instr.value.loc,
49 + },
50 loc: instr.value.loc,
51 };
52 }
compiler/forget/src/Inference/InferAlias.ts
+3 -3
@@ -33,11 +33,11 @@ function inferInstr(instr: Instruction, state: AliasAnalyser) {
33 const { lvalue, value: instrValue } = instr;
34 let alias: Place | null = null;
35 switch (instrValue.kind) {
36 - case "Identifier": {
37 - if (isPrimitiveType(instrValue.identifier)) {
36 + case "LoadLocal": {
37 + if (isPrimitiveType(instrValue.place.identifier)) {
38 return;
39 }
40 - alias = instrValue;
40 + alias = instrValue.place;
41 break;
42 }
43 case "ComputedLoad":
compiler/forget/src/Inference/InferReferenceEffects.ts
+4 -4
@@ -188,7 +188,7 @@ class InferenceState {
188 */
189 initialize(value: InstructionValue, kind: ValueKind) {
190 invariant(
191 - value.kind !== "Identifier",
191 + value.kind !== "LoadLocal",
192 "Expected all top-level identifiers to be defined as variables, not values"
193 );
194 this.#values.set(value, kind);
@@ -782,12 +782,12 @@ function inferBlock(
782 state.alias(lvalue.place, instrValue.value);
783 continue;
784 }
785 - case "Identifier": {
786 - state.reference(instrValue, Effect.Capture);
785 + case "LoadLocal": {
786 + state.reference(instrValue.place, Effect.Capture);
787 const lvalue = instr.lvalue;
788 lvalue.place.effect = Effect.Mutate;
789 // direct aliasing: `a = b`;
790 - state.alias(lvalue.place, instrValue);
790 + state.alias(lvalue.place, instrValue.place);
791 continue;
792 }
793 default: {
compiler/forget/src/Optimization/ConstantPropagation.ts
+2 -2
@@ -308,8 +308,8 @@ function evaluateInstruction(
308 }
309 return null;
310 }
311 - case "Identifier": {
312 - return read(constants, value);
311 + case "LoadLocal": {
312 + return read(constants, value.place);
313 }
314 default: {
315 // TODO: handle more cases
compiler/forget/src/Optimization/DeadCodeElimination.ts
+1 -1
@@ -100,7 +100,7 @@ function pruneableValue(value: InstructionValue): boolean {
100 case "ComputedLoad":
101 case "ComputedStore":
102 case "FunctionExpression":
103 - case "Identifier":
103 + case "LoadLocal":
104 case "JsxExpression":
105 case "JsxFragment":
106 case "JSXText":
compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts
+5 -1
@@ -484,7 +484,11 @@ class Driver {
484 return {
485 block: defaultBlock.id,
486 place: defaultBlock.terminal.test,
487 - value: defaultBlock.terminal.test,
487 + value: {
488 + kind: "LoadLocal",
489 + place: defaultBlock.terminal.test,
490 + loc: defaultBlock.terminal.test.loc,
491 + },
492 id: defaultBlock.terminal.id,
493 };
494 } else if (defaultBlock.instructions.length === 1) {
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+3 -3
@@ -696,8 +696,8 @@ function codegenInstructionValue(
696 );
697 break;
698 }
699 - case "Identifier": {
700 - value = codegenPlace(cx, instrValue);
699 + case "LoadLocal": {
700 + value = codegenPlace(cx, instrValue.place);
701 break;
702 }
703 case "FunctionExpression": {
@@ -714,7 +714,7 @@ function codegenInstructionValue(
714 }
715 case "TypeCastExpression": {
716 value = t.typeCastExpression(
717 - codegenInstructionValue(cx, instrValue.value),
717 + codegenPlace(cx, instrValue.value),
718 instrValue.type
719 );
720 break;
compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts
+1 -1
@@ -171,7 +171,7 @@ function mayAllocate(value: InstructionValue): boolean {
171 case "LoadGlobal":
172 case "TypeCastExpression":
173 case "BinaryExpression":
174 - case "Identifier":
174 + case "LoadLocal":
175 case "PropertyLoad":
176 case "ComputedLoad":
177 case "JSXText":
compiler/forget/src/ReactiveScopes/PromoteUsedTemporaries.ts
+1 -1
@@ -57,7 +57,7 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
57 if (
58 instruction.lvalue !== null &&
59 instruction.lvalue.place.identifier.name === null &&
60 - instruction.value.kind !== "Identifier"
60 + instruction.value.kind !== "LoadLocal"
61 ) {
62 state.temporaries.set(instruction.lvalue.place.identifier, 0);
63 }
compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts
+4 -4
@@ -676,14 +676,14 @@ function visitInstructionValue(
676 value: ReactiveValue,
677 lvalue: LValue | null
678 ): void {
679 - if (value.kind === "Identifier" && lvalue !== null) {
679 + if (value.kind === "LoadLocal" && lvalue !== null) {
680 if (
681 - value.identifier.name !== null &&
681 + value.place.identifier.name !== null &&
682 lvalue.place.identifier.name === null
683 ) {
684 - context.declareTemporary(lvalue.place, value);
684 + context.declareTemporary(lvalue.place, value.place);
685 } else {
686 - context.visitOperand(value);
686 + context.visitOperand(value.place);
687 }
688 } else if (value.kind === "PropertyLoad") {
689 if (lvalue !== null) {
compiler/forget/src/ReactiveScopes/visitors.ts
+4 -4
@@ -91,12 +91,12 @@ export class ReactiveFunctionVisitor<TState = void> {
91 }
92 case "return": {
93 if (terminal.value !== null) {
94 - this.visitValue(terminal.id, terminal.value, state);
94 + this.visitPlace(terminal.id, terminal.value, state);
95 }
96 break;
97 }
98 case "throw": {
99 - this.visitValue(terminal.id, terminal.value, state);
99 + this.visitPlace(terminal.id, terminal.value, state);
100 break;
101 }
102 case "for": {
@@ -112,7 +112,7 @@ export class ReactiveFunctionVisitor<TState = void> {
112 break;
113 }
114 case "if": {
115 - this.visitValue(terminal.id, terminal.test, state);
115 + this.visitPlace(terminal.id, terminal.test, state);
116 this.visitBlock(terminal.consequent, state);
117 if (terminal.alternate !== null) {
118 this.visitBlock(terminal.alternate, state);
@@ -120,7 +120,7 @@ export class ReactiveFunctionVisitor<TState = void> {
120 break;
121 }
122 case "switch": {
123 - this.visitValue(terminal.id, terminal.test, state);
123 + this.visitPlace(terminal.id, terminal.test, state);
124 for (const case_ of terminal.cases) {
125 if (case_.test !== null) {
126 this.visitPlace(terminal.id, case_.test, state);
compiler/forget/src/SSA/LeaveSSA.ts
+7 -3
@@ -240,9 +240,13 @@ export function leaveSSA(fn: HIRFunction): void {
240 value:
241 initOperand !== null
242 ? {
243 - kind: "Identifier",
244 - identifier: initOperand,
245 - effect: Effect.Read,
243 + kind: "LoadLocal",
244 + place: {
245 + kind: "Identifier",
246 + identifier: initOperand,
247 + effect: Effect.Read,
248 + loc: GeneratedSource,
249 + },
250 loc: GeneratedSource,
251 }
252 : {
compiler/forget/src/TypeInference/InferTypes.ts
+2 -2
@@ -107,8 +107,8 @@ function* generateInstructionTypes(
107 break;
108 }
109
110 - case "Identifier": {
111 - yield equation(left, value.identifier.type);
110 + case "LoadLocal": {
111 + yield equation(left, value.place.identifier.type);
112 break;
113 }
114
compiler/forget/src/__tests__/fixtures/hir/assignment-in-nested-if.expect.md
+3 -5
@@ -24,14 +24,12 @@ function useBar(props) {
24 let z = undefined;
25 if (props.a) {
26 if (props.b) {
27 - let t0;
27 if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
29 - t0 = baz();
30 - $[0] = t0;
28 + z = baz();
29 + $[0] = z;
30 } else {
32 - t0 = $[0];
31 + z = $[0];
32 }
34 - z = t0;
33 }
34 }
35 return z;
compiler/forget/src/__tests__/fixtures/hir/capturing-function-within-block.expect.md
+4 -5
@@ -30,17 +30,16 @@ function component(a) {
30 z = $[1];
31 }
32 const c_2 = $[2] !== z;
33 - let t0;
33 + let x;
34 if (c_2) {
35 - t0 = function () {
35 + x = function () {
36 z;
37 };
38 $[2] = z;
39 - $[3] = t0;
39 + $[3] = x;
40 } else {
41 - t0 = $[3];
41 + x = $[3];
42 }
43 - const x = t0;
43 return x;
44 }
45
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+3 -5
@@ -33,14 +33,12 @@ function Component(props) {
33 if (cond) {
34 a = x;
35 } else {
36 - let t0;
36 if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
38 - t0 = [];
39 - $[0] = t0;
37 + a = [];
38 + $[0] = a;
39 } else {
41 - t0 = $[0];
40 + a = $[0];
41 }
43 - a = t0;
42 }
43
44 useFreeze(a);
compiler/forget/src/__tests__/fixtures/hir/obj-literal-cached-in-if-else.expect.md
+6 -10
@@ -23,26 +23,22 @@ function foo(a, b, c, d) {
23 let x = undefined;
24 if (someVal) {
25 const c_0 = $[0] !== b;
26 - let t0;
26 if (c_0) {
28 - t0 = { b: b };
27 + x = { b: b };
28 $[0] = b;
30 - $[1] = t0;
29 + $[1] = x;
30 } else {
32 - t0 = $[1];
31 + x = $[1];
32 }
34 - x = t0;
33 } else {
34 const c_2 = $[2] !== c;
37 - let t1;
35 if (c_2) {
39 - t1 = { c: c };
36 + x = { c: c };
37 $[2] = c;
41 - $[3] = t1;
38 + $[3] = x;
39 } else {
43 - t1 = $[3];
40 + x = $[3];
41 }
45 - x = t1;
42 }
43 return x;
44 }
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+8 -10
@@ -36,29 +36,27 @@ function Component(props) {
36 }
37 const y = x;
38 if (props.p1) {
39 - let t0;
39 if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
41 - t0 = [];
42 - $[2] = t0;
40 + x = [];
41 + $[2] = x;
42 } else {
44 - t0 = $[2];
43 + x = $[2];
44 }
46 - x = t0;
45 }
46
47 y.push(props.p2);
48 const c_3 = $[3] !== x;
49 const c_4 = $[4] !== y;
52 - let t1;
50 + let t0;
51 if (c_3 || c_4) {
54 - t1 = <Component x={x} y={y}></Component>;
52 + t0 = <Component x={x} y={y}></Component>;
53 $[3] = x;
54 $[4] = y;
57 - $[5] = t1;
55 + $[5] = t0;
56 } else {
59 - t1 = $[5];
57 + t0 = $[5];
58 }
61 - return t1;
59 + return t0;
60 }
61
62 ```
compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md
+8 -10
@@ -30,14 +30,12 @@ function Component(props) {
30 x = [];
31 x.push(props.p0);
32 y = x;
33 - let t0;
33 if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
35 - t0 = [];
36 - $[4] = t0;
34 + x = [];
35 + $[4] = x;
36 } else {
38 - t0 = $[4];
37 + x = $[4];
38 }
40 - x = t0;
39
40 y.push(props.p1);
41 $[0] = props.p0;
@@ -50,16 +48,16 @@ function Component(props) {
48 }
49 const c_5 = $[5] !== x;
50 const c_6 = $[6] !== y;
53 - let t1;
51 + let t0;
52 if (c_5 || c_6) {
55 - t1 = <Component x={x} y={y}></Component>;
53 + t0 = <Component x={x} y={y}></Component>;
54 $[5] = x;
55 $[6] = y;
58 - $[7] = t1;
56 + $[7] = t0;
57 } else {
60 - t1 = $[7];
58 + t0 = $[7];
59 }
62 - return t1;
60 + return t0;
61 }
62
63 ```
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+8 -10
@@ -45,14 +45,12 @@ function Component(props) {
45 }
46 case true: {
47 x.push(props.p2);
48 - let t0;
48 if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
50 - t0 = [];
51 - $[3] = t0;
49 + y = [];
50 + $[3] = y;
51 } else {
53 - t0 = $[3];
52 + y = $[3];
53 }
55 - y = t0;
54 break bb1;
55 }
56 default: {
@@ -81,16 +79,16 @@ function Component(props) {
79 y.push(props.p4);
80 const c_6 = $[6] !== y;
81 const c_7 = $[7] !== child;
84 - let t1;
82 + let t0;
83 if (c_6 || c_7) {
86 - t1 = <Component data={y}>{child}</Component>;
84 + t0 = <Component data={y}>{child}</Component>;
85 $[6] = y;
86 $[7] = child;
89 - $[8] = t1;
87 + $[8] = t0;
88 } else {
91 - t1 = $[8];
89 + t0 = $[8];
90 }
93 - return t1;
91 + return t0;
92 }
93
94 ```