-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP][MIR] Generic lattice-based DF framework #33628
Conversation
Only a forward one so far
ACS here stands for Alias-Constant-Simplify. This propagation pass is a composition of three distinct dataflow passes: alias-propagation, constant-propagation and terminator simplification. This pass also serves to showcase the features of the framework. Most notably the terseness, composability and the capability to interleave analysis and transformations.
r? @Aatch (rust_highfive has picked a reviewer for you, use r? to override) |
☔ The latest upstream changes (presumably #33632) made this pull request unmergeable. Please resolve the merge conflicts. |
StatementChange::None => StatementChange::Statement(ns), | ||
x => x | ||
}, | ||
StatementChange::Statements(nss) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that, in the case of multiple statements, just transforming each statement doesn't work - the fact needs to be transferred across each statement. For example, an (admittedly silly) transformation that takes x = y
to newtmp = y; x = newtmp
should not mess up constant propogation - if y
is constant, it should infer that newtmp
is the same constant and fill in the value for x.
In Hoopl, this is solved by having rewrite functions be more like lists of rewrite functions - thenFwdRw
doesn't actually run one rewrite after another, instead doing the first rewrite and then scheduling the second rewrite to occur next. Thus, the final transfer and rewrite engine is responsible for running rewrites in sequence, and can transfer facts across newly transformed statements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that, in the case of multiple statements, just transforming each statement doesn't work - the fact needs to be transferred across each statement.
That’s right, I was thinking about how I would approach it and that’s exactly why I didn’t include a way to replace a statement with a (sub-)graph but replacement with a list of statements fell through the cracks.
Note for everybody looking at this: my exam session begins this week and lasts through the 2nd part of june. I’m pretty sure this PR won’t progress at all before the session ends. All the reviews are appreciated and I’ll look at and try to respond to them in as timely manner as possible. |
Cc me |
Note to self: do not forget about nagisa#1 |
cc @rust-lang/compiler (I for one didn't see this due to lack of notification :) |
@nagisa good luck on exams :) |
@@ -118,12 +83,11 @@ impl<'tcx> MirPass<'tcx> for SimplifyCfg { | |||
while changed { | |||
pretty::dump_mir(tcx, "simplify_cfg", &counter, src, mir, None); | |||
counter += 1; | |||
changed = self.simplify_branches(mir); | |||
changed |= self.remove_goto_chains(mir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an endless loop now, as changed
is never set to false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's why I commented the pass out.
On May 19, 2016 3:39 PM, "Björn Steinbrink" notifications@github.com
wrote:
In src/librustc_mir/transform/simplify_cfg.rs
#33628 (comment):@@ -118,12 +83,11 @@ impl<'tcx> MirPass<'tcx> for SimplifyCfg {
while changed {
pretty::dump_mir(tcx, "simplify_cfg", &counter, src, mir, None);
counter += 1;
changed = self.simplify_branches(mir); changed |= self.remove_goto_chains(mir);
This is an endless loop now, as changed is never set to false.
—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/rust-lang/rust/pull/33628/files/ee4a7c39e84237756fd453356eaec0921356873f#r63869926
This PR at its current state has only the implementation of forward dataflow analysis and a accompanying alias-constant-simplify propagation pass.
The lattice-based dataflow framework is greatly inspired by the Hoopl and its paper. The framework besides just being yet another dataflow engine allows for interleaving transformations and analysis + composition of the passes. These are something the gen-kill-set-based dataflow engines aren’t quite suited for. Those features are showcased by the accompanying ACS pass and without them the ACS pass wouldn‘t be otherwise possible (at least not within 200 lines).
Some notes: this is not yet complete: I expect to expand the framework to gain some more useful combinators (or at least those described in the paper) as well as some more other niceties to simplify production of dataflow-reliant passes and backwards analysis capabilities and so on and on.
Some results:
For following pieces of code this MIR (with dead variables removed by yours truly) gets produced: