Skip to content

refactor(rust): simplify cross_module_optimization by removing redundant scope tracking#8672

Merged
shulaoda merged 1 commit intomainfrom
03-13-refactor_rust_simplify_cross_module_optimization_by_removing_redundant_scope_tracking
Mar 18, 2026
Merged

refactor(rust): simplify cross_module_optimization by removing redundant scope tracking#8672
shulaoda merged 1 commit intomainfrom
03-13-refactor_rust_simplify_cross_module_optimization_by_removing_redundant_scope_tracking

Conversation

@Dunqing
Copy link
Copy Markdown
Collaborator

@Dunqing Dunqing commented Mar 13, 2026

Remove scope_stack, traverse_state, and unused side_effects_free_function_optimization field from CrossModuleOptimizationRunnerContext. The TopLevel guard on visit_call_expression was redundant because the second branch !stmt_idx_to_dynamic_import_expr_addr.is_empty() already ensured the check ran for modules with dynamic imports, and for the top-level case the side-effect-free function detection should run unconditionally anyway.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 13, 2026

Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit 9a832b5
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/69b97605ce425e0008f3cca9

@Dunqing Dunqing changed the title refactor(rust): simplify cross_module_optimization by removing redundant scope tracking refactor(rust): simplify cross_module_optimization by removing redundant scope tracking Mar 13, 2026
@Dunqing Dunqing force-pushed the 03-13-refactor_rust_simplify_cross_module_optimization_by_removing_redundant_scope_tracking branch from 3b80991 to 9a832b5 Compare March 17, 2026 15:40
@Dunqing Dunqing requested a review from IWANABETHATGUY March 17, 2026 15:41
@Dunqing Dunqing marked this pull request as ready for review March 17, 2026 15:41
@github-actions
Copy link
Copy Markdown
Contributor

Benchmarks Rust

  • target: main(529f54b)
  • pr: 03-13-refactor_rust_simplify_cross_module_optimization_by_removing_redundant_scope_tracking(9a832b5)
group                                                        pr                                     target
-----                                                        --                                     ------
bundle/bundle@multi-duplicated-top-level-symbol              1.00     65.6±2.55ms        ? ?/sec    1.12     73.4±2.98ms        ? ?/sec
bundle/bundle@multi-duplicated-top-level-symbol-sourcemap    1.00     75.6±4.09ms        ? ?/sec    1.12     84.7±4.33ms        ? ?/sec
bundle/bundle@rome_ts                                        1.00    142.6±6.79ms        ? ?/sec    1.09    155.4±5.93ms        ? ?/sec
bundle/bundle@rome_ts-sourcemap                              1.00    161.4±5.91ms        ? ?/sec    1.10    177.0±5.40ms        ? ?/sec
bundle/bundle@threejs                                        1.00     64.2±5.28ms        ? ?/sec    1.05     67.8±4.96ms        ? ?/sec
bundle/bundle@threejs-sourcemap                              1.00     71.7±2.48ms        ? ?/sec    1.10     78.9±4.28ms        ? ?/sec
bundle/bundle@threejs10x                                     1.00    726.6±8.23ms        ? ?/sec    1.00   729.6±14.68ms        ? ?/sec
bundle/bundle@threejs10x-sourcemap                           1.01   825.2±12.75ms        ? ?/sec    1.00   818.4±11.76ms        ? ?/sec

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 17, 2026

Merging this PR will not alter performance

✅ 6 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing 03-13-refactor_rust_simplify_cross_module_optimization_by_removing_redundant_scope_tracking (9a832b5) with main (638ce1e)2

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (529f54b) during the generation of this report, so 638ce1e was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@Dunqing Dunqing requested review from IWANABETHATGUY and removed request for IWANABETHATGUY March 18, 2026 05:09
.canonical_ref_for((self.immutable_ctx.module_idx, symbol_id).into());
Some(self.immutable_ctx.global_side_effect_free_function_symbols.contains(&symbol_ref))
})
.unwrap_or(false);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For the inner scope CallExpr heavy scenario, this will regress.

@IWANABETHATGUY
Copy link
Copy Markdown
Member

Analysis generated by C/C:

Old code's guard was cheap:

  • self.traverse_state.contains(TraverseState::TopLevel) is a single bitflag check — essentially free
  • It immediately rejects all non-top-level call expressions with zero work

Old code's scope tracking was also cheap:

  • Vec::push/pop of a ScopeFlags (a small integer) — sequential, cache-friendly
  • Bitflag update — trivial

New code now runs the full check on every call expression:

  • as_identifier() — enum match
  • reference_id.get() — Cell read
  • scope.get_reference().symbol_id() — indexed lookup
  • canonical_ref_for(...) — pointer chasing through symbol ref chain
  • HashSet::contains(...) — hash + probe

the vast majority of call expressions live inside function bodies, not at the top level. A typical module might have 10 top-level calls and 200+ nested ones. The old bitflag guard rejected those 200 calls with a single branch. Now all 200 go through the full lookup chain.

So the real trade-off is:

Old New
Scope tracking O(scopes) cheap Vec ops 0
Side-effect check ~top-level calls only ALL call expressions

The 190+ extra hash lookups (with cache-unfriendly pointer chasing in canonical_ref_for) likely outweigh the savings from removing cheap, cache-friendly Vec push/pops.

Performance is likely a small net negative, not a win. The readability gain is real, but calling the scope tracking "redundant" understates the fact that it was also serving as an efficient early-exit optimization.

@IWANABETHATGUY
Copy link
Copy Markdown
Member

I don't have a strong opinion on this because I haven't had time to analyze the actual distribution of CallExpr, which requires many real-world projects. Feel free to merge

@Dunqing
Copy link
Copy Markdown
Collaborator Author

Dunqing commented Mar 18, 2026

Considering this becomes much clearer, so merging it.

@Dunqing Dunqing enabled auto-merge (squash) March 18, 2026 06:30
@shulaoda shulaoda disabled auto-merge March 18, 2026 06:42
@shulaoda shulaoda merged commit ba13d10 into main Mar 18, 2026
35 checks passed
@shulaoda shulaoda deleted the 03-13-refactor_rust_simplify_cross_module_optimization_by_removing_redundant_scope_tracking branch March 18, 2026 06:42
@github-actions github-actions bot mentioned this pull request Mar 18, 2026
shulaoda added a commit that referenced this pull request Mar 18, 2026
## [1.0.0-rc.10] - 2026-03-18

### 🚀 Features

- add indentExclusionRanges property to MagicString (#8746) by @IWANABETHATGUY
- expose `oxcRuntimePlugin` (#8654) by @sapphi-red
- rust: make bundler generic over FileSystem for in-memory benchmarks (#8652) by @Boshen

### 🐛 Bug Fixes

- rolldown_plugin_vite_dynamic_import_vars: align dynamic import fast check with Vite (#8760) by @shulaoda
- renamer: handle existing bindings in nested scopes when finding unique names (#8741) by @drewolson
- pass `yarn_pnp` option where needed (#8736) by @sapphi-red
- preserve optional chaining in namespace member expr rewrite (#8712) by @Copilot
- correct UTF-16 index handling in native MagicString (#8693) by @IWANABETHATGUY
- mark failing doctests as ignore (#8700) by @Boshen
- prevent may_partial_namespace from leaking through include_module (#8682) by @IWANABETHATGUY
- ci: bump native-build cache key to invalidate stale napi-rs artifacts (#8678) by @Boshen
- `comments.annotation: false` breaking tree-shaking (#8657) by @IWANABETHATGUY
- validate filenames for NUL bytes from chunkFileNames/entryFileNames (#8644) by @IWANABETHATGUY
- dce-only minify should not set NODE_ENV to production (#8651) by @IWANABETHATGUY

### 🚜 Refactor

- rust: remove dead `CrossModuleOptimizationConfig::side_effects_free_function_optimization` (#8673) by @Dunqing
- rust: simplify `cross_module_optimization` by removing redundant scope tracking (#8672) by @Dunqing
- simplify string repeat in guess_indentor (#8753) by @IWANABETHATGUY
- consolidate custom magic-string tests into one file (#8696) by @IWANABETHATGUY
- extract CJS bailout checks from include_symbol (#8683) by @IWANABETHATGUY
- rust: remove `BindingIdentifierExt` to use `BindingIdentifier::symbol_id()` instead (#8667) by @Dunqing
- bench: add bench_preset helper and inline presets (#8658) by @Boshen
- rust: filter external modules from entries instead of mapping bit positions (#8637) by @Dunqing

### 📚 Documentation

- clarify watch mode behavior and its limitations (#8751) by @sapphi-red
- add external link icon to GitHub button in Hero section (#8731) by @thisisnkc
- guide: clarify that `inject` option is only conceptually similar to esbuild's one (#8743) by @sapphi-red
- meta/design: add `devtools.md` (#8663) by @hyf0
- add viteplus alpha announcement banner (#8668) by @shulaoda

### ⚡ Performance

- rolldown: some minor perf optimization found by autoresearch (#8730) by @Brooooooklyn
- replace Vec allocation with lazy iterator in find_hash_placeholders (#8703) by @Boshen
- replace TypedDashMap with TypedMap in CustomField (#8708) by @Boshen
- bench: remove scan benchmark binary to halve LTO link time (#8694) by @Boshen

### 🧪 Testing

- watch: increase timeout for error output (#8766) by @sapphi-red
- vite-tests: remove JS plugin tests (#8767) by @sapphi-red
- watch: add CLI exit code test (#8752) by @sapphi-red
- normalize paths on Windows even if `resolve.symlinks` is false (#8483) by @sapphi-red

### ⚙️ Miscellaneous Tasks

- correct comment in bundle-analyzer-plugin.ts (#8770) by @origami-z
- upgrade oxc to 0.120.0 (#8764) by @Boshen
- enable all test for `reset` category in MagicString.test.ts (#8749) by @IWANABETHATGUY
- deps: update test262 submodule for tests (#8742) by @sapphi-red
- deps: update oxc apps (#8734) by @renovate[bot]
- deps: update softprops/action-gh-release action to v2.6.1 (#8724) by @renovate[bot]
- deps: update npm packages (major) (#8722) by @renovate[bot]
- deps: update github-actions (major) (#8721) by @renovate[bot]
- deps: update softprops/action-gh-release action to v2.6.0 (#8720) by @renovate[bot]
- deps: update npm packages (#8718) by @renovate[bot]
- deps: update rust crates (#8717) by @renovate[bot]
- deps: update github-actions (#8716) by @renovate[bot]
- deps: update dependency oxlint-tsgolint to v0.17.0 (#8713) by @renovate[bot]
- deps: bump cargo-shear to v1.11.2 (#8711) by @Boshen
- use org level `CODE_OF_CONDUCT.md` (#8706) by @sapphi-red
- fix cache key mismatch and remove redundant cache saves (#8695) by @Boshen
- deps: update oxc apps (#8692) by @renovate[bot]
- deps: update oxc apps (#8649) by @renovate[bot]
- should do matrix out side of reusable workflows 2 (#8691) by @hyf0
- should do matrix out side of reusable workflows (#8690) by @hyf0
- deps: update dependency rolldown-plugin-dts to v0.22.5 (#8689) by @renovate[bot]
- upgrade oxc to 0.119.0 and oxc_resolver to 11.19.1 (#8686) by @Boshen
- correct if condition of `type-check` job (#8677) by @hyf0
- Gate CI type-check job on node changes (#8669) by @Copilot
- benchmark: improve codspeed build (#8665) by @Boshen
- deps: update oxc to v0.118.0 (#8650) by @renovate[bot]
- deps: update crate-ci/typos action to v1.44.0 (#8647) by @renovate[bot]
- deps: update oxc resolver to v11.19.1 (#8646) by @renovate[bot]
- deps: update dependency rust to v1.94.0 (#8648) by @renovate[bot]
- deps: update dependency rolldown-plugin-dts to v0.22.4 (#8645) by @renovate[bot]

### ◀️ Revert

- Revert "ci: Gate CI type-check job on node changes" (#8674) by @hyf0
- "chore(deps): update dependency rust to v1.94.0 (#8648)" (#8660) by @shulaoda

### ❤️ New Contributors

* @origami-z made their first contribution in [#8770](#8770)
* @drewolson made their first contribution in [#8741](#8741)
* @thisisnkc made their first contribution in [#8731](#8731)

Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants