Skip to content

Translate Wasm block params into Variables instead of CLIF block params#13711

Open
fitzgen wants to merge 3 commits into
bytecodealliance:mainfrom
fitzgen:wasmtime-wasm-block-params-should-be-variables
Open

Translate Wasm block params into Variables instead of CLIF block params#13711
fitzgen wants to merge 3 commits into
bytecodealliance:mainfrom
fitzgen:wasmtime-wasm-block-params-should-be-variables

Conversation

@fitzgen

@fitzgen fitzgen commented Jun 22, 2026

Copy link
Copy Markdown
Member

This allows SSA construction to determine whether they need to actually become block params or not, and cuts down on the number of unnecessary block parameters we pessimistically introduce during Wasm-to-CLIF translation.

@fitzgen fitzgen requested review from a team as code owners June 22, 2026 22:01
@fitzgen fitzgen requested review from cfallin and removed request for a team June 22, 2026 22:01

@cfallin cfallin 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.

Thanks! This technically looks fine to me, and I agree it's nice to use our existing algorithm to avoid creating blockparams where they are actually trivial/unneeded.

I'm curious, however, since this does make things a little more complex (some blocks take vars, some don't), and leans more on an implicit SSA construction algorithm, which does have some cost, with the hypothesis that we'll get better code / faster compiles with fewer blockparams in the IR: have you measured the improvement? Do we see faster compile or faster runtimes out of this?

/// For a Wasm control-flow target (i.e. a block with associated parameter
/// `Variable`s) we `use_var` each of those variables. For a block with real
/// CLIF block parameters (the function's exit block) we read those parameters
/// directly.

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.

This distinction seems to me like it has potential to be error-prone or at least lead to subtle cases (e.g. there's the implicit invariant that the exit block is not also a Wasm target; we're creating a new bifurcation of kinds-of-blocks). Is there a reason we can't have the exit-block take its return value(s) as variables, too?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I initially was trying to minimize changes by leaving the return block as-is, but switching it over as well means that basically all blocks are handled uniformly now (using variables instead of block params) except for two cases:

  1. The entry block, which has function params
  2. Exception blocks, which take the payload as params

However, both of these kinds of blocks are never targeted for branching directly by e.g. br_if in Wasm so they can never have Wasm stack operand params, so our handling of Wasm branch targets can still be uniform. I think this leaves us in a pretty nice place, but I'm curious what your opinion is too.

See also c20864c

@fitzgen

fitzgen commented Jun 24, 2026

Copy link
Copy Markdown
Member Author

I'm curious, however, since this does make things a little more complex (some blocks take vars, some don't), and leans more on an implicit SSA construction algorithm, which does have some cost, with the hypothesis that we'll get better code / faster compiles with fewer blockparams in the IR: have you measured the improvement? Do we see faster compile or faster runtimes out of this?

Just did a sightglass run on a subset of the suite recommended by an initial PCA analysis (before going through all the steps I still want to do before the Official analysis) and this PR doesn't have any statistically significant effect on either compilation or execution:

Details
compilation :: cycles :: benchmarks/cm-online-stats/cm-online-stats.wasm

  No difference in performance.

  [61682 72049.07 117404] main.dylib
  [63866 80856.55 570407] vars.dylib

compilation :: cycles :: benchmarks/splay/splay.wasm

  No difference in performance.

  [40436 50629.25 62620] main.dylib
  [39045 49528.01 59814] vars.dylib

compilation :: cycles :: benchmarks/tinygo/tinygo-json.wasm

  No difference in performance.

  [1347717 1544747.12 1945877] main.dylib
  [1341698 1563298.14 1827803] vars.dylib

compilation :: cycles :: benchmarks/hex-simd/benchmark.wasm

  No difference in performance.

  [188251 211734.34 259940] main.dylib
  [189635 214170.23 294342] vars.dylib

execution :: cycles :: benchmarks/hex-simd/benchmark.wasm

  No difference in performance.

  [1163 1294.28 1621] main.dylib
  [1163 1280.12 1472] vars.dylib

compilation :: cycles :: benchmarks/rust-protobuf/benchmark.wasm

  No difference in performance.

  [250100 273895.97 312874] main.dylib
  [247004 276475.62 514901] vars.dylib

compilation :: cycles :: benchmarks/spidermonkey/spidermonkey-regex.wasm

  No difference in performance.

  [12437845 12799608.08 14087684] main.dylib
  [12399019 12868181.21 14477717] vars.dylib

execution :: cycles :: benchmarks/rust-protobuf/benchmark.wasm

  No difference in performance.

  [26572 30433.83 35473] main.dylib
  [26738 30307.06 34453] vars.dylib

compilation :: cycles :: benchmarks/blake3-scalar/benchmark.wasm

  No difference in performance.

  [196620 230621.09 321439] main.dylib
  [201370 229802.09 290981] vars.dylib

execution :: cycles :: benchmarks/spidermonkey/spidermonkey-regex.wasm

  No difference in performance.

  [521266 536802.54 589523] main.dylib
  [518161 535075.71 630966] vars.dylib

execution :: cycles :: benchmarks/tinygo/tinygo-json.wasm

  No difference in performance.

  [687485 711986.11 737841] main.dylib
  [692311 714065.42 743352] vars.dylib

execution :: cycles :: benchmarks/splay/splay.wasm

  No difference in performance.

  [64684190 66353450.56 67354379] main.dylib
  [64723590 66454334.51 67421356] vars.dylib

execution :: cycles :: benchmarks/cm-online-stats/cm-online-stats.wasm

  No difference in performance.

  [80048559 83716999.75 85692835] main.dylib
  [82024100 83823961.71 89048619] vars.dylib

execution :: cycles :: benchmarks/blake3-scalar/benchmark.wasm

  No difference in performance.

  [1917 2113.29 2455] main.dylib
  [1915 2112.69 3030] vars.dylib

fitzgen added 3 commits June 23, 2026 18:18
…rams

This allows SSA construction to determine whether they need to actually become
block params or not, and cuts down on the number of unnecessary block parameters
we pessimistically introduce during Wasm-to-CLIF translation.
@fitzgen fitzgen force-pushed the wasmtime-wasm-block-params-should-be-variables branch from 71c6d56 to 2b3665c Compare June 24, 2026 01:31
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