Add StoreGlobal instruction
ghstack-source-id: a715b1385da6648d867118d2b7486ffdb0ff89f6 Pull Request resolved: https://github.com/facebook/react-forget/pull/2871
Joe Savona committed
Apr 18, 2024 at 13:21 UTC
d870c979a127e210856484e25c0affa5615faeec
9 files changed
+62
-3
compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts
+8
@@ -897,6 +897,7 @@ export type InstructionValue =
897
loc: SourceLocation;
898
}
899
| LoadGlobal
900
+ | StoreGlobal
901
| FunctionExpression
902
| {
903
kind: "TaggedTemplateExpression";
@@ -1030,6 +1031,13 @@ export type LoadGlobal = {
1031
loc: SourceLocation;
1032
};
1033
1034
+export type StoreGlobal = {
1035
+ kind: "StoreGlobal";
1036
+ name: string;
1037
+ value: Place;
1038
+ loc: SourceLocation;
1039
+};
1040
+
1041
export type BuiltinTag = {
1042
kind: "BuiltinTag";
1043
name: string;
compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts
+7
-1
@@ -571,7 +571,13 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
571
break;
572
}
573
case "LoadGlobal": {
574
- value = `Global ${instrValue.name}`;
574
+ value = `LoadGlobal ${instrValue.name}`;
575
+ break;
576
+ }
577
+ case "StoreGlobal": {
578
+ value = `StoreGlobal ${instrValue.name} = ${printPlace(
579
+ instrValue.value
580
+ )}`;
581
break;
582
}
583
case "OptionalExpression": {
compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts
+8
@@ -93,6 +93,10 @@ export function* eachInstructionValueOperand(
93
yield instrValue.value;
94
break;
95
}
96
+ case "StoreGlobal": {
97
+ yield instrValue.value;
98
+ break;
99
+ }
100
case "Destructure": {
101
yield instrValue.value;
102
break;
@@ -421,6 +425,10 @@ export function mapInstructionValueOperands(
425
instrValue.value = fn(instrValue.value);
426
break;
427
}
428
+ case "StoreGlobal": {
429
+ instrValue.value = fn(instrValue.value);
430
+ break;
431
+ }
432
case "Destructure": {
433
instrValue.value = fn(instrValue.value);
434
break;
compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts
+11
@@ -1572,6 +1572,17 @@ function inferBlock(
1572
lvalue.effect = Effect.Store;
1573
continue;
1574
}
1575
+ case "StoreGlobal": {
1576
+ state.reference(
1577
+ instrValue.value,
1578
+ functionEffects,
1579
+ Effect.Capture,
1580
+ ValueReason.Other
1581
+ );
1582
+ const lvalue = instr.lvalue;
1583
+ lvalue.effect = Effect.Store;
1584
+ continue;
1585
+ }
1586
case "Destructure": {
1587
let effect: Effect = Effect.Capture;
1588
for (const place of eachPatternOperand(instrValue.lvalue.pattern)) {
compiler/packages/babel-plugin-react-forget/src/Optimization/DeadCodeElimination.ts
+2
-1
@@ -310,7 +310,8 @@ function pruneableValue(value: InstructionValue, state: State): boolean {
310
case "ComputedStore":
311
case "PropertyDelete":
312
case "MethodCall":
313
- case "PropertyStore": {
313
+ case "PropertyStore":
314
+ case "StoreGlobal": {
315
/*
316
* Mutating instructions are not safe to prune.
317
* TODO: we could be more precise and make this conditional on whether
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+8
@@ -1813,6 +1813,14 @@ function codegenInstructionValue(
1813
);
1814
break;
1815
}
1816
+ case "StoreGlobal": {
1817
+ value = t.assignmentExpression(
1818
+ "=",
1819
+ t.identifier(instrValue.name),
1820
+ codegenPlaceToExpression(cx, instrValue.value)
1821
+ );
1822
+ break;
1823
+ }
1824
case "ReactiveFunctionValue":
1825
case "StartMemoize":
1826
case "FinishMemoize":
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/InferReactiveScopeVariables.ts
+2
-1
@@ -195,7 +195,8 @@ function mayAllocate(env: Environment, instruction: Instruction): boolean {
195
case "FinishMemoize":
196
case "UnaryExpression":
197
case "BinaryExpression":
198
- case "PropertyLoad": {
198
+ case "PropertyLoad":
199
+ case "StoreGlobal": {
200
return false;
201
}
202
case "CallExpression":
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneNonEscapingScopes.ts
+11
@@ -571,6 +571,17 @@ function computeMemoizationInputs(
571
rvalues: [value.value],
572
};
573
}
574
+ case "StoreGlobal": {
575
+ const lvalues = [];
576
+ if (lvalue !== null) {
577
+ lvalues.push({ place: lvalue, level: MemoizationLevel.Unmemoized });
578
+ }
579
+
580
+ return {
581
+ lvalues,
582
+ rvalues: [value.value],
583
+ };
584
+ }
585
case "Destructure": {
586
// Indirection for the inner value, memoized if the value is
587
const lvalues = [];
compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts
+5
@@ -174,6 +174,11 @@ function* generateInstructionTypes(
174
break;
175
}
176
177
+ case "StoreGlobal": {
178
+ yield equation(left, value.value.identifier.type);
179
+ break;
180
+ }
181
+
182
case "BinaryExpression": {
183
if (isPrimitiveBinaryOp(value.operator)) {
184
yield equation(value.left.identifier.type, { kind: "Primitive" });