Repository navigation
feat(rewrite): native statement and block rules in driver sweeps - #842
Conversation
c63615e to
3fa29cc
Compare
3fa29cc to
92523e4
Compare
planza-quera
left a comment
There was a problem hiding this comment.
Thanks for the work!
I'm a bit unsure as to whether allowing writing rewrite rules in this way is ideal. At my previous work it was a bit hassle having essentially two codebases in which rewrite rules are written: native C++ mlir patterns, and DSL PDLL patterns.
I suppose in Kirin this is not so much of a problem since the "DSL" #[rewrite_rule] patterns can live alongside the native Rust rules. Since both kinds of rules can also be included in the same RuleSet and applied together in the same rewrite driver, my concerns mostly go away. (Sorry for the ramble)
Regarding implementing CSE (or even DCE) as a #[rewrite_rule], my idea was that this would be possible once we have a way of accessing analysis results from the rewrite rules.
|
I agree @planza-quera, I wasn't initially sold on why we should also have rules written in Rust either. But I think the main benefit is that these Rust rules are able to store state so they are more powerful. |
Opened a PR implementing the read-only view to access analysis results. There is currently some awkwardness/inconvenience since the analysis results keep borrowing the same pipeline the rewrite engine needs. |
Add the StatementRule and BlockRule traits and RuleSet methods adding them by recipe, in one ordered list with pattern rules. Rename RuleSet::add to add_pattern_rule. The driver does not run native rules yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Build a fresh copy of each statement rule every sweep and try it at each visited statement, in list order with pattern rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hand each block a visited statement owns to a fresh copy of each block rule, in list order with the other rules, skipping blocks an earlier copy removed. Add ScfFunctionLanguage for tests with scf.if. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe native rules in the crate docs, tick the M2 native-rule items, and update the NativeRule section and Gap 4 to the per-sweep and per-block lifecycle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92523e4 to
8c83c59
Compare
Adds native rules to
kirin-rewrite: rules written in Rust, with no pattern, for work a#[rewrite_rule]pattern can't express, such as CSE, which has to remember the expressions it has seen. Covers the four open native-rule items of M2 indocs/design/rewrite-engine.md.Stacked on
alex/walk-results.What's added
StatementRule<L>is handed each statement the driver visits.BlockRule<L>is handed each block a visited statement owns: itsBlocks, then every block of itsCFGs. Graph bodies are not handed over.Result<WalkResult, RewriteError>, so they steer the sweep like pattern rules do.RuleSetmethods:add_statement_rule(name, recipe)andadd_block_rule(name, recipe). The name is used in errors.Decisions
RuleSetstores a recipe (a closure) per native rule, not a live rule. A statement rule gets a fresh copy every sweep, and a block rule a fresh copy for every block.DriverError::Walk.RewriteErrorbecomesDriverError::Rewrite, carrying the rule's name and the visited statement.API changes
RuleSet::addis renamedadd_pattern_rule, to sit next to the two new methods. Its only caller wasRuleSet::build.RuleSet::rules()is now crate-private.Known limitation
A block rule gets a fresh copy per block, so a CSE block rule starts each block with an empty table of the expressions seen so far. It therefore can't reuse a value computed in an enclosing block, for example merge a
neg %xin anscf.ifarm into an identicalneg %xbefore theif. Reusing one needs no driver change: hoist speculatable ops out of the nested block first, so both are in the same block, or have the rule seed its table by reading the statements of the enclosing blocks that come before the nested block's owner.Tests
ScfFunctionLanguageinkirin-test-languages, behind featurescf-function-language.kirin-rewritegains dev-dependencies onkirin-scfandkirin-cf.