Skip to content

[compiler][rewrite] Represent scope dependencies with value blocks#76

Open
everettbu wants to merge 2 commits into
mainfrom
pr32099
Open

[compiler][rewrite] Represent scope dependencies with value blocks#76
everettbu wants to merge 2 commits into
mainfrom
pr32099

Conversation

@everettbu

@everettbu everettbu commented Dec 12, 2025

Copy link
Copy Markdown

Mirror of facebook/react#32099
Original author: mofeiZ


(needs cleanup)

  • Scopes no longer store a flat list of their dependencies. Instead:
    • Scope terminals are effectively a goto for scope dependency instructions (represented as value blocks that terminate with a goto scopeBlock for HIR and a series of ReactiveInstructions for ReactiveIR)
    • Scopes themselves store dependencies: Array<Place>, which refer to temporaries written to by scope dependency instructions

Next steps:

  • new pass to dedupe scope dependency instructions after all dependency and scope pruning passes, effectively 'hoisting' dependencies out
  • more complex dependencies (unary ops like Boolean or Not, binary ops like !== or logical operators)

Stack created with Sapling. Best reviewed with ReviewStack.

  • -> #32099
  • #32286

mofeiZ added 2 commits April 29, 2025 18:38
(needs cleanup)

- Scopes no longer store a flat list of their dependencies. Instead:
  - Scope terminals are effectively a `goto` for scope dependency instructions (represented as value blocks that terminate with a `goto scopeBlock` for HIR and a series of ReactiveInstructions for ReactiveIR)
  - Scopes themselves store `dependencies: Array<Place>`, which refer to temporaries written to by scope dependency instructions

Next steps:
- new pass to dedupe scope dependency instructions after all dependency and scope pruning passes, effectively 'hoisting' dependencies out
- more complex dependencies (unary ops like `Boolean` or `Not`, binary ops like `!==` or logical operators)
@everettbu everettbu added CLA Signed React Core Team Opened by a member of the React Core Team labels Dec 12, 2025
@greptile-apps

greptile-apps Bot commented Dec 12, 2025

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

This PR fundamentally restructures how the React Compiler represents scope dependencies, moving from a flat list stored directly on scopes to a more sophisticated representation using value blocks and instruction sequences.

Key Changes

  • Dependency Representation: Scope dependencies are now represented as value blocks (sequences of LoadLocal and PropertyLoad instructions) instead of a flat Set<ReactiveScopeDependency>. The ReactiveScope.dependencies field changed from a Set to an Array<Place> that references temporaries written by dependency instructions.
  • New CFG Structure: Scope terminals now include a dependencies BlockId that points to a value block containing dependency instructions, which then jumps to the actual scope body block.
  • Reactive Tracking: Added reactive boolean field to ReactiveScopeDependency to track whether base identifiers are reactive.
  • HIRBuilder Refactoring: Moved parentFunction from HIRBuilder to Environment and refactored constructor to use options object for better extensibility.
  • Codegen Changes: Dependency codegen now processes dependencyInstructions array and uses @babel/generator to create comparison keys, removing manual dependency-to-expression conversion.

Implementation Quality

  • Added comprehensive sanity checks in BuildReactiveFunction.ts comparing HIR and ReactiveFunction dependencies
  • Proper range fixing after dependency injection (instruction IDs, scope ranges)
  • DCE (dead code elimination) for unused dependency instructions
  • Consistent reactive field propagation across all dependency creation sites

The changes enable future work on hoisting and deduplicating scope dependencies, and support more complex dependency patterns (unary/binary operations).

Confidence Score: 4/5

  • This PR is safe to merge with careful testing, as it's a well-structured architectural refactoring with comprehensive validation
  • Score reflects thorough implementation with sanity checks and validation, but the significant architectural changes across 31 files warrant careful integration testing. The refactoring is internally consistent with proper Set-to-Array conversions throughout, and includes validation that HIR and ReactiveFunction dependencies match.
  • Pay close attention to ScopeDependencyUtils.ts (new complex logic for writing dependencies) and PropagateScopeDependenciesHIR.ts (critical refactoring of dependency propagation)

Important Files Changed

File Analysis

Filename Score Overview
compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts 5/5 Added dependencies BlockId to scope terminals and changed ReactiveScope.dependencies from Set to Array of Places. Added dependencyInstructions to scope blocks and reactive flag to ReactiveScopeDependency.
compiler/packages/babel-plugin-react-compiler/src/HIR/ScopeDependencyUtils.ts 4/5 New utility file for reading/writing scope dependencies as value blocks. Implements writeNonOptionalDependency, writeOptional for complex dependency chains, and readScopeDependencies for validation.
compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts 5/5 Refactored constructor to use options object instead of positional parameters. Moved parentFunction from HIRBuilder to Environment. Made terminate() return BlockId.
compiler/packages/babel-plugin-react-compiler/src/HIR/BuildReactiveScopeTerminalsHIR.ts 5/5 Added dependencyId to StartScope rewrites. Creates empty dependency block (bb1) between scope start and scope body (bb2), filled later by PropagateScopeDependenciesHIR.
compiler/packages/babel-plugin-react-compiler/src/HIR/PropagateScopeDependenciesHIR.ts 4/5 Major refactoring to write dependencies as value blocks via writeScopeDependencies(). Added scope/identifier range fixing after dependency injection. Includes sanity checks comparing HIR and RHIR dependencies.
compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/BuildReactiveFunction.ts 4/5 Traverses dependency blocks into dependencyInstructions array on scope blocks. Added sanity check validating HIR and ReactiveFunction dependencies match. Changed Context to store HIRFunction instead of just HIR.
compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts 4/5 Dependency codegen now uses dependencyInstructions instead of directly generating from ReactiveScopeDependency. Uses @babel/generator to create dependency comparison keys. Removed codegenDependency and compareScopeDependency functions.
compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PromoteUsedTemporaries.ts 4/5 Added scopeDependenciesDCE() call and traversal of dependencyInstructions. New scopeDepContext tracks declarations/dependencies to avoid promoting lvalues defined within scope dependency blocks.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

31 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants