Skip to content

Limit alias regions in Wasm-to-CLIF translation to 256 - #14253

Open
fitzgen wants to merge 2 commits into
bytecodealliance:mainfrom
fitzgen:limit-number-of-alias-regions
Open

Limit alias regions in Wasm-to-CLIF translation to 256#14253
fitzgen wants to merge 2 commits into
bytecodealliance:mainfrom
fitzgen:limit-number-of-alias-regions

Conversation

@fitzgen

@fitzgen fitzgen commented Sep 1, 2026

Copy link
Copy Markdown
Member

Instead of bitpacking the AliasRegionKey into a u32, hash it and then xor-fold the hash down to one byte.

Fixes #14221

Depends on #14230

There were two ways in which alias analysis's `LastStores` state was not a
proper lattice, which made the order we processed the worklist and called
`LastStores::meet` observable:

1. We didn't have a single, canonical bottom value for the last store to a
region. We were taking the first instruction in a block as an identifier for
control-flow join points so that we would get different `MemoryLoc`s for
different control-flow joins, which is necessary to avoid illegally forwarding a
value loaded inside one control-flow join to a load in another, different
control-flow join. However, this meant that we effectively had multiple bottom
elements, which made the path we descended through the "lattice" observable. The
solution here was to create a separate `LastStore` dataflow value that has a
single, canonical bottom element, and a distinct `MemoryVersion` value that is
the same as `LastStore` but replaces its bottom value with a variant that
identifies the associated control-flow join point. We use `LastStore` in our
`LastStores` lattice, when we need a bottom element, and we use `MemoryVersion`
in our `MemoryLoc` keys, to distinguish between different regions where we don't
know anything about the contents of memory.

2. We computed the observed-stores set while we computed the fixpoint of the
initial `LastStores` inputs to each block. This was incorrect, however, because
a `LastStores` could transiently contain a `LastStore::Inst` that disappears in
later iterations of the fixpoint, and which instructions do or don't transiently
appear in `LastStores` in that way depends on the order in which we call
`LastStores::meet`. Therefore, observing stores while computing the fixpoint
might or might not observe an instruction depending on the worklist processing
order. The solution in this case was to only compute the observed-stores set
after we've computed the `LastStores` fixpoint, at which point there are no
transient `LastStore::Inst`s anymore.
Instead of bitpacking the `AliasRegionKey` into a `u32`, hash it and then
`xor`-fold the hash down to one byte.

Fixes bytecodealliance#14221
@fitzgen
fitzgen requested review from a team as code owners September 1, 2026 00:29
@fitzgen
fitzgen requested review from cfallin and removed request for a team September 1, 2026 00:29
@github-actions github-actions Bot added the cranelift Issues related to the Cranelift code generator label Sep 1, 2026
@gfx

gfx commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

This fixes the problem I reported in #14210.

I used the generator script from that issue and ran wasmtime compile -o /dev/null. Release build, best of 3, macOS / aarch64 only.

N base ffb04089ea this PR
250 0.14 s 0.08 s
500 0.97 s 0.19 s
1000 6.86 s 0.40 s
2000 51.48 s 0.87 s
4000 -- 1.79 s
8000 -- 4.15 s

Time roughly doubles when N doubles, out to N=8000. The blowup is gone and my
module builds again. Thank you.

FYI, the RPO worklist from #14211 is still 3-5x faster on top of this PR
(0.16 s at N=2000, 1.39 s at N=8000), but the gap narrows as N grows, so it is
only a constant factor now. However, I am closing #14211. It conflicts, and this PR fixes what I actually
hit.

One request: if this misses the 49.0.0 branch on the 5th, could it be
backported to release-48.0.0? The slowdown is a serious regression in 48.0.0, and
48.0.x is the current release. I know patch releases are meant for
security and correctness fixes and that backports are volunteer work, so this
is only a request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cranelift Issues related to the Cranelift code generator

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Excessive compile time in alias analysis for 500 live structs on the stack

2 participants