Skip to content

Conversation

@kripken
Copy link
Member

@kripken kripken commented Nov 26, 2025

If a codebase has a long chain of single calls

a -> b -> c -> d

then we can end up in a very slow and unprofitable situation, removing
params from c's call to d, which then means c does not use some params,
and then we go back and so forth. Each step back requires a full scan of
the code. We could develop a more sophisticated IR to handle this, but it
would need to track that the local.get of the incoming param is only used
in an outgoing param, etc., which is not trivial (1), and these chains are
unprofitable in another way: single calls like this are inlined anyhow,
making this work redundant.

For simplicity, this PR detects the most obvious case of such a chain -
that an iteratiion of work only found a single single-caller call to remove
params from - and stops removing params from that point.

This makes this pass 30% faster on a large Dart testcase, which makes
-O3 9% faster. On other large wasm files I see much smaller benefits,
but it helps sometimes there too.

This is not truly NFC as while inlining will handle this case after, we do
alter the order a bit, leading to slightly different outputs sometimes. (The
changes are not better or worse, just noise.)

Diff without whitespace is smaller.

(1) We would need to track such things through all the other
operations this pass does, like optimize. I tinkered with this in various
ways but it ends up far more complex. I also tried other options here:

  • Run inlining before. This works great on Dart, where DAE is slow and
    inlining is fast, but on large C++ cases the reverse is true, leading to
    regressions.
  • Running removeParameters in a loop: keep removing while we
    find something, rather than wait for a whole new iteration of the pass.
    This is complex, though, as we need to update the IR as we go.

@kripken kripken requested review from dschuff and tlively November 26, 2025 21:12
@kripken kripken merged commit 3f922c3 into WebAssembly:main Dec 2, 2025
17 checks passed
@kripken kripken deleted the dae.unprofit branch December 2, 2025 23:16
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