mirror of
https://github.com/facebook/react.git
synced 2026-02-22 11:51:55 +00:00
Autogenerated summaries of each of the compiler passes which allow agents to get the key ideas of a compiler pass, including key input/output invariants, without having to reprocess the file each time. In the subsequent diff this seemed to help. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35595). * #35607 * #35298 * #35596 * #35573 * __->__ #35595 * #35539
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 ──▶ instructionReordering │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 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 |
|---|---|---|---|
| 32 | transformFire | Transform/TransformFire.ts |
Transform fire() calls in effects |
| 33 | lowerContextAccess | Optimization/LowerContextAccess.ts |
Optimize context access with selectors |
| 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 |
| 52 | validateMemoizedEffectDependencies | Validation/ValidateMemoizedEffectDependencies.ts |
Effect scope memoization |
| 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 scopeparams: Function parametersreturns: The function's return place
-
BasicBlock: A sequence of instructions with a terminal
instructions: Array of Instructionsterminal: Control flow (return, branch, etc.)phis: Phi nodes for SSA
-
Instruction: A single operation
lvalue: The place being assigned tovalue: The instruction kind (CallExpression, FunctionExpression, etc.)effects: Array of AliasingEffects
-
Place: A reference to a value
identifier.id: Unique IdentifierIdeffect: 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 |
|---|---|
enableFire |
transformFire |
lowerContextAccess |
lowerContextAccess |
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
# Update expected outputs
yarn snap -u
Further Reading
- MUTABILITY_ALIASING_MODEL.md: Detailed aliasing model docs
- Pipeline.ts: Pass ordering and orchestration
- HIR.ts: Core data structure definitions