[hir] Refactor out LoweredFunction from FunctionExpression
Sathya Gunasekaran committed
Sep 15, 2023 at 17:16 UTC
88f65d44a7854753b1d2321a3903ee998776dfd7
13 files changed
+35
-29
compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+1
-2
@@ -2737,8 +2737,7 @@ function lowerFunctionExpression(
2737
return {
2738
kind: "FunctionExpression",
2739
name,
2740
- loweredFunc,
2741
- dependencies: captured.refs,
2740
+ loweredFunc: { func: loweredFunc, dependencies: captured.refs },
2741
expr: expr.node,
2742
loc: exprLoc,
2743
};
compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts
+7
-4
@@ -557,11 +557,15 @@ export type ObjectProperty = {
557
place: Place;
558
};
559
560
+export type LoweredFunction = {
561
+ dependencies: Array<Place>;
562
+ func: HIRFunction;
563
+};
564
+
565
export type ObjectMethod = {
566
kind: "ObjectMethod";
562
- dependencies: Array<Place>;
563
- loweredFunc: HIRFunction;
567
loc: SourceLocation;
568
+ loweredFunc: LoweredFunction;
569
};
570
571
export enum InstructionKind {
@@ -844,8 +848,7 @@ export type JsxAttribute =
848
export type FunctionExpression = {
849
kind: "FunctionExpression";
850
name: string | null;
847
- dependencies: Array<Place>;
848
- loweredFunc: HIRFunction;
851
+ loweredFunc: LoweredFunction;
852
expr: t.ArrowFunctionExpression | t.FunctionExpression;
853
loc: SourceLocation;
854
};
compiler/packages/babel-plugin-react-forget/src/HIR/MergeConsecutiveBlocks.ts
+1
-1
@@ -33,7 +33,7 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void {
33
for (const [, block] of fn.body.blocks) {
34
for (const instr of block.instructions) {
35
if (instr.value.kind === "FunctionExpression") {
36
- mergeConsecutiveBlocks(instr.value.loweredFunc);
36
+ mergeConsecutiveBlocks(instr.value.loweredFunc.func);
37
}
38
}
39
compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts
+3
-3
@@ -463,14 +463,14 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
463
break;
464
}
465
case "FunctionExpression": {
466
- const fn = printFunction(instrValue.loweredFunc)
466
+ const fn = printFunction(instrValue.loweredFunc.func)
467
.split("\n")
468
.map((line) => ` ${line}`)
469
.join("\n");
470
- const deps = instrValue.dependencies
470
+ const deps = instrValue.loweredFunc.dependencies
471
.map((dep) => printPlace(dep))
472
.join(",");
473
- const context = instrValue.loweredFunc.context
473
+ const context = instrValue.loweredFunc.func.context
474
.map((dep) => printPlace(dep))
475
.join(",");
476
value = `Function @deps[${deps}] @context[${context}]:\n${fn}`;
compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts
+3
-2
@@ -170,7 +170,7 @@ export function* eachInstructionValueOperand(
170
break;
171
}
172
case "FunctionExpression": {
173
- yield* instrValue.dependencies;
173
+ yield* instrValue.loweredFunc.dependencies;
174
break;
175
}
176
case "TaggedTemplateExpression": {
@@ -457,7 +457,8 @@ export function mapInstructionOperands(
457
break;
458
}
459
case "FunctionExpression": {
460
- instrValue.dependencies = instrValue.dependencies.map((d) => fn(d));
460
+ instrValue.loweredFunc.dependencies =
461
+ instrValue.loweredFunc.dependencies.map((d) => fn(d));
462
break;
463
}
464
case "TaggedTemplateExpression": {
compiler/packages/babel-plugin-react-forget/src/Inference/AnalyseFunctions.ts
+4
-4
@@ -71,7 +71,7 @@ export default function analyseFunctions(func: HIRFunction): void {
71
for (const instr of block.instructions) {
72
switch (instr.value.kind) {
73
case "FunctionExpression": {
74
- lower(instr.value.loweredFunc);
74
+ lower(instr.value.loweredFunc.func);
75
infer(instr.value, state, func.context);
76
break;
77
}
@@ -118,7 +118,7 @@ function infer(
118
context: Place[]
119
): void {
120
const mutations = new Map<string, Effect>();
121
- for (const operand of value.loweredFunc.context) {
121
+ for (const operand of value.loweredFunc.func.context) {
122
if (
123
isMutatedOrReassigned(operand.identifier) &&
124
operand.identifier.name !== null
@@ -128,7 +128,7 @@ function infer(
128
operand.identifier.mutableRange.end = operand.identifier.mutableRange.start;
129
}
130
131
- for (const dep of value.dependencies) {
131
+ for (const dep of value.loweredFunc.dependencies) {
132
let name: string | null = null;
133
134
if (state.properties.has(dep.identifier)) {
@@ -174,7 +174,7 @@ function infer(
174
const effect = mutations.get(place.identifier.name);
175
if (effect !== undefined) {
176
place.effect = effect === Effect.Unknown ? Effect.Capture : effect;
177
- value.dependencies.push(place);
177
+ value.loweredFunc.dependencies.push(place);
178
}
179
}
180
}
compiler/packages/babel-plugin-react-forget/src/Inference/InlineUseMemo.ts
+7
-4
@@ -99,7 +99,7 @@ export function inlineUseMemo(fn: HIRFunction): void {
99
continue;
100
}
101
102
- if (body.loweredFunc.params.length > 0) {
102
+ if (body.loweredFunc.func.params.length > 0) {
103
CompilerError.invalidReact({
104
reason: "useMemo callbacks may not accept any arguments",
105
description: null,
@@ -108,7 +108,10 @@ export function inlineUseMemo(fn: HIRFunction): void {
108
});
109
}
110
111
- if (body.loweredFunc.async || body.loweredFunc.generator) {
111
+ if (
112
+ body.loweredFunc.func.async ||
113
+ body.loweredFunc.func.generator
114
+ ) {
115
CompilerError.invalidReact({
116
reason:
117
"useMemo callbacks may not be async or generator functions",
@@ -141,7 +144,7 @@ export function inlineUseMemo(fn: HIRFunction): void {
144
// as if it were a single labeled statement, and replace all returns with gotos
145
// to the label fallthrough.
146
const newTerminal: LabelTerminal = {
144
- block: body.loweredFunc.body.entry,
147
+ block: body.loweredFunc.func.body.entry,
148
id: makeInstructionId(0),
149
kind: "label",
150
fallthrough: continuationBlockId,
@@ -160,7 +163,7 @@ export function inlineUseMemo(fn: HIRFunction): void {
163
164
// Rewrite blocks from the lambda to replace any `return` with a
165
// store to the result and `goto` the continuation block
163
- for (const [id, block] of body.loweredFunc.body.blocks) {
166
+ for (const [id, block] of body.loweredFunc.func.body.blocks) {
167
block.preds.clear();
168
rewriteBlock(fn.env, block, continuationBlockId, result);
169
fn.body.blocks.set(id, block);
compiler/packages/babel-plugin-react-forget/src/Optimization/ConstantPropagation.ts
+2
-2
@@ -107,7 +107,7 @@ function applyConstantPropagation(
107
for (const [, block] of fn.body.blocks) {
108
for (const instr of block.instructions) {
109
if (instr.value.kind === "FunctionExpression") {
110
- for (const operand of instr.value.dependencies) {
110
+ for (const operand of instr.value.loweredFunc.dependencies) {
111
functionDependencies.add(operand.identifier.id);
112
}
113
}
@@ -434,7 +434,7 @@ function evaluateInstruction(
434
return placeValue;
435
}
436
case "FunctionExpression": {
437
- constantPropagationImpl(value.loweredFunc, constants);
437
+ constantPropagationImpl(value.loweredFunc.func, constants);
438
return null;
439
}
440
default: {
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+1
-1
@@ -1088,7 +1088,7 @@ function codegenInstructionValue(
1088
break;
1089
}
1090
case "FunctionExpression": {
1091
- const loweredFunc = instrValue.loweredFunc;
1091
+ const loweredFunc = instrValue.loweredFunc.func;
1092
const reactiveFunction = buildReactiveFunction(loweredFunc);
1093
pruneUnusedLabels(reactiveFunction);
1094
pruneUnusedLValues(reactiveFunction);
compiler/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts
+2
-2
@@ -107,7 +107,7 @@ export function eliminateRedundantPhi(
107
}
108
109
if (instr.value.kind === "FunctionExpression") {
110
- const { context } = instr.value.loweredFunc;
110
+ const { context } = instr.value.loweredFunc.func;
111
for (const place of context) {
112
rewritePlace(place, rewrites);
113
}
@@ -115,7 +115,7 @@ export function eliminateRedundantPhi(
115
// recursive call to:
116
// - eliminate phi nodes in child node
117
// - propagate rewrites, which may have changed between iterations
118
- eliminateRedundantPhi(instr.value.loweredFunc, rewrites);
118
+ eliminateRedundantPhi(instr.value.loweredFunc.func, rewrites);
119
}
120
}
121
compiler/packages/babel-plugin-react-forget/src/SSA/EnterSSA.ts
+1
-1
@@ -267,7 +267,7 @@ function enterSSAImpl(
267
mapInstructionLValues(instr, (lvalue) => builder.definePlace(lvalue));
268
269
if (instr.value.kind === "FunctionExpression") {
270
- const loweredFunc = instr.value.loweredFunc;
270
+ const loweredFunc = instr.value.loweredFunc.func;
271
const entry = loweredFunc.body.blocks.get(loweredFunc.body.entry)!;
272
CompilerError.invariant(entry.preds.size === 0, {
273
reason:
compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts
+2
-2
@@ -69,7 +69,7 @@ function apply(func: HIRFunction, unifier: Unifier): void {
69
lvalue.identifier.type = unifier.get(lvalue.identifier.type);
70
71
if (value.kind === "FunctionExpression") {
72
- apply(value.loweredFunc, unifier);
72
+ apply(value.loweredFunc.func, unifier);
73
}
74
}
75
}
@@ -256,7 +256,7 @@ function* generateInstructionTypes(
256
}
257
258
case "FunctionExpression": {
259
- yield* generate(value.loweredFunc);
259
+ yield* generate(value.loweredFunc.func);
260
break;
261
}
262
compiler/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts
+1
-1
@@ -68,7 +68,7 @@ export function validateFrozenLambdas(fn: HIRFunction): void {
68
switch (instr.value.kind) {
69
case "FunctionExpression": {
70
if (
71
- instr.value.dependencies.some(
71
+ instr.value.loweredFunc.dependencies.some(
72
(place) =>
73
place.effect === Effect.Mutate &&
74
!isRefValueType(place.identifier) &&