Files
react/compiler/packages/babel-plugin-react-compiler/docs/passes/README.md
Joseph Savona b354bbd2d2 [compiler] Update docs with fault tolerance summary, remove planning doc (#35888)
Add concise fault tolerance documentation to CLAUDE.md and the passes
README covering error accumulation, tryRecord wrapping, and the
distinction between validation vs infrastructure passes. Remove the
detailed planning document now that the work is complete.
2026-02-23 16:18:44 -08:00

23 KiB

React Compiler Passes Documentation

This directory contains detailed documentation for each pass in the React Compiler pipeline. The compiler transforms React components and hooks to add automatic memoization.

High-Level Architecture

                    ┌─────────────────────────────────────────────────────────────┐
                    │                     COMPILATION PIPELINE                      │
                    └─────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  PHASE 1: HIR CONSTRUCTION                                                          │
│  ┌─────────┐                                                                        │
│  │  Babel  │──▶ lower ──▶ enterSSA ──▶ eliminateRedundantPhi                        │
│  │   AST   │              │                                                         │
│  └─────────┘              ▼                                                         │
│                     ┌──────────┐                                                    │
│                     │   HIR    │  (Control Flow Graph in SSA Form)                  │
│                     └──────────┘                                                    │
└─────────────────────────────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  PHASE 2: OPTIMIZATION                                                              │
│                                                                                     │
│  constantPropagation ──▶ deadCodeElimination                                         │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  PHASE 3: TYPE & EFFECT INFERENCE                                                   │
│                                                                                     │
│  inferTypes ──▶ analyseFunctions ──▶ inferMutationAliasingEffects                   │
│                                              │                                      │
│                                              ▼                                      │
│                         inferMutationAliasingRanges ──▶ inferReactivePlaces         │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  PHASE 4: REACTIVE SCOPE CONSTRUCTION                                               │
│                                                                                     │
│  inferReactiveScopeVariables ──▶ alignMethodCallScopes ──▶ alignObjectMethodScopes  │
│              │                                                                      │
│              ▼                                                                      │
│  alignReactiveScopesToBlockScopesHIR ──▶ mergeOverlappingReactiveScopesHIR          │
│              │                                                                      │
│              ▼                                                                      │
│  buildReactiveScopeTerminalsHIR ──▶ flattenReactiveLoopsHIR                         │
│              │                                                                      │
│              ▼                                                                      │
│  flattenScopesWithHooksOrUseHIR ──▶ propagateScopeDependenciesHIR                   │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  PHASE 5: HIR → REACTIVE FUNCTION                                                   │
│                                                                                     │
│                           buildReactiveFunction                                     │
│                                    │                                                │
│                                    ▼                                                │
│                         ┌───────────────────┐                                       │
│                         │ ReactiveFunction  │  (Tree Structure)                     │
│                         └───────────────────┘                                       │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  PHASE 6: REACTIVE FUNCTION OPTIMIZATION                                            │
│                                                                                     │
│  pruneUnusedLabels ──▶ pruneNonEscapingScopes ──▶ pruneNonReactiveDependencies      │
│              │                                                                      │
│              ▼                                                                      │
│  pruneUnusedScopes ──▶ mergeReactiveScopesThatInvalidateTogether                    │
│              │                                                                      │
│              ▼                                                                      │
│  pruneAlwaysInvalidatingScopes ──▶ propagateEarlyReturns ──▶ promoteUsedTemporaries │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│  PHASE 7: CODE GENERATION                                                           │
│                                                                                     │
│  renameVariables ──▶ codegenReactiveFunction                                        │
│                              │                                                      │
│                              ▼                                                      │
│                      ┌─────────────┐                                                │
│                      │  Babel AST  │  (With Memoization)                            │
│                      └─────────────┘                                                │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘

Pass Categories

HIR Construction & SSA (1-3)

# Pass File Description
1 lower HIR/BuildHIR.ts Convert Babel AST to HIR control-flow graph
2 enterSSA SSA/EnterSSA.ts Convert to Static Single Assignment form
3 eliminateRedundantPhi SSA/EliminateRedundantPhi.ts Remove unnecessary phi nodes

Optimization (4-5)

# Pass File Description
4 constantPropagation Optimization/ConstantPropagation.ts Sparse conditional constant propagation
5 deadCodeElimination Optimization/DeadCodeElimination.ts Remove unreferenced instructions

Type Inference (6)

# Pass File Description
6 inferTypes TypeInference/InferTypes.ts Constraint-based type unification

Mutation/Aliasing Inference (7-10)

# Pass File Description
7 analyseFunctions Inference/AnalyseFunctions.ts Analyze nested function effects
8 inferMutationAliasingEffects Inference/InferMutationAliasingEffects.ts Infer mutation/aliasing via abstract interpretation
9 inferMutationAliasingRanges Inference/InferMutationAliasingRanges.ts Compute mutable ranges from effects
10 inferReactivePlaces Inference/InferReactivePlaces.ts Mark reactive places (props, hooks, derived)

Reactive Scope Variables (11-12)

# Pass File Description
11 inferReactiveScopeVariables ReactiveScopes/InferReactiveScopeVariables.ts Group co-mutating variables into scopes
12 rewriteInstructionKindsBasedOnReassignment SSA/RewriteInstructionKindsBasedOnReassignment.ts Convert SSA loads to context loads for reassigned vars

Scope Alignment (13-15)

# Pass File Description
13 alignMethodCallScopes ReactiveScopes/AlignMethodCallScopes.ts Align method call scopes with receivers
14 alignObjectMethodScopes ReactiveScopes/AlignObjectMethodScopes.ts Align object method scopes
15 alignReactiveScopesToBlockScopesHIR ReactiveScopes/AlignReactiveScopesToBlockScopesHIR.ts Align to control-flow block boundaries

Scope Construction (16-18)

# Pass File Description
16 mergeOverlappingReactiveScopesHIR HIR/MergeOverlappingReactiveScopesHIR.ts Merge overlapping scopes
17 buildReactiveScopeTerminalsHIR HIR/BuildReactiveScopeTerminalsHIR.ts Insert scope terminals into CFG
18 flattenReactiveLoopsHIR ReactiveScopes/FlattenReactiveLoopsHIR.ts Prune scopes inside loops

Scope Flattening & Dependencies (19-20)

# Pass File Description
19 flattenScopesWithHooksOrUseHIR ReactiveScopes/FlattenScopesWithHooksOrUseHIR.ts Prune scopes containing hooks
20 propagateScopeDependenciesHIR HIR/PropagateScopeDependenciesHIR.ts Derive minimal scope dependencies

HIR → Reactive Conversion (21)

# Pass File Description
21 buildReactiveFunction ReactiveScopes/BuildReactiveFunction.ts Convert CFG to tree structure

Reactive Function Pruning (22-25)

# Pass File Description
22 pruneUnusedLabels ReactiveScopes/PruneUnusedLabels.ts Remove unused labels
23 pruneNonEscapingScopes ReactiveScopes/PruneNonEscapingScopes.ts Remove non-escaping scopes
24 pruneNonReactiveDependencies ReactiveScopes/PruneNonReactiveDependencies.ts Remove non-reactive dependencies
25 pruneUnusedScopes ReactiveScopes/PruneUnusedScopes.ts Remove empty scopes

Scope Optimization (26-28)

# Pass File Description
26 mergeReactiveScopesThatInvalidateTogether ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts Merge co-invalidating scopes
27 pruneAlwaysInvalidatingScopes ReactiveScopes/PruneAlwaysInvalidatingScopes.ts Prune always-invalidating scopes
28 propagateEarlyReturns ReactiveScopes/PropagateEarlyReturns.ts Handle early returns in scopes

Codegen Preparation (29-31)

# Pass File Description
29 promoteUsedTemporaries ReactiveScopes/PromoteUsedTemporaries.ts Promote temps to named vars
30 renameVariables ReactiveScopes/RenameVariables.ts Ensure unique variable names
31 codegenReactiveFunction ReactiveScopes/CodegenReactiveFunction.ts Generate final Babel AST

Transformations (32-38)

# Pass File Description
34 optimizePropsMethodCalls Optimization/OptimizePropsMethodCalls.ts Normalize props method calls
35 optimizeForSSR Optimization/OptimizeForSSR.ts SSR-specific optimizations
36 outlineJSX Optimization/OutlineJsx.ts Outline JSX to components
37 outlineFunctions Optimization/OutlineFunctions.ts Outline pure functions
38 memoizeFbtAndMacroOperandsInSameScope ReactiveScopes/MemoizeFbtAndMacroOperandsInSameScope.ts Keep FBT operands together

Validation (39-55)

# Pass File Description
39 validateContextVariableLValues Validation/ValidateContextVariableLValues.ts Variable reference consistency
40 validateUseMemo Validation/ValidateUseMemo.ts useMemo callback requirements
41 validateHooksUsage Validation/ValidateHooksUsage.ts Rules of Hooks
42 validateNoCapitalizedCalls Validation/ValidateNoCapitalizedCalls.ts Component vs function calls
43 validateLocalsNotReassignedAfterRender Validation/ValidateLocalsNotReassignedAfterRender.ts Variable mutation safety
44 validateNoSetStateInRender Validation/ValidateNoSetStateInRender.ts No setState during render
45 validateNoDerivedComputationsInEffects Validation/ValidateNoDerivedComputationsInEffects.ts Effect optimization hints
46 validateNoSetStateInEffects Validation/ValidateNoSetStateInEffects.ts Effect performance
47 validateNoJSXInTryStatement Validation/ValidateNoJSXInTryStatement.ts Error boundary usage
48 validateNoImpureValuesInRender Validation/ValidateNoImpureValuesInRender.ts Impure value isolation
49 validateNoRefAccessInRender Validation/ValidateNoRefAccessInRender.ts Ref access constraints
50 validateNoFreezingKnownMutableFunctions Validation/ValidateNoFreezingKnownMutableFunctions.ts Mutable function isolation
51 validateExhaustiveDependencies Validation/ValidateExhaustiveDependencies.ts Dependency array completeness
53 validatePreservedManualMemoization Validation/ValidatePreservedManualMemoization.ts Manual memo preservation
54 validateStaticComponents Validation/ValidateStaticComponents.ts Component identity stability
55 validateSourceLocations Validation/ValidateSourceLocations.ts Source location preservation

Key Data Structures

HIR (High-level Intermediate Representation)

The compiler converts source code to HIR for analysis. Key types:

  • HIRFunction: A function being compiled

    • body.blocks: Map of BasicBlocks (control flow graph)
    • context: Captured variables from outer scope
    • params: Function parameters
    • returns: The function's return place
  • BasicBlock: A sequence of instructions with a terminal

    • instructions: Array of Instructions
    • terminal: Control flow (return, branch, etc.)
    • phis: Phi nodes for SSA
  • Instruction: A single operation

    • lvalue: The place being assigned to
    • value: The instruction kind (CallExpression, FunctionExpression, etc.)
    • effects: Array of AliasingEffects
  • Place: A reference to a value

    • identifier.id: Unique IdentifierId
    • effect: How the place is used (read, mutate, etc.)

ReactiveFunction

After HIR is analyzed, it's converted to ReactiveFunction:

  • Tree structure instead of CFG
  • Contains ReactiveScopes that define memoization boundaries
  • Each scope has dependencies and declarations

AliasingEffects

Effects describe data flow and operations:

  • Capture/Alias: Value relationships
  • Mutate/MutateTransitive: Mutation tracking
  • Freeze: Immutability marking
  • Render: JSX usage context
  • Create/CreateFunction: Value creation

Feature Flags

Many passes are controlled by feature flags in Environment.ts:

Flag Enables Pass
enableJsxOutlining outlineJSX
enableFunctionOutlining outlineFunctions
validateNoSetStateInRender validateNoSetStateInRender
enableUseMemoCacheInterop Preserves manual memoization

Running Tests

# Run all tests
yarn snap

# Run specific fixture
yarn snap -p <fixture-name>

# Run with debug output (shows all passes)
yarn snap -p <fixture-name> -d

# Compile any file (not just fixtures) and see output
yarn snap compile <path>

# Compile any file with debug output (alternative to yarn snap -d -p when you don't have a fixture)
yarn snap compile --debug <path>

# Minimize a failing test case to its minimal reproduction
yarn snap minimize <path>

# Update expected outputs
yarn snap -u

Fault Tolerance

The pipeline is fault-tolerant: all passes run to completion, accumulating errors on Environment rather than aborting on the first error.

  • Validation passes are wrapped in env.tryRecord() in Pipeline.ts, which catches non-invariant CompilerErrors and records them. If a validation pass throws, compilation continues.
  • Infrastructure/transformation passes (enterSSA, eliminateRedundantPhi, inferMutationAliasingEffects, codegen, etc.) are NOT wrapped in tryRecord() because subsequent passes depend on their output being structurally valid. If they fail, compilation aborts.
  • lower() (BuildHIR) always produces an HIRFunction, recording errors on env instead of returning Err. Unsupported constructs (e.g., var) are lowered best-effort.
  • At the end of the pipeline, env.hasErrors() determines whether to return Ok(codegen) or Err(aggregatedErrors).

Further Reading