From 88f65d44a7854753b1d2321a3903ee998776dfd7 Mon Sep 17 00:00:00 2001 From: Sathya Gunasekaran Date: Fri, 15 Sep 2023 17:16:04 +0100 Subject: [PATCH] [hir] Refactor out LoweredFunction from FunctionExpression --- .../babel-plugin-react-forget/src/HIR/BuildHIR.ts | 3 +-- .../packages/babel-plugin-react-forget/src/HIR/HIR.ts | 11 +++++++---- .../src/HIR/MergeConsecutiveBlocks.ts | 2 +- .../babel-plugin-react-forget/src/HIR/PrintHIR.ts | 6 +++--- .../babel-plugin-react-forget/src/HIR/visitors.ts | 5 +++-- .../src/Inference/AnalyseFunctions.ts | 8 ++++---- .../src/Inference/InlineUseMemo.ts | 11 +++++++---- .../src/Optimization/ConstantPropagation.ts | 4 ++-- .../src/ReactiveScopes/CodegenReactiveFunction.ts | 2 +- .../src/SSA/EliminateRedundantPhi.ts | 4 ++-- .../babel-plugin-react-forget/src/SSA/EnterSSA.ts | 2 +- .../src/TypeInference/InferTypes.ts | 4 ++-- .../src/Validation/ValidateFrozenLambdas.ts | 2 +- 13 files changed, 35 insertions(+), 29 deletions(-) diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts index d07d3f2082..521bd95287 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts @@ -2737,8 +2737,7 @@ function lowerFunctionExpression( return { kind: "FunctionExpression", name, - loweredFunc, - dependencies: captured.refs, + loweredFunc: { func: loweredFunc, dependencies: captured.refs }, expr: expr.node, loc: exprLoc, }; diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts index d086853ae7..f34a88b905 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts @@ -557,11 +557,15 @@ export type ObjectProperty = { place: Place; }; +export type LoweredFunction = { + dependencies: Array; + func: HIRFunction; +}; + export type ObjectMethod = { kind: "ObjectMethod"; - dependencies: Array; - loweredFunc: HIRFunction; loc: SourceLocation; + loweredFunc: LoweredFunction; }; export enum InstructionKind { @@ -844,8 +848,7 @@ export type JsxAttribute = export type FunctionExpression = { kind: "FunctionExpression"; name: string | null; - dependencies: Array; - loweredFunc: HIRFunction; + loweredFunc: LoweredFunction; expr: t.ArrowFunctionExpression | t.FunctionExpression; loc: SourceLocation; }; diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/MergeConsecutiveBlocks.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/MergeConsecutiveBlocks.ts index e2f210ae01..2c1f955e74 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/MergeConsecutiveBlocks.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/MergeConsecutiveBlocks.ts @@ -33,7 +33,7 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void { for (const [, block] of fn.body.blocks) { for (const instr of block.instructions) { if (instr.value.kind === "FunctionExpression") { - mergeConsecutiveBlocks(instr.value.loweredFunc); + mergeConsecutiveBlocks(instr.value.loweredFunc.func); } } diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts index 04cf43facd..9f1e4468a1 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts @@ -463,14 +463,14 @@ export function printInstructionValue(instrValue: ReactiveValue): string { break; } case "FunctionExpression": { - const fn = printFunction(instrValue.loweredFunc) + const fn = printFunction(instrValue.loweredFunc.func) .split("\n") .map((line) => ` ${line}`) .join("\n"); - const deps = instrValue.dependencies + const deps = instrValue.loweredFunc.dependencies .map((dep) => printPlace(dep)) .join(","); - const context = instrValue.loweredFunc.context + const context = instrValue.loweredFunc.func.context .map((dep) => printPlace(dep)) .join(","); value = `Function @deps[${deps}] @context[${context}]:\n${fn}`; diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts index 79b2ce3970..3b29f62d82 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts @@ -170,7 +170,7 @@ export function* eachInstructionValueOperand( break; } case "FunctionExpression": { - yield* instrValue.dependencies; + yield* instrValue.loweredFunc.dependencies; break; } case "TaggedTemplateExpression": { @@ -457,7 +457,8 @@ export function mapInstructionOperands( break; } case "FunctionExpression": { - instrValue.dependencies = instrValue.dependencies.map((d) => fn(d)); + instrValue.loweredFunc.dependencies = + instrValue.loweredFunc.dependencies.map((d) => fn(d)); break; } case "TaggedTemplateExpression": { diff --git a/compiler/packages/babel-plugin-react-forget/src/Inference/AnalyseFunctions.ts b/compiler/packages/babel-plugin-react-forget/src/Inference/AnalyseFunctions.ts index 6aa56f00ee..0c232a135a 100644 --- a/compiler/packages/babel-plugin-react-forget/src/Inference/AnalyseFunctions.ts +++ b/compiler/packages/babel-plugin-react-forget/src/Inference/AnalyseFunctions.ts @@ -71,7 +71,7 @@ export default function analyseFunctions(func: HIRFunction): void { for (const instr of block.instructions) { switch (instr.value.kind) { case "FunctionExpression": { - lower(instr.value.loweredFunc); + lower(instr.value.loweredFunc.func); infer(instr.value, state, func.context); break; } @@ -118,7 +118,7 @@ function infer( context: Place[] ): void { const mutations = new Map(); - for (const operand of value.loweredFunc.context) { + for (const operand of value.loweredFunc.func.context) { if ( isMutatedOrReassigned(operand.identifier) && operand.identifier.name !== null @@ -128,7 +128,7 @@ function infer( operand.identifier.mutableRange.end = operand.identifier.mutableRange.start; } - for (const dep of value.dependencies) { + for (const dep of value.loweredFunc.dependencies) { let name: string | null = null; if (state.properties.has(dep.identifier)) { @@ -174,7 +174,7 @@ function infer( const effect = mutations.get(place.identifier.name); if (effect !== undefined) { place.effect = effect === Effect.Unknown ? Effect.Capture : effect; - value.dependencies.push(place); + value.loweredFunc.dependencies.push(place); } } } diff --git a/compiler/packages/babel-plugin-react-forget/src/Inference/InlineUseMemo.ts b/compiler/packages/babel-plugin-react-forget/src/Inference/InlineUseMemo.ts index 8103be12f0..904f006df8 100644 --- a/compiler/packages/babel-plugin-react-forget/src/Inference/InlineUseMemo.ts +++ b/compiler/packages/babel-plugin-react-forget/src/Inference/InlineUseMemo.ts @@ -99,7 +99,7 @@ export function inlineUseMemo(fn: HIRFunction): void { continue; } - if (body.loweredFunc.params.length > 0) { + if (body.loweredFunc.func.params.length > 0) { CompilerError.invalidReact({ reason: "useMemo callbacks may not accept any arguments", description: null, @@ -108,7 +108,10 @@ export function inlineUseMemo(fn: HIRFunction): void { }); } - if (body.loweredFunc.async || body.loweredFunc.generator) { + if ( + body.loweredFunc.func.async || + body.loweredFunc.func.generator + ) { CompilerError.invalidReact({ reason: "useMemo callbacks may not be async or generator functions", @@ -141,7 +144,7 @@ export function inlineUseMemo(fn: HIRFunction): void { // as if it were a single labeled statement, and replace all returns with gotos // to the label fallthrough. const newTerminal: LabelTerminal = { - block: body.loweredFunc.body.entry, + block: body.loweredFunc.func.body.entry, id: makeInstructionId(0), kind: "label", fallthrough: continuationBlockId, @@ -160,7 +163,7 @@ export function inlineUseMemo(fn: HIRFunction): void { // Rewrite blocks from the lambda to replace any `return` with a // store to the result and `goto` the continuation block - for (const [id, block] of body.loweredFunc.body.blocks) { + for (const [id, block] of body.loweredFunc.func.body.blocks) { block.preds.clear(); rewriteBlock(fn.env, block, continuationBlockId, result); fn.body.blocks.set(id, block); diff --git a/compiler/packages/babel-plugin-react-forget/src/Optimization/ConstantPropagation.ts b/compiler/packages/babel-plugin-react-forget/src/Optimization/ConstantPropagation.ts index 56b3dc6fd5..c692e8633e 100644 --- a/compiler/packages/babel-plugin-react-forget/src/Optimization/ConstantPropagation.ts +++ b/compiler/packages/babel-plugin-react-forget/src/Optimization/ConstantPropagation.ts @@ -107,7 +107,7 @@ function applyConstantPropagation( for (const [, block] of fn.body.blocks) { for (const instr of block.instructions) { if (instr.value.kind === "FunctionExpression") { - for (const operand of instr.value.dependencies) { + for (const operand of instr.value.loweredFunc.dependencies) { functionDependencies.add(operand.identifier.id); } } @@ -434,7 +434,7 @@ function evaluateInstruction( return placeValue; } case "FunctionExpression": { - constantPropagationImpl(value.loweredFunc, constants); + constantPropagationImpl(value.loweredFunc.func, constants); return null; } default: { diff --git a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts index e4a2855942..0a7b64d943 100644 --- a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -1088,7 +1088,7 @@ function codegenInstructionValue( break; } case "FunctionExpression": { - const loweredFunc = instrValue.loweredFunc; + const loweredFunc = instrValue.loweredFunc.func; const reactiveFunction = buildReactiveFunction(loweredFunc); pruneUnusedLabels(reactiveFunction); pruneUnusedLValues(reactiveFunction); diff --git a/compiler/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts b/compiler/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts index cb622ac903..b6ccc436a1 100644 --- a/compiler/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts +++ b/compiler/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts @@ -107,7 +107,7 @@ export function eliminateRedundantPhi( } if (instr.value.kind === "FunctionExpression") { - const { context } = instr.value.loweredFunc; + const { context } = instr.value.loweredFunc.func; for (const place of context) { rewritePlace(place, rewrites); } @@ -115,7 +115,7 @@ export function eliminateRedundantPhi( // recursive call to: // - eliminate phi nodes in child node // - propagate rewrites, which may have changed between iterations - eliminateRedundantPhi(instr.value.loweredFunc, rewrites); + eliminateRedundantPhi(instr.value.loweredFunc.func, rewrites); } } diff --git a/compiler/packages/babel-plugin-react-forget/src/SSA/EnterSSA.ts b/compiler/packages/babel-plugin-react-forget/src/SSA/EnterSSA.ts index 7cbd779282..d96ade703e 100644 --- a/compiler/packages/babel-plugin-react-forget/src/SSA/EnterSSA.ts +++ b/compiler/packages/babel-plugin-react-forget/src/SSA/EnterSSA.ts @@ -267,7 +267,7 @@ function enterSSAImpl( mapInstructionLValues(instr, (lvalue) => builder.definePlace(lvalue)); if (instr.value.kind === "FunctionExpression") { - const loweredFunc = instr.value.loweredFunc; + const loweredFunc = instr.value.loweredFunc.func; const entry = loweredFunc.body.blocks.get(loweredFunc.body.entry)!; CompilerError.invariant(entry.preds.size === 0, { reason: diff --git a/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts b/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts index 2a606f415b..33233b5c5f 100644 --- a/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts +++ b/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts @@ -69,7 +69,7 @@ function apply(func: HIRFunction, unifier: Unifier): void { lvalue.identifier.type = unifier.get(lvalue.identifier.type); if (value.kind === "FunctionExpression") { - apply(value.loweredFunc, unifier); + apply(value.loweredFunc.func, unifier); } } } @@ -256,7 +256,7 @@ function* generateInstructionTypes( } case "FunctionExpression": { - yield* generate(value.loweredFunc); + yield* generate(value.loweredFunc.func); break; } diff --git a/compiler/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts b/compiler/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts index ca76e43fb0..86fb89f9f3 100644 --- a/compiler/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts +++ b/compiler/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts @@ -68,7 +68,7 @@ export function validateFrozenLambdas(fn: HIRFunction): void { switch (instr.value.kind) { case "FunctionExpression": { if ( - instr.value.dependencies.some( + instr.value.loweredFunc.dependencies.some( (place) => place.effect === Effect.Mutate && !isRefValueType(place.identifier) &&