Repository: facebook/react
Pull request: [compiler] Stay in SSA form through entire pipeline

Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at bottom):
* __->__ #30573
* #30569

This PR updates to use SSA form through the entire compilation pipeline. This means that in both HIR form and ReactiveFunction form, `Identifier` instances map 1:1 to `IdentifierId` values. If two identifiers have the same IdentifierId, they are the same instance. What this means is that all our passes can use this more precise information to determine if two particular identifiers are not just the same variable, but the same SSA "version" of that variable.

However, some parts of our analysis really care about program variables as opposed to SSA versions, and were relying on LeaveSSA to reset identifiers such that all Identifier instances for a particular program variable would have the same IdentifierId (though not necessarily the same Identifier instance). With LeaveSSA removed, those analysis passes can now use DeclarationId instead to uniquely identify a program variable.

Note that this PR surfaces some opportunties to improve edge-cases around reassigned values being declared/reassigned/depended-upon across multiple scopes. Several passes could/should use IdentifierId to more precisely identify exactly which values are accessed - for example, a scope that reassigns `x` but doesn't use `x` prior to reassignment doesn't have to take a dependency on `x`. But today we take a dependnecy.

My approach for these cases was to add a "TODO LeaveSSA" comment with notes and the name of the fixture demonstrating the difference, but to intentionally preserve the existing behavior (generally, switching to use DeclarationId when IdentifierId would have been more precise).

Beyond updating passes to use DeclarationId instead of Identifier/IdentifierId, the other change here is to extract out the remaining necessary bits of LeaveSSA into a new pass that rewrites InstructionKind (const/let/reassign/etc) based on whether a value is actually const or has reassignments and should be let.

Changed files:
filename: compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
patch: @@ -1213,7 +1213,7 @@ export type ValidIdentifierName = string & {
   [opaqueValidIdentifierName]: 'ValidIdentifierName';
 };
 
-export function makeTemporary(
+export function makeTemporaryIdentifier(
   id: IdentifierId,
   loc: SourceLocation,
 ): Identifier {

filename: compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts
patch: @@ -28,7 +28,7 @@ import {
   makeDeclarationId,
   makeIdentifierName,
   makeInstructionId,
-  makeTemporary,
+  makeTemporaryIdentifier,
   makeType,
 } from './HIR';
 import {printInstruction} from './PrintHIR';
@@ -184,7 +184,7 @@ export default class HIRBuilder {
 
   makeTemporary(loc: SourceLocation): Identifier {
     const id = this.nextIdentifierId;
-    return makeTemporary(id, loc);
+    return makeTemporaryIdentifier(id, loc);
   }
 
   #resolveBabelBinding(
@@ -891,18 +891,9 @@ export function createTemporaryPlace(
   env: Environment,
   loc: SourceLocation,
 ): Place {
-  const id = env.nextIdentifierId;
   return {
     kind: 'Identifier',
-    identifier: {
-      id,
-      declarationId: makeDeclarationId(id),
-      mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
-      name: null,
-      scope: null,
-      type: makeType(),
-      loc,
-    },
+    identifier: makeTemporaryIdentifier(env.nextIdentifierId, loc),
     reactive: false,
     effect: Effect.Unknown,
     loc: GeneratedSource,

filename: fixtures/flight/package.json
patch: @@ -4,7 +4,7 @@
   "version": "0.1.0",
   "private": true,
   "devEngines": {
-    "node": "20.x || 21.x"
+    "node": "20.x || 22.x"
   },
   "dependencies": {
     "@babel/core": "^7.16.0",

filename: package.json
patch: @@ -103,7 +103,7 @@
     "yargs": "^15.3.1"
   },
   "devEngines": {
-    "node": "16.x || 18.x || 20.x || 21.x"
+    "node": "16.x || 18.x || 20.x || 22.x"
   },
   "jest": {
     "testRegex": "/scripts/jest/dont-run-jest-directly\\.js$"