Cranelift: add "fuel" to egraph rewrites.#13390
Merged
Merged
Conversation
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.
fitzgen
approved these changes
May 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
Noneafterward. 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.