Skip to content

[wasm-split] Deduplicate loops in shareImportableItems (NFC) - #8992

Open
aheejin wants to merge 20 commits into
wasm_split_remove_optfrom
wasm_split_dedup_loops
Open

[wasm-split] Deduplicate loops in shareImportableItems (NFC)#8992
aheejin wants to merge 20 commits into
wasm_split_remove_optfrom
wasm_split_dedup_loops

Conversation

@aheejin

@aheejin aheejin commented Aug 12, 2026

Copy link
Copy Markdown
Member

We have six mostly identical loops in shareImportableItems, each for memories, tables, globals, tags, data segments, and element segments. This factors the core logic out as a generic lambda function.

Given a module element name, many parts of the code queries for its
owning modules (where the module element has to be placed) or secondary
modules using that module element. This adds `OwnershipTracker`, which
precomputes and manages that information. All calls to `getOwner` or
`getUsingSecondaries` that required computations iterating on all
secondary modules which can be as many as thousands, has been replaced
with a call that simply returns prcomputed information.

For the Jul 2026 version of the applications received from the Dart
team, this reduces the running time of wasm-split by 17% for acx_gallery
(30s -> 25s) and by 33% for essentials (230s -> 153s).

Suggested in
#8832 (comment).
Previously we removed module elements one by one within a loop. But
because `Module` stores a module element in both a map and a vector,
removing a single module element using `removeModuleElement` is O(N),
because it needs to shift all vector elements after it:
https://github.com/WebAssembly/binaryen/blob/302396a676433152a32375a81d71e74687c97a1b/src/wasm/wasm.cpp#L1970-L1979

This removes module elements in bulk using `removeModuleElements`, which
does the shifting only once.
https://github.com/WebAssembly/binaryen/blob/302396a676433152a32375a81d71e74687c97a1b/src/wasm/wasm.cpp#L2004-L2018

Combining with #8986, acx_gallery's running time improved by 50.3% (30s
-> 15s), and essentials by 60.8% (230s -> 90s). (for Jul 2026 version)

I guess the main reason for the running time increase in #8441 was this
O(N) `removeModuleElement` called within a loop after all.
We have six mostly identical loops in `shareImportableItems`, each for
memories, tables, globals, tags, data segments, and element segments.
This factors the core logic out as a generic lambda function.
@aheejin
aheejin requested a review from tlively August 12, 2026 16:29
@aheejin
aheejin requested a review from a team as a code owner August 12, 2026 16:29

@tlively tlively left a comment

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.

Nice! LGTM once the preliminaries land.

aheejin and others added 14 commits August 14, 2026 14:25
Co-authored-by: Thomas Lively <tlively@google.com>
Co-authored-by: Thomas Lively <tlively123@gmail.com>
This removes the use of `ParallelFunctionAnalysis` within `scanModule`
(in `computeUsedNames`), which scans `UsedNames` for each module.

I'm not 100% sure why but this improves running time at least for Dart
applications. I also previously tried to use `ParallelFunctionAnalysis`
in other functions but it resulted in slowdown so didn't do it. Maybe
cache locality works against the parallelism.

This reduces running time of acx_gallery (Jul 2026) by 7.8% (30.6s ->
28.2s) essentials by 4.2% (225.1s -> 215.6s).
Co-authored-by: Thomas Lively <tlively@google.com>
@aheejin
aheejin force-pushed the wasm_split_remove_opt branch from e802ede to 485abf9 Compare August 17, 2026 23:38
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.

2 participants