Skip to content

Cranelift: add "fuel" to egraph rewrites.#13390

Merged
cfallin merged 2 commits into
bytecodealliance:mainfrom
cfallin:egraph-fuel
May 15, 2026
Merged

Cranelift: add "fuel" to egraph rewrites.#13390
cfallin merged 2 commits into
bytecodealliance:mainfrom
cfallin:egraph-fuel

Conversation

@cfallin
Copy link
Copy Markdown
Member

@cfallin cfallin commented May 15, 2026

This addresses the kind of blowup seen in #13068 (and analyzed in #13204). Specifically, even though we limit the rewrite depth, and size of eclasses, one can still get into situations where the Cartesian product of match possibilities on the left-hand side blows up.

The ISLE rules in the mid-end are compiled to Rust that loops over iterators over each eclass, so if we limit what those iterators can return, we can limit the only dynamic factor in the runtime of the ruleset. This PR implements "fuel" that imposes a hard cutoff of 500 LHS matches per top-level rewrite invocation, with iterators returning None afterward. The mid-end failing to find a match is always OK -- it just means that we don't rewrite/optimize -- so cutting off early is always a correct/valid choice.

The cutoff limit of 500 might seem a little high at first glance, but note that this is every LHS match; including e.g. in sub-matchers; 50 turned out to miss a few rewrites in our tests, so I turned the knob up to 500. This is still sufficient to limit the blowup case shown in #13068 from 2.31s to 0.01s, with RSS decreasing from 855 MiB to 17 MiB, which is a significant win.

Fixes #13204.

This addresses the kind of blowup seen in bytecodealliance#13068 (and analyzed in bytecodealliance#13204).
Specifically, even though we limit the rewrite depth, and size of
eclasses, one can still get into situations where the Cartesian
product of match possibilities on the left-hand side blows up.

The ISLE rules in the mid-end are compiled to Rust that loops over
iterators over each eclass, so if we limit what those iterators can
return, we can limit the only dynamic factor in the runtime of the
ruleset. This PR implements "fuel" that imposes a hard cutoff of 500
LHS matches per top-level rewrite invocation, with iterators returning
`None` afterward. The mid-end failing to find a match is always OK --
it just means that we don't rewrite/optimize -- so cutting off early
is always a correct/valid choice.

The cutoff limit of 500 might seem a little high at first glance, but
note that this is *every* LHS match; including e.g. in sub-matchers;
50 turned out to miss a few rewrites in our tests, so I turned the
knob up to 500. This is still sufficient to limit the blowup case
shown in bytecodealliance#13068 from 2.31s to 0.01s, with RSS decreasing from 855 MiB
to 17 MiB, which is a significant win.

Fixes bytecodealliance#13204.
@cfallin cfallin requested a review from a team as a code owner May 15, 2026 17:59
@cfallin cfallin requested review from fitzgen and removed request for a team May 15, 2026 17:59
@github-actions github-actions Bot added the cranelift Issues related to the Cranelift code generator label May 15, 2026
Copy link
Copy Markdown
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Thanks!

Comment thread cranelift/codegen/src/egraph/mod.rs Outdated
@cfallin cfallin enabled auto-merge May 15, 2026 22:37
@cfallin cfallin added this pull request to the merge queue May 15, 2026
Merged via the queue into bytecodealliance:main with commit 66f1b3b May 15, 2026
51 checks passed
@cfallin cfallin deleted the egraph-fuel branch May 15, 2026 23:12
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.

Cranelift: follow-up analysis of e-graph rewrite blow-up in #13068

2 participants