[compiler] Add Instruction.effects property

ghstack-source-id: ffdbd73de5
Pull Request resolved: https://github.com/facebook/react/pull/33350
This commit is contained in:
Joe Savona
2025-06-09 11:10:31 -07:00
parent 631644075f
commit 77d33803e2
10 changed files with 75 additions and 18 deletions
@@ -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),
value: value,
loc: value.loc,
lvalue: {...place},
value: value,
effects: null,
loc: value.loc,
});
return place;
}
@@ -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<AliasingEffect> | null;
};
export function todoPopulateAliasingEffects(): Array<AliasingEffect> | null {
return null;
}
export type TInstruction<T extends InstructionValue> = {
id: InstructionId;
lvalue: Place;
value: T;
effects: Array<AliasingEffect> | null;
loc: SourceLocation;
};
@@ -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);
@@ -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,
},
];
@@ -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<Instruction> = [];
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;
}
@@ -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,
});
}
@@ -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 = {
@@ -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<string>): Instruction {
loc: GeneratedSource,
},
lvalue: createTemporaryPlace(env, GeneratedSource),
effects: todoPopulateAliasingEffects(),
loc: GeneratedSource,
};
return fnInstr;
@@ -294,6 +299,7 @@ function emitArrayInstr(elements: Array<Place>, env: Environment): Instruction {
id: makeInstructionId(0),
value: array,
lvalue: arrayLvalue,
effects: todoPopulateAliasingEffects(),
loc: GeneratedSource,
};
return arrayInstr;
@@ -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;
}
@@ -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(),
};
}