diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index b9f82eea18e9f..b31f73c796095 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -1235,6 +1235,7 @@ function lowerStatement( kind: 'Debugger', loc, }, + effects: null, loc, }); return; @@ -1892,6 +1893,7 @@ function lowerExpression( place: leftValue, loc: exprLoc, }, + effects: null, loc: exprLoc, }); builder.terminateWithContinuation( @@ -2827,6 +2829,7 @@ function lowerOptionalCallExpression( args, loc, }, + effects: null, loc, }); } else { @@ -2840,6 +2843,7 @@ function lowerOptionalCallExpression( args, loc, }, + effects: null, loc, }); } @@ -3466,9 +3470,10 @@ function lowerValueToTemporary( const place: Place = buildTemporaryPlace(builder, value.loc); builder.push({ id: makeInstructionId(0), + lvalue: {...place}, value: value, + effects: null, loc: value.loc, - lvalue: {...place}, }); return place; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index 991ac9e72d16c..b170820f136f9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -13,6 +13,7 @@ import {Environment, ReactFunctionType} from './Environment'; import type {HookKind} from './ObjectShape'; import {Type, makeType} from './Types'; import {z} from 'zod'; +import {AliasingEffect} from '../Inference/InferMutationAliasingEffects'; /* * ******************************************************************************************* @@ -649,12 +650,18 @@ export type Instruction = { lvalue: Place; value: InstructionValue; loc: SourceLocation; + effects: Array | null; }; +export function todoPopulateAliasingEffects(): Array | null { + return null; +} + export type TInstruction = { id: InstructionId; lvalue: Place; value: T; + effects: Array | null; loc: SourceLocation; }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts index ea132b772aa44..3d6ae4e6b211d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts @@ -12,6 +12,7 @@ import { GeneratedSource, HIRFunction, Instruction, + Place, } from './HIR'; import {markPredecessors} from './HIRBuilder'; import {terminalFallthrough, terminalHasFallthrough} from './visitors'; @@ -80,20 +81,22 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void { suggestions: null, }); const operand = Array.from(phi.operands.values())[0]!; + const lvalue: Place = { + kind: 'Identifier', + identifier: phi.place.identifier, + effect: Effect.ConditionallyMutate, + reactive: false, + loc: GeneratedSource, + }; const instr: Instruction = { id: predecessor.terminal.id, - lvalue: { - kind: 'Identifier', - identifier: phi.place.identifier, - effect: Effect.ConditionallyMutate, - reactive: false, - loc: GeneratedSource, - }, + lvalue: {...lvalue}, value: { kind: 'LoadLocal', place: {...operand}, loc: GeneratedSource, }, + effects: [{kind: 'Alias', from: {...operand}, into: {...lvalue}}], loc: GeneratedSource, }; predecessor.instructions.push(instr); diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts index 8d123845c3739..306e636b12b3a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts @@ -197,6 +197,7 @@ function makeManualMemoizationMarkers( deps: depsList, loc: fnExpr.loc, }, + effects: null, loc: fnExpr.loc, }, { @@ -208,6 +209,7 @@ function makeManualMemoizationMarkers( decl: {...memoDecl}, loc: fnExpr.loc, }, + effects: null, loc: fnExpr.loc, }, ]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts index f1a584341912b..2878b72877fd6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts @@ -29,6 +29,7 @@ import { isSetStateType, isFireFunctionType, makeScopeId, + todoPopulateAliasingEffects, } from '../HIR'; import {collectHoistablePropertyLoadsInInnerFn} from '../HIR/CollectHoistablePropertyLoads'; import {collectOptionalChainSidemap} from '../HIR/CollectOptionalChainDependencies'; @@ -236,9 +237,10 @@ export function inferEffectDependencies(fn: HIRFunction): void { newInstructions.push({ id: makeInstructionId(0), - loc: GeneratedSource, lvalue: {...depsPlace, effect: Effect.Mutate}, + effects: todoPopulateAliasingEffects(), value: deps, + loc: GeneratedSource, }); // Step 2: push the inferred deps array as an argument of the useEffect @@ -249,9 +251,10 @@ export function inferEffectDependencies(fn: HIRFunction): void { // Global functions have no reactive dependencies, so we can insert an empty array newInstructions.push({ id: makeInstructionId(0), - loc: GeneratedSource, lvalue: {...depsPlace, effect: Effect.Mutate}, + effects: todoPopulateAliasingEffects(), value: deps, + loc: GeneratedSource, }); value.args.push({...depsPlace, effect: Effect.Freeze}); rewriteInstrs.set(instr.id, newInstructions); @@ -316,21 +319,25 @@ function writeDependencyToInstructions( const instructions: Array = []; let currValue = createTemporaryPlace(env, GeneratedSource); currValue.reactive = reactive; + const dependencyPlace: Place = { + kind: 'Identifier', + identifier: dep.identifier, + effect: Effect.Capture, + reactive, + loc: loc, + }; instructions.push({ id: makeInstructionId(0), loc: GeneratedSource, lvalue: {...currValue, effect: Effect.Mutate}, value: { kind: 'LoadLocal', - place: { - kind: 'Identifier', - identifier: dep.identifier, - effect: Effect.Capture, - reactive, - loc: loc, - }, + place: {...dependencyPlace}, loc: loc, }, + effects: [ + {kind: 'Alias', from: {...dependencyPlace}, into: {...currValue}}, + ], }); for (const path of dep.path) { if (path.optional) { @@ -359,6 +366,7 @@ function writeDependencyToInstructions( property: path.property, loc: loc, }, + effects: [{kind: 'Capture', from: {...currValue}, into: {...nextValue}}], }); currValue = nextValue; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InlineImmediatelyInvokedFunctionExpressions.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InlineImmediatelyInvokedFunctionExpressions.ts index c6c6f2f54fbef..26fd710f2c39d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InlineImmediatelyInvokedFunctionExpressions.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InlineImmediatelyInvokedFunctionExpressions.ts @@ -235,6 +235,7 @@ function rewriteBlock( type: null, loc: terminal.loc, }, + effects: null, }); block.terminal = { kind: 'goto', @@ -263,5 +264,6 @@ function declareTemporary( type: null, loc: result.loc, }, + effects: null, }); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/InlineJsxTransform.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/InlineJsxTransform.ts index 29c59c7b3644a..8a26ed9022e71 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/InlineJsxTransform.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/InlineJsxTransform.ts @@ -27,6 +27,7 @@ import { Place, promoteTemporary, SpreadPattern, + todoPopulateAliasingEffects, } from '../HIR'; import { createTemporaryPlace, @@ -151,6 +152,7 @@ export function inlineJsxTransform( type: null, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; currentBlockInstructions.push(varInstruction); @@ -167,6 +169,7 @@ export function inlineJsxTransform( }, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; currentBlockInstructions.push(devGlobalInstruction); @@ -220,6 +223,7 @@ export function inlineJsxTransform( type: null, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; thenBlockInstructions.push(reassignElseInstruction); @@ -292,6 +296,7 @@ export function inlineJsxTransform( ], loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; elseBlockInstructions.push(reactElementInstruction); @@ -309,6 +314,7 @@ export function inlineJsxTransform( type: null, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; elseBlockInstructions.push(reassignConditionalInstruction); @@ -436,6 +442,7 @@ function createSymbolProperty( binding: {kind: 'Global', name: 'Symbol'}, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; nextInstructions.push(symbolInstruction); @@ -450,6 +457,7 @@ function createSymbolProperty( property: makePropertyLiteral('for'), loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; nextInstructions.push(symbolForInstruction); @@ -463,6 +471,7 @@ function createSymbolProperty( value: symbolName, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; nextInstructions.push(symbolValueInstruction); @@ -478,6 +487,7 @@ function createSymbolProperty( args: [symbolValueInstruction.lvalue], loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; const $$typeofProperty: ObjectProperty = { @@ -508,6 +518,7 @@ function createTagProperty( value: componentTag.name, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; tagProperty = { @@ -634,6 +645,7 @@ function createPropsProperties( elements: [...children], loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; nextInstructions.push(childrenPropInstruction); @@ -657,6 +669,7 @@ function createPropsProperties( value: null, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; refProperty = { @@ -678,6 +691,7 @@ function createPropsProperties( value: null, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; keyProperty = { @@ -711,6 +725,7 @@ function createPropsProperties( properties: props, loc: instr.value.loc, }, + effects: todoPopulateAliasingEffects(), loc: instr.loc, }; propsProperty = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts index 834f60195af29..55205a366d337 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts @@ -29,6 +29,7 @@ import { markInstructionIds, promoteTemporary, reversePostorderBlocks, + todoPopulateAliasingEffects, } from '../HIR'; import {createTemporaryPlace} from '../HIR/HIRBuilder'; import {enterSSA} from '../SSA'; @@ -146,6 +147,7 @@ function emitLoadLoweredContextCallee( id: makeInstructionId(0), loc: GeneratedSource, lvalue: createTemporaryPlace(env, GeneratedSource), + effects: todoPopulateAliasingEffects(), value: loadGlobal, }; } @@ -192,6 +194,7 @@ function emitPropertyLoad( lvalue: object, value: loadObj, id: makeInstructionId(0), + effects: todoPopulateAliasingEffects(), loc: GeneratedSource, }; @@ -206,6 +209,7 @@ function emitPropertyLoad( lvalue: element, value: loadProp, id: makeInstructionId(0), + effects: todoPopulateAliasingEffects(), loc: GeneratedSource, }; return { @@ -278,6 +282,7 @@ function emitSelectorFn(env: Environment, keys: Array): Instruction { loc: GeneratedSource, }, lvalue: createTemporaryPlace(env, GeneratedSource), + effects: todoPopulateAliasingEffects(), loc: GeneratedSource, }; return fnInstr; @@ -294,6 +299,7 @@ function emitArrayInstr(elements: Array, env: Environment): Instruction { id: makeInstructionId(0), value: array, lvalue: arrayLvalue, + effects: todoPopulateAliasingEffects(), loc: GeneratedSource, }; return arrayInstr; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts index d35c4d77362db..46383e666c845 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts @@ -26,6 +26,7 @@ import { Place, promoteTemporary, promoteTemporaryJsxTag, + todoPopulateAliasingEffects, } from '../HIR/HIR'; import {createTemporaryPlace} from '../HIR/HIRBuilder'; import {printIdentifier} from '../HIR/PrintHIR'; @@ -297,6 +298,7 @@ function emitOutlinedJsx( }, loc: GeneratedSource, }, + effects: null, }; promoteTemporaryJsxTag(loadJsx.lvalue.identifier); const jsxExpr: Instruction = { @@ -312,6 +314,7 @@ function emitOutlinedJsx( openingLoc: GeneratedSource, closingLoc: GeneratedSource, }, + effects: todoPopulateAliasingEffects(), }; return [loadJsx, jsxExpr]; @@ -517,6 +520,7 @@ function emitDestructureProps( loc: GeneratedSource, value: propsObj, }, + effects: todoPopulateAliasingEffects(), }; return destructurePropsInstr; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Transform/TransformFire.ts b/compiler/packages/babel-plugin-react-compiler/src/Transform/TransformFire.ts index b033af6750c37..86f38077f65ec 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Transform/TransformFire.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Transform/TransformFire.ts @@ -31,6 +31,7 @@ import { NonLocalImportSpecifier, Place, promoteTemporary, + todoPopulateAliasingEffects, } from '../HIR'; import {createTemporaryPlace, markInstructionIds} from '../HIR/HIRBuilder'; import {getOrInsertWith} from '../Utils/utils'; @@ -436,6 +437,7 @@ function makeLoadUseFireInstruction( value: instrValue, lvalue: {...useFirePlace}, loc: GeneratedSource, + effects: todoPopulateAliasingEffects(), }; } @@ -460,6 +462,7 @@ function makeLoadFireCalleeInstruction( }, lvalue: {...loadedFireCallee}, loc: GeneratedSource, + effects: todoPopulateAliasingEffects(), }; } @@ -483,6 +486,7 @@ function makeCallUseFireInstruction( value: useFireCall, lvalue: {...useFireCallResultPlace}, loc: GeneratedSource, + effects: todoPopulateAliasingEffects(), }; } @@ -511,6 +515,7 @@ function makeStoreUseFireInstruction( }, lvalue: fireFunctionBindingLValuePlace, loc: GeneratedSource, + effects: todoPopulateAliasingEffects(), }; }