Stream: git-wasmtime

Topic: wasmtime / PR #13459 Implement the branch-hinting proposa...


view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:04):

gfx opened PR #13459 from wado-lang:gfx/branch-hinting-v2 to bytecodealliance:main:

Refs #9463. Supersedes #12483 (closed); this reworks that attempt to address
the review there.

What this does

Parses the metadata.code.branch_hint custom section and uses the hints to mark
cold blocks during Cranelift compilation, behind a new opt-in knob:

Addressing the #12483 review

The hint offset uses builder.srcloc().bits() (module-relative) minus the
function body's start (body.get_binary_reader().original_position()), matching
wasmparser::BranchHint.func_offset.

Config::wasm_branch_hinting only affects cold-block layout, so it is excluded
from the compiled-artifact compatibility check in engine/serialization.rs
(an artifact loads into an engine configured either way).

Codegen evidence

In-tree, tests/disas/branch-hinting-aarch64.wat checks $if_unlikely with the
knob on: the unlikely then-block is hoisted out of line past ret, so the hot
path falls through. tests/disas/branch-hinting-disabled.wat is the same module
without the flag and asserts that nothing is marked cold.

The off-vs-on contrast is clearest on a hot loop — from the objdump A/B in the
dogfood experiment linked below, per iteration the hot path goes from two taken
branches to one:

off  cold inline, hot path branches over it every iteration:
    cbnz x0, <cold>    ; ~always taken, skip the inline cold body
    <cold body>        ; wedged between the hot body and the loop back-edge
    add  x3, #1
    b    <loop>

on  cold hoisted past `ret`, hot path falls through:
    cbz  x0, <cold>    ; ~never taken
    add  x3, #1
    b    <loop>
    ret
    <cold body>        ; out of line

Performance

The transformation is the expected one (hot path tightened, cold path moved out
of line), but I'm not claiming a microbenchmark number here: on a tight loop on
Apple Silicon the wall-time delta is within noise — the eliminated forward
branch is perfectly predicted and the loop fits in L1i, so layout barely
matters. Branch hints pay off under i-cache pressure / large hot code, so the
credible place for a number is /bench_x64 on a representative workload rather
than a microbenchmark. There is no runtime overhead either way: hints only
affect compile-time block layout, and with the knob off codegen is unchanged.

This was dogfooded end-to-end against Wado
output (a language that emits metadata.code.branch_hint): an objdump A/B on a
real Wado component shows the hints take effect. The harness and numbers are
published as a reproducible experiment:
<https://github.com/wado-lang/wado/pull/1152>.

Testing

Scope and follow-ups

This is intentionally the codegen + knob slice. Tracked as follow-ups before
flipping the default on:

The stability matrix is updated accordingly (Tier 3, API/C-API done, Tests/Fuzzed
pending, off by default).

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:04):

gfx requested Copilot for a review on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:04):

gfx requested fitzgen for a review on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:04):

gfx requested wasmtime-core-reviewers for a review on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:04):

gfx requested wasmtime-compiler-reviewers for a review on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:04):

gfx requested wasmtime-default-reviewers for a review on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:05):

gfx updated PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:08):

:memo: Copilot submitted PR review:

Pull request overview

[!NOTE]
Copilot was unable to run its full agentic suite in this review.

Adds opt-in support for the WebAssembly branch-hinting proposal by parsing metadata.code.branch_hint and using it to mark cold blocks during Cranelift compilation, with corresponding user-facing knobs and regression tests.

Changes:

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

<details>
<summary>Show a summary per file</summary>

File Description
tests/disas/branch-hinting.wat New disas test ensuring hints mark the expected cold blocks when enabled.
tests/disas/branch-hinting-disabled.wat New disas regression test ensuring hints are ignored by default (no cold blocks).
tests/disas/branch-hinting-aarch64.wat New backend coverage showing hint-driven cold-path layout on aarch64.
tests/all/main.rs Wires in the new Rust test module.
tests/all/branch_hinting.rs Adds semantic-neutrality test across enabled/disabled/default configurations.
docs/stability-wasm-proposals.md Documents branch-hinting status and adds tracking footnote.
crates/wasmtime/src/engine/serialization.rs Treats branch_hinting as non-compat-affecting for serialized artifacts.
crates/wasmtime/src/config.rs Adds Config::wasm_branch_hinting public API.
crates/environ/src/tunables.rs Adds branch_hinting tunable with default false.
crates/environ/src/compile/module_environ.rs Stores parsed branch hints in ModuleTranslation when enabled.
crates/cranelift/src/translate/stack.rs Tracks deferred “else is cold” state for lazily-allocated else blocks.
crates/cranelift/src/translate/code_translator.rs Applies branch hints for if and br_if by marking cold successor blocks.
crates/cranelift/src/func_environ.rs Adds per-function hint cursoring and take_branch_hint lookup by srcloc.
crates/cranelift/src/compiler.rs Feeds per-function hints and function-body start offset into FuncEnvironment.
crates/cli-flags/src/lib.rs Exposes -Wbranch-hinting / wasm proposal flag wiring (opt-in, not in “all”).
crates/c-api/src/config.rs Adds C API setter to enable/disable branch-hinting.
crates/c-api/include/wasmtime/config.h Declares the new C API configuration property.
RELEASES.md Notes the new opt-in branch-hinting support in release notes.
</details>

:light_bulb: <a href="/bytecodealliance/wasmtime/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:08):

:speech_balloon: Copilot created PR review comment:

Making ModuleTranslation::branch_hints a public field exposes an internal representation (and its invariants, e.g. sorted offsets) as API surface. Consider keeping the field private and providing a small accessor (e.g., lookup by FuncIndex returning &[BranchHint]) so you can change storage/validation strategy later without forcing downstream changes.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:08):

:speech_balloon: Copilot created PR review comment:

Using HashMap::insert will overwrite any previously-parsed hints for the same function index, silently dropping earlier entries if the custom section contains duplicates. Even if full validation is deferred, it would be safer to either (a) append/extend an existing hint list (entry(...).and_modify(|v| ...).or_insert(...)) or (b) ignore/log duplicates deterministically to avoid losing hints unexpectedly.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2026 at 23:47):

gfx updated PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 04:01):

github-actions[bot] added the label wasmtime:api on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 04:01):

github-actions[bot] added the label wasmtime:c-api on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 04:01):

github-actions[bot] added the label wasmtime:config on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 04:01):

github-actions[bot] added the label wasmtime:docs on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 04:02):

github-actions[bot] commented on PR #13459:

Label Messager: wasmtime:config

It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:

[fuzzing-config]: https://github.com/bytecodealliance/wasmtime/blob/ca0e8d0a1d8cefc0496dba2f77a670571d8fdcab/crates/fuzzing/src/generators.rs#L182-L194
[fuzzing-docs]: https://docs.wasmtime.dev/contributing-fuzzing.html


<details>

To modify this label's message, edit the <code>.github/label-messager/wasmtime-config.md</code> file.

To add new label messages or remove existing label messages, edit the
<code>.github/label-messager.json</code> configuration file.

Learn more.

</details>

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 15:42):

alexcrichton commented on PR #13459:

@gfx please take a moment to acquaint yourself with the BA's AI tool use policy. Notably this looks like a very large wall of text generated by an AI. Please ensure that you are yourself in the loop on all communication because you, after all, own this change and are responsible for it.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:memo: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

This is quite wordy -- this just needs to refer to the tracking issue.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

You'll want to update at least the first two, possibly third, entry in this matrix. The proposal is phase 5 and this PR includes tests. For "Finished" either the footnote should explicitly say what remains, or it should be checked off.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

Can this pass -Wbranch-hinting=n in the flags section? Also please make sure to phrase comments for readers of the code, not reviewers of the PR. This is committed documentation and does not need to refer to historical state which no one will remember once this lands. This only needs to indicate, for example, that this is testing codegen specifically ignores the custom section when the feature is disabled.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

Can this test be extracted to a *.wast file?

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

Instead of returning Option<bool>, which an be confusing, could this yield a BranchHint itself directly? That way the taken field can be used and english-wise understoood quickly.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

Additionally, to avoid extra overhead, I'd recommend storing the raw decoder itself and saving that in a side table. There shouldn't be a need here to decode the entire section and heap-allocate it all in Wasmtime.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

This comment can be misleading because Wasmtime, spec-wise, can't guarantee anything or require anything of custom sections. This implementation does not validate branch hints nor does it fail on any malformed input. It should be sufficient to say that this ignores invalid sections and more generally does not perform any validation at all.

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

Rather than making a dedicated method for this, could the construction and initialization happen in the constructor for this type?

view this post on Zulip Wasmtime GitHub notifications bot (May 23 2026 at 16:01):

:speech_balloon: alexcrichton created PR review comment:

Can this loop explicitly handle errors rather than discarding them with .flatten()? For example if the branch-hinting section is corrupt then the entire section should be discarded.

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2026 at 01:31):

gfx converted PR #13459 Implement the branch-hinting proposal (parse + Cranelift cold blocks) to a draft

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2026 at 07:40):

gfx updated PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2026 at 09:26):

github-actions[bot] added the label fuzzing on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2026 at 09:26):

github-actions[bot] commented on PR #13459:

Subscribe to Label Action

cc @fitzgen

<details>
This issue or pull request has been labeled: "fuzzing", "wasmtime:api", "wasmtime:c-api", "wasmtime:config", "wasmtime:docs"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2026 at 15:30):

:thumbs_up: alexcrichton submitted PR review:

Thanks! This all looks good to me. I've got one possible touch-up with peekable below, but otherwise with a cargo fmt this seems reasonable to land

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2026 at 15:30):

:speech_balloon: alexcrichton created PR review comment:

One option here would be to use the Iterator::peekable method in the standard library to avoid the peeked_hint field and make it a bit easier to use branch_hints perhaps?

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 07:06):

gfx updated PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 07:20):

gfx updated PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 08:47):

gfx has marked PR #13459 as ready for review.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 08:47):

gfx requested wasmtime-fuzz-reviewers for a review on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 08:50):

gfx commented on PR #13459:

Rebased onto main (conflicts from #13487 and #13354 resolved), all review comments addressed, and cold-block layout is now covered across the x86-64, aarch64, and Pulley backends. CI is green. I think this is ready to merge!

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 11:42):

gfx edited PR #13459:

Refs #9463. Supersedes #12483 (closed); this reworks that attempt to address
the review there.

What this does

Parses the metadata.code.branch_hint custom section and uses the hints to mark
cold blocks during Cranelift compilation, behind a new opt-in knob:

Addressing the #12483 review

The hint offset uses builder.srcloc().bits() (module-relative) minus the
function body's start (body.get_binary_reader().original_position()), matching
wasmparser::BranchHint.func_offset.

Config::wasm_branch_hinting only affects cold-block layout, so it is excluded
from the compiled-artifact compatibility check in engine/serialization.rs
(an artifact loads into an engine configured either way).

Codegen evidence

In-tree, tests/disas/branch-hinting-aarch64.wat checks $if_unlikely with the
knob on: the unlikely then-block is hoisted out of line past ret, so the hot
path falls through. tests/disas/branch-hinting-disabled.wat is the same module
without the flag and asserts that nothing is marked cold.

The off-vs-on contrast is clearest on a hot loop — from the objdump A/B in the
dogfood experiment linked below, per iteration the hot path goes from two taken
branches to one:

off  cold inline, hot path branches over it every iteration:
    cbnz x0, <cold>    ; ~always taken, skip the inline cold body
    <cold body>        ; wedged between the hot body and the loop back-edge
    add  x3, #1
    b    <loop>

on  cold hoisted past `ret`, hot path falls through:
    cbz  x0, <cold>    ; ~never taken
    add  x3, #1
    b    <loop>
    ret
    <cold body>        ; out of line

Performance

The transformation is the expected one (hot path tightened, cold path moved out
of line), but I'm not claiming a microbenchmark number here: on a tight loop on
Apple Silicon the wall-time delta is within noise — the eliminated forward
branch is perfectly predicted and the loop fits in L1i, so layout barely
matters. Branch hints pay off under i-cache pressure / large hot code, so the
credible place for a number is /bench_x64 on a representative workload rather
than a microbenchmark. There is no runtime overhead either way: hints only
affect compile-time block layout, and with the knob off codegen is unchanged.

This was dogfooded end-to-end against Wado
output (a language that emits metadata.code.branch_hint): an objdump A/B on a
real Wado component shows the hints take effect. The harness and numbers are
published as a reproducible experiment:
<https://github.com/wado-lang/wado/pull/1152>.

Scope and follow-ups

This is intentionally the codegen + knob slice. Tracked as follow-ups before
flipping the default on:

The stability matrix is updated accordingly (Tier 3, API/C-API done, Tests/Fuzzed
pending, off by default).

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 11:58):

gfx updated PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 13:03):

gfx updated PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 13:49):

gfx requested Copilot for a review on PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 14:24):

:thumbs_up: alexcrichton submitted PR review:

Thanks!

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 14:25):

alexcrichton added PR #13459 Implement the branch-hinting proposal (parse + Cranelift cold blocks) to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 14:49):

:check: alexcrichton merged PR #13459.

view this post on Zulip Wasmtime GitHub notifications bot (May 28 2026 at 14:49):

alexcrichton removed PR #13459 Implement the branch-hinting proposal (parse + Cranelift cold blocks) from the merge queue


Last updated: Jun 01 2026 at 09:49 UTC