From 3682b797133657a0b75dde5dfb9ab67d2344c285 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Thu, 1 Aug 2024 09:06:45 -0700 Subject: [PATCH] [compiler] Add Identifier.declarationId ghstack-source-id: 54973a034bf9ca2e778326a5b0bf367113a63736 Pull Request resolved: https://github.com/facebook/react/pull/30569 --- .../src/HIR/HIR.ts | 31 ++++++++++++-- .../src/HIR/HIRBuilder.ts | 7 +++- ...neImmediatelyInvokedFunctionExpressions.ts | 42 ++++--------------- .../src/SSA/EnterSSA.ts | 1 + 4 files changed, 42 insertions(+), 39 deletions(-) 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 b94bffa040f7f..3dcc181a302f0 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -1174,11 +1174,19 @@ export type NonLocalBinding = // Represents a user-defined variable (has a name) or a temporary variable (no name). export type Identifier = { - /* - * unique value to distinguish a variable, since name is not guaranteed to - * exist or be unique + /** + * After EnterSSA, `id` uniquely identifies an SSA instance of a variable. + * Before EnterSSA, `id` matches `declarationId`. */ id: IdentifierId; + + /** + * Uniquely identifies a given variable in the original program. If a value is + * reassigned in the original program each reassigned value will have a distinct + * `id` (after EnterSSA), but they will still have the same `declarationId`. + */ + declarationId: DeclarationId; + // null for temporaries. name is primarily used for debugging. name: IdentifierName | null; // The range for which this variable is mutable @@ -1494,6 +1502,23 @@ export function makeIdentifierId(id: number): IdentifierId { return id as IdentifierId; } +/* + * Simulated opaque type for IdentifierId to prevent using normal numbers as ids + * accidentally. + */ +const opageDeclarationId = Symbol(); +export type DeclarationId = number & {[opageDeclarationId]: 'DeclarationId'}; + +export function makeDeclarationId(id: number): DeclarationId { + CompilerError.invariant(id >= 0 && Number.isInteger(id), { + reason: 'Expected declaration id to be a non-negative integer', + description: null, + loc: null, + suggestions: null, + }); + return id as DeclarationId; +} + /* * Simulated opaque type for InstructionId to prevent using normal numbers as ids * accidentally. diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts index d3a25d2fa3cc7..09ac39e3b3e34 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts @@ -25,6 +25,7 @@ import { Terminal, VariableBinding, makeBlockId, + makeDeclarationId, makeIdentifierName, makeInstructionId, makeType, @@ -184,6 +185,7 @@ export default class HIRBuilder { const id = this.nextIdentifierId; return { id, + declarationId: makeDeclarationId(id), name: null, mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)}, scope: null, @@ -326,6 +328,7 @@ export default class HIRBuilder { const id = this.nextIdentifierId; const identifier: Identifier = { id, + declarationId: makeDeclarationId(id), name: makeIdentifierName(name), mutableRange: { start: makeInstructionId(0), @@ -895,10 +898,12 @@ export function createTemporaryPlace( env: Environment, loc: SourceLocation, ): Place { + const id = env.nextIdentifierId; return { kind: 'Identifier', identifier: { - id: env.nextIdentifierId, + id, + declarationId: makeDeclarationId(id), mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)}, name: null, scope: null, 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 a5f81a433d4b6..fe5160c533243 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InlineImmediatelyInvokedFunctionExpressions.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InlineImmediatelyInvokedFunctionExpressions.ts @@ -23,7 +23,11 @@ import { promoteTemporary, reversePostorderBlocks, } from '../HIR'; -import {markInstructionIds, markPredecessors} from '../HIR/HIRBuilder'; +import { + createTemporaryPlace, + markInstructionIds, + markPredecessors, +} from '../HIR/HIRBuilder'; import {eachInstructionValueOperand} from '../HIR/visitors'; import {retainWhere} from '../Utils/utils'; @@ -225,23 +229,7 @@ function rewriteBlock( block.instructions.push({ id: makeInstructionId(0), loc: terminal.loc, - lvalue: { - effect: Effect.Unknown, - identifier: { - id: env.nextIdentifierId, - mutableRange: { - start: makeInstructionId(0), - end: makeInstructionId(0), - }, - name: null, - scope: null, - type: makeType(), - loc: terminal.loc, - }, - kind: 'Identifier', - reactive: false, - loc: terminal.loc, - }, + lvalue: createTemporaryPlace(env, terminal.loc), value: { kind: 'StoreLocal', lvalue: {kind: InstructionKind.Reassign, place: {...returnValue}}, @@ -267,23 +255,7 @@ function declareTemporary( block.instructions.push({ id: makeInstructionId(0), loc: GeneratedSource, - lvalue: { - effect: Effect.Unknown, - identifier: { - id: env.nextIdentifierId, - mutableRange: { - start: makeInstructionId(0), - end: makeInstructionId(0), - }, - name: null, - scope: null, - type: makeType(), - loc: result.loc, - }, - kind: 'Identifier', - reactive: false, - loc: GeneratedSource, - }, + lvalue: createTemporaryPlace(env, result.loc), value: { kind: 'DeclareLocal', lvalue: { 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 7c1073622ed17..7d665514f4f6e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/SSA/EnterSSA.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/SSA/EnterSSA.ts @@ -79,6 +79,7 @@ class SSABuilder { makeId(oldId: Identifier): Identifier { return { id: this.nextSsaId, + declarationId: oldId.declarationId, name: oldId.name, mutableRange: { start: makeInstructionId(0),