mirror of
https://github.com/facebook/react.git
synced 2026-02-22 03:42:05 +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
22 KiB
22 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 ──▶ 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