From 7b7fac073d1473df839a1caf8d0444c32bf4de49 Mon Sep 17 00:00:00 2001 From: Mike Vitousek Date: Thu, 10 Oct 2024 12:41:03 -0700 Subject: [PATCH] [compiler] Represent phis with places rather than identifiers Summary: The fact that phis are identifiers rather than places is unfortunate in a few cases. In some later analyses, we might wish to know whether a phi is reactive, but we don't have an easy way to do that currently. Most of the changes here is just replacing phi.id with phi.place.identifier and such. Interesting bits are EnterSSA (several functions now take places rather than identifiers, and InferReactivePlaces now needs to mark places as reactive explicitly. ghstack-source-id: 5f4fb396cd86b421008c37832a5735ac40f8806e Pull Request resolved: https://github.com/facebook/react/pull/31171 --- .../src/HIR/AssertConsistentIdentifiers.ts | 4 +- .../src/HIR/AssertValidMutableRanges.ts | 4 +- .../src/HIR/HIR.ts | 4 +- .../src/HIR/MergeConsecutiveBlocks.ts | 10 +-- .../src/HIR/PrintHIR.ts | 10 +-- .../src/HIR/PropagateScopeDependenciesHIR.ts | 2 +- .../src/Inference/InferAliasForPhis.ts | 4 +- .../src/Inference/InferMutableLifetimes.ts | 16 +++-- .../src/Inference/InferReactivePlaces.ts | 8 +-- .../src/Inference/InferReferenceEffects.ts | 4 +- .../src/Optimization/ConstantPropagation.ts | 4 +- .../src/Optimization/DeadCodeElimination.ts | 6 +- .../src/Optimization/PruneMaybeThrows.ts | 4 +- .../InferReactiveScopeVariables.ts | 15 +++-- .../src/SSA/EliminateRedundantPhi.ts | 15 ++--- .../src/SSA/EnterSSA.ts | 61 ++++++++++--------- .../src/TypeInference/InferTypes.ts | 6 +- .../src/TypeInference/PropagatePhiTypes.ts | 13 ++-- .../src/Validation/ValidateHooksUsage.ts | 7 ++- .../Validation/ValidateNoRefAccesInRender.ts | 5 +- 20 files changed, 103 insertions(+), 99 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertConsistentIdentifiers.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertConsistentIdentifiers.ts index dbe662c609a32..2588ee1f9a8da 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertConsistentIdentifiers.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertConsistentIdentifiers.ts @@ -29,9 +29,9 @@ export function assertConsistentIdentifiers(fn: HIRFunction): void { const assignments: Set = new Set(); for (const [, block] of fn.body.blocks) { for (const phi of block.phis) { - validate(identifiers, phi.id); + validate(identifiers, phi.place.identifier); for (const [, operand] of phi.operands) { - validate(identifiers, operand); + validate(identifiers, operand.identifier); } } for (const instr of block.instructions) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertValidMutableRanges.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertValidMutableRanges.ts index 95b11db40c90a..d44f6108eaa57 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertValidMutableRanges.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/AssertValidMutableRanges.ts @@ -20,9 +20,9 @@ import { export function assertValidMutableRanges(fn: HIRFunction): void { for (const [, block] of fn.body.blocks) { for (const phi of block.phis) { - visitIdentifier(phi.id); + visitIdentifier(phi.place.identifier); for (const [, operand] of phi.operands) { - visitIdentifier(operand); + visitIdentifier(operand.identifier); } } for (const instr of block.instructions) { 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 873082bdbeaa0..e771b386b3942 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -761,8 +761,8 @@ function _staticInvariantInstructionValueHasLocation( export type Phi = { kind: 'Phi'; - id: Identifier; - operands: Map; + place: Place; + operands: Map; }; /** 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 98721f636f8f9..ea132b772aa44 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts @@ -84,20 +84,14 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void { id: predecessor.terminal.id, lvalue: { kind: 'Identifier', - identifier: phi.id, + identifier: phi.place.identifier, effect: Effect.ConditionallyMutate, reactive: false, loc: GeneratedSource, }, value: { kind: 'LoadLocal', - place: { - kind: 'Identifier', - identifier: operand, - effect: Effect.Read, - reactive: false, - loc: GeneratedSource, - }, + place: {...operand}, loc: GeneratedSource, }, loc: GeneratedSource, diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts index c88d3bf773898..526ab7c7e52bb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts @@ -163,13 +163,13 @@ export function printInstruction(instr: ReactiveInstruction): string { export function printPhi(phi: Phi): string { const items = []; - items.push(printIdentifier(phi.id)); - items.push(printMutableRange(phi.id)); - items.push(printType(phi.id.type)); + items.push(printPlace(phi.place)); + items.push(printMutableRange(phi.place.identifier)); + items.push(printType(phi.place.identifier.type)); items.push(': phi('); const phis = []; - for (const [blockId, id] of phi.operands) { - phis.push(`bb${blockId}: ${printIdentifier(id)}`); + for (const [blockId, place] of phi.operands) { + phis.push(`bb${blockId}: ${printPlace(place)}`); } items.push(phis.join(', ')); diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/PropagateScopeDependenciesHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/PropagateScopeDependenciesHIR.ts index ab2cf4cf56157..855ca9121d26b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/PropagateScopeDependenciesHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/PropagateScopeDependenciesHIR.ts @@ -607,7 +607,7 @@ function collectDependencies( // Record referenced optional chains in phis for (const phi of block.phis) { for (const operand of phi.operands) { - const maybeOptionalChain = temporaries.get(operand[1].id); + const maybeOptionalChain = temporaries.get(operand[1].identifier.id); if (maybeOptionalChain) { context.visitDependency(maybeOptionalChain); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferAliasForPhis.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferAliasForPhis.ts index 126990196ccbd..e81e3ebdae7a2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferAliasForPhis.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferAliasForPhis.ts @@ -15,11 +15,11 @@ export function inferAliasForPhis( for (const [_, block] of func.body.blocks) { for (const phi of block.phis) { const isPhiMutatedAfterCreation: boolean = - phi.id.mutableRange.end > + phi.place.identifier.mutableRange.end > (block.instructions.at(0)?.id ?? block.terminal.id); if (isPhiMutatedAfterCreation) { for (const [, operand] of phi.operands) { - aliases.union([phi.id, operand]); + aliases.union([phi.place.identifier, operand.identifier]); } } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutableLifetimes.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutableLifetimes.ts index 459baf4e287cc..508a970d931b0 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutableLifetimes.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutableLifetimes.ts @@ -116,19 +116,23 @@ export function inferMutableLifetimes( for (const [_, block] of func.body.blocks) { for (const phi of block.phis) { const isPhiMutatedAfterCreation: boolean = - phi.id.mutableRange.end > + phi.place.identifier.mutableRange.end > (block.instructions.at(0)?.id ?? block.terminal.id); if ( inferMutableRangeForStores && isPhiMutatedAfterCreation && - phi.id.mutableRange.start === 0 + phi.place.identifier.mutableRange.start === 0 ) { for (const [, operand] of phi.operands) { - if (phi.id.mutableRange.start === 0) { - phi.id.mutableRange.start = operand.mutableRange.start; + if (phi.place.identifier.mutableRange.start === 0) { + phi.place.identifier.mutableRange.start = + operand.identifier.mutableRange.start; } else { - phi.id.mutableRange.start = makeInstructionId( - Math.min(phi.id.mutableRange.start, operand.mutableRange.start), + phi.place.identifier.mutableRange.start = makeInstructionId( + Math.min( + phi.place.identifier.mutableRange.start, + operand.identifier.mutableRange.start, + ), ); } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts index 20e1a97b08790..98b1ec75e1337 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts @@ -162,23 +162,23 @@ export function inferReactivePlaces(fn: HIRFunction): void { let hasReactiveControl = isReactiveControlledBlock(block.id); for (const phi of block.phis) { - if (reactiveIdentifiers.isReactiveIdentifier(phi.id)) { + if (reactiveIdentifiers.isReactive(phi.place)) { // Already marked reactive on a previous pass continue; } let isPhiReactive = false; for (const [, operand] of phi.operands) { - if (reactiveIdentifiers.isReactiveIdentifier(operand)) { + if (reactiveIdentifiers.isReactive(operand)) { isPhiReactive = true; break; } } if (isPhiReactive) { - reactiveIdentifiers.markReactiveIdentifier(phi.id); + reactiveIdentifiers.markReactive(phi.place); } else { for (const [pred] of phi.operands) { if (isReactiveControlledBlock(pred)) { - reactiveIdentifiers.markReactiveIdentifier(phi.id); + reactiveIdentifiers.markReactive(phi.place); break; } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts index 5231b7aef631c..8cf30a9666e25 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts @@ -635,7 +635,7 @@ class InferenceState { inferPhi(phi: Phi): void { const values: Set = new Set(); for (const [_, operand] of phi.operands) { - const operandValues = this.#variables.get(operand.id); + const operandValues = this.#variables.get(operand.identifier.id); // This is a backedge that will be handled later by State.merge if (operandValues === undefined) continue; for (const v of operandValues) { @@ -644,7 +644,7 @@ class InferenceState { } if (values.size > 0) { - this.#variables.set(phi.id.id, values); + this.#variables.set(phi.place.identifier.id, values); } } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts index 112cca7491483..24498012a08eb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts @@ -117,7 +117,7 @@ function applyConstantPropagation( for (const phi of block.phis) { let value = evaluatePhi(phi, constants); if (value !== null) { - constants.set(phi.id.id, value); + constants.set(phi.place.identifier.id, value); } } @@ -167,7 +167,7 @@ function applyConstantPropagation( function evaluatePhi(phi: Phi, constants: Constants): Constant | null { let value: Constant | null = null; for (const [, operand] of phi.operands) { - const operandValue = constants.get(operand.id) ?? null; + const operandValue = constants.get(operand.identifier.id) ?? null; // did not find a constant, can't constant propogate if (operandValue === null) { return null; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/DeadCodeElimination.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/DeadCodeElimination.ts index 3cdba101a82ac..885ec2b3ab2eb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/DeadCodeElimination.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/DeadCodeElimination.ts @@ -42,7 +42,7 @@ export function deadCodeElimination(fn: HIRFunction): void { */ for (const [, block] of fn.body.blocks) { for (const phi of block.phis) { - if (!state.isIdOrNameUsed(phi.id)) { + if (!state.isIdOrNameUsed(phi.place.identifier)) { block.phis.delete(phi); } } @@ -159,9 +159,9 @@ function findReferencedIdentifiers(fn: HIRFunction): State { } } for (const phi of block.phis) { - if (state.isIdOrNameUsed(phi.id)) { + if (state.isIdOrNameUsed(phi.place.identifier)) { for (const [_pred, operand] of phi.operands) { - state.reference(operand); + state.reference(operand.identifier); } } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/PruneMaybeThrows.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/PruneMaybeThrows.ts index 3843cdf23fc2d..9175fbdd1af1b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/PruneMaybeThrows.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/PruneMaybeThrows.ts @@ -23,7 +23,7 @@ import { removeUnnecessaryTryCatch, removeUnreachableForUpdates, } from '../HIR/HIRBuilder'; -import {printIdentifier} from '../HIR/PrintHIR'; +import {printPlace} from '../HIR/PrintHIR'; /* * This pass prunes `maybe-throw` terminals for blocks that can provably *never* throw. @@ -55,7 +55,7 @@ export function pruneMaybeThrows(fn: HIRFunction): void { loc: GeneratedSource, description: `Could not find mapping for predecessor bb${predecessor} in block bb${ block.id - } for phi ${printIdentifier(phi.id)}`, + } for phi ${printPlace(phi.place)}`, suggestions: null, }); phi.operands.delete(predecessor); diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/InferReactiveScopeVariables.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/InferReactiveScopeVariables.ts index 0d0b37ce58afe..098139b150d5a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/InferReactiveScopeVariables.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/InferReactiveScopeVariables.ts @@ -281,22 +281,25 @@ export function findDisjointMutableValues( */ for (const phi of block.phis) { if ( - phi.id.mutableRange.start + 1 !== phi.id.mutableRange.end && - phi.id.mutableRange.end > + phi.place.identifier.mutableRange.start + 1 !== + phi.place.identifier.mutableRange.end && + phi.place.identifier.mutableRange.end > (block.instructions.at(0)?.id ?? block.terminal.id) ) { - const operands = [phi.id]; - const declaration = declarations.get(phi.id.declarationId); + const operands = [phi.place.identifier]; + const declaration = declarations.get( + phi.place.identifier.declarationId, + ); if (declaration !== undefined) { operands.push(declaration); } for (const [_, phiId] of phi.operands) { - operands.push(phiId); + operands.push(phiId.identifier); } scopeIdentifiers.union(operands); } else if (fn.env.config.enableForest) { for (const [, phiId] of phi.operands) { - scopeIdentifiers.union([phi.id, phiId]); + scopeIdentifiers.union([phi.place.identifier, phiId.identifier]); } } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/SSA/EliminateRedundantPhi.ts b/compiler/packages/babel-plugin-react-compiler/src/SSA/EliminateRedundantPhi.ts index b5b0afb41236a..bae038f9bd9df 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/SSA/EliminateRedundantPhi.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/SSA/EliminateRedundantPhi.ts @@ -68,18 +68,13 @@ export function eliminateRedundantPhi( // Find any redundant phis phis: for (const phi of block.phis) { // Remap phis in case operands are from eliminated phis - phi.operands = new Map( - Array.from(phi.operands).map(([block, id]) => [ - block, - rewrites.get(id) ?? id, - ]), - ); + phi.operands.forEach((place, _) => rewritePlace(place, rewrites)); // Find if the phi can be eliminated let same: Identifier | null = null; for (const [_, operand] of phi.operands) { if ( - (same !== null && operand.id === same.id) || - operand.id === phi.id.id + (same !== null && operand.identifier.id === same.id) || + operand.identifier.id === phi.place.identifier.id ) { /* * This operand is the same as the phi or is the same as the @@ -94,7 +89,7 @@ export function eliminateRedundantPhi( continue phis; } else { // First non-phi operand - same = operand; + same = operand.identifier; } } CompilerError.invariant(same !== null, { @@ -103,7 +98,7 @@ export function eliminateRedundantPhi( loc: null, suggestions: null, }); - rewrites.set(phi.id, same); + rewrites.set(phi.place.identifier, same); block.phis.delete(phi); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/SSA/EnterSSA.ts b/compiler/packages/babel-plugin-react-compiler/src/SSA/EnterSSA.ts index 73942769c22be..caba0d3c36992 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/SSA/EnterSSA.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/SSA/EnterSSA.ts @@ -18,7 +18,7 @@ import { Phi, Place, } from '../HIR/HIR'; -import {printIdentifier} from '../HIR/PrintHIR'; +import {printIdentifier, printPlace} from '../HIR/PrintHIR'; import { eachTerminalSuccessor, mapInstructionLValues, @@ -27,8 +27,8 @@ import { } from '../HIR/visitors'; type IncompletePhi = { - oldId: Identifier; - newId: Identifier; + oldPlace: Place; + newPlace: Place; }; type State = { @@ -122,33 +122,33 @@ class SSABuilder { } getPlace(oldPlace: Place): Place { - const newId = this.getIdAt(oldPlace.identifier, this.#current!.id); + const newId = this.getIdAt(oldPlace, this.#current!.id); return { ...oldPlace, identifier: newId, }; } - getIdAt(oldId: Identifier, blockId: BlockId): Identifier { + getIdAt(oldPlace: Place, blockId: BlockId): Identifier { // check if Place is defined locally const block = this.#blocks.get(blockId)!; const state = this.#states.get(block)!; - if (state.defs.has(oldId)) { - return state.defs.get(oldId)!; + if (state.defs.has(oldPlace.identifier)) { + return state.defs.get(oldPlace.identifier)!; } if (block.preds.size == 0) { /* * We're at the entry block and haven't found our defintion yet. * console.log( - * `Unable to find "${printIdentifier( - * oldId + * `Unable to find "${printPlace( + * oldPlace * )}" in bb${blockId}, assuming it's a global` * ); */ - this.#unknown.add(oldId); - return oldId; + this.#unknown.add(oldPlace.identifier); + return oldPlace.identifier; } if (this.unsealedPreds.get(block)! > 0) { @@ -156,52 +156,55 @@ class SSABuilder { * We haven't visited all our predecessors, let's place an incomplete phi * for now. */ - const newId = this.makeId(oldId); - state.incompletePhis.push({oldId, newId}); - state.defs.set(oldId, newId); + const newId = this.makeId(oldPlace.identifier); + state.incompletePhis.push({ + oldPlace, + newPlace: {...oldPlace, identifier: newId}, + }); + state.defs.set(oldPlace.identifier, newId); return newId; } // Only one predecessor, let's check there if (block.preds.size == 1) { const [pred] = block.preds; - const newId = this.getIdAt(oldId, pred); - state.defs.set(oldId, newId); + const newId = this.getIdAt(oldPlace, pred); + state.defs.set(oldPlace.identifier, newId); return newId; } // There are multiple predecessors, we may need a phi. - const newId = this.makeId(oldId); + const newId = this.makeId(oldPlace.identifier); /* * Adding a phi may loop back to our block if there is a loop in the CFG. We * update our defs before adding the phi to terminate the recursion rather than * looping infinitely. */ - state.defs.set(oldId, newId); - return this.addPhi(block, oldId, newId); + state.defs.set(oldPlace.identifier, newId); + return this.addPhi(block, oldPlace, {...oldPlace, identifier: newId}); } - addPhi(block: BasicBlock, oldId: Identifier, newId: Identifier): Identifier { - const predDefs: Map = new Map(); + addPhi(block: BasicBlock, oldPlace: Place, newPlace: Place): Identifier { + const predDefs: Map = new Map(); for (const predBlockId of block.preds) { - const predId = this.getIdAt(oldId, predBlockId); - predDefs.set(predBlockId, predId); + const predId = this.getIdAt(oldPlace, predBlockId); + predDefs.set(predBlockId, {...oldPlace, identifier: predId}); } const phi: Phi = { kind: 'Phi', - id: newId, + place: newPlace, operands: predDefs, }; block.phis.add(phi); - return newId; + return newPlace.identifier; } fixIncompletePhis(block: BasicBlock): void { const state = this.#states.get(block)!; for (const phi of state.incompletePhis) { - this.addPhi(block, phi.oldId, phi.newId); + this.addPhi(block, phi.oldPlace, phi.newPlace); } } @@ -223,9 +226,9 @@ class SSABuilder { for (const incompletePhi of state.incompletePhis) { text.push( - ` iphi \$${printIdentifier( - incompletePhi.newId, - )} = \$${printIdentifier(incompletePhi.oldId)}`, + ` iphi \$${printPlace( + incompletePhi.newPlace, + )} = \$${printPlace(incompletePhi.oldPlace)}`, ); } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts b/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts index 25bc87838ae83..0270723c3e863 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts @@ -69,7 +69,7 @@ export function inferTypes(func: HIRFunction): void { function apply(func: HIRFunction, unifier: Unifier): void { for (const [_, block] of func.body.blocks) { for (const phi of block.phis) { - phi.id.type = unifier.get(phi.id.type); + phi.place.identifier.type = unifier.get(phi.place.identifier.type); } for (const instr of block.instructions) { for (const operand of eachInstructionLValue(instr)) { @@ -127,9 +127,9 @@ function* generate( const returnTypes: Array = []; for (const [_, block] of func.body.blocks) { for (const phi of block.phis) { - yield equation(phi.id.type, { + yield equation(phi.place.identifier.type, { kind: 'Phi', - operands: [...phi.operands.values()].map(id => id.type), + operands: [...phi.operands.values()].map(id => id.identifier.type), }); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/TypeInference/PropagatePhiTypes.ts b/compiler/packages/babel-plugin-react-compiler/src/TypeInference/PropagatePhiTypes.ts index b33c8773dc0c7..0369945525bcf 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/TypeInference/PropagatePhiTypes.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/TypeInference/PropagatePhiTypes.ts @@ -62,21 +62,24 @@ export function propagatePhiTypes(fn: HIRFunction): void { * We also don't propagate scopes for named variables, to preserve compatibility * with previous LeaveSSA behavior. */ - if (phi.id.type.kind !== 'Type' || phi.id.name !== null) { + if ( + phi.place.identifier.type.kind !== 'Type' || + phi.place.identifier.name !== null + ) { continue; } let type: Type | null = null; for (const [, operand] of phi.operands) { if (type === null) { - type = operand.type; - } else if (!typeEquals(type, operand.type)) { + type = operand.identifier.type; + } else if (!typeEquals(type, operand.identifier.type)) { type = null; break; } } if (type !== null) { - phi.id.type = type; - propagated.add(phi.id.id); + phi.place.identifier.type = type; + propagated.add(phi.place.identifier.id); } } for (const instr of block.instructions) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts index 74f6346b3a37b..53640da5020bd 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts @@ -198,11 +198,12 @@ export function validateHooksUsage(fn: HIRFunction): void { for (const [, block] of fn.body.blocks) { for (const phi of block.phis) { let kind: Kind = - phi.id.name !== null && isHookName(phi.id.name.value) + phi.place.identifier.name !== null && + isHookName(phi.place.identifier.name.value) ? Kind.PotentialHook : Kind.Local; for (const [, operand] of phi.operands) { - const operandKind = valueKinds.get(operand.id); + const operandKind = valueKinds.get(operand.identifier.id); /* * NOTE: we currently skip operands whose value is unknown * (which can only occur for functions with loops), we may @@ -213,7 +214,7 @@ export function validateHooksUsage(fn: HIRFunction): void { kind = joinKinds(kind, operandKind); } } - valueKinds.set(phi.id.id, kind); + valueKinds.set(phi.place.identifier.id, kind); } for (const instr of block.instructions) { switch (instr.value.kind) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts index 5f98b0ee8e4af..7fb835e0496c6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts @@ -209,10 +209,11 @@ function validateNoRefAccessInRenderImpl( for (const [, block] of fn.body.blocks) { for (const phi of block.phis) { env.set( - phi.id.id, + phi.place.identifier.id, joinRefAccessTypes( ...Array(...phi.operands.values()).map( - operand => env.get(operand.id) ?? ({kind: 'None'} as const), + operand => + env.get(operand.identifier.id) ?? ({kind: 'None'} as const), ), ), );