-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
New mir-opt pass to simplify gotos with const values (reopening #77486) #80475
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:8:22: 8:26 | ||
} | ||
|
||
bb1: { |
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.
CC @oli-obk from #77486 (comment)
The MIR still contains two branches in the final MIR, so the optimization in this PR still messes this up. I'm wondering if this can be considered a bug in MatchBranchSimplification
that it does not handle the _0 = const ()
case.
Tangentially, is _0 = const ()
ever needed in a function that returns unit? I think it would only make sense if _0
is considered uninitialized at the beginning of the function. But then, it would probably be a simplification to just set _0 = const ()
at the beginning of bb0
.
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.
_0 = const ()
is never needed, and I thought it's actually eliminated by InstCombine
or sth. Not sure why there's still one around at this point. No ZST assignment is ever needed, you can create references to locals before they are assigned if the local is a ZST (as long as it was StorageLive
d I think).
05b4e79
to
6a73f1c
Compare
cc @tmiasko if you have the time (and interest), could you have a look at this PR? |
I'll set aside some time in the next week or so to review this. In the meantime, if you could squash your commits to remove refactorings/fixes to newly added code, it would make things a bit easier for me. |
if is_local_assigned_in_statements(place.local, &target_bb.statements) { | ||
None? | ||
} |
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.
Compared to the earlier version the transform now supports switch blocks with statements. As a result it has to establish that the definition place = const
reaches the switch, whereas previously it was trivially true.
Based on past experiences, I feel that doing this for an arbitrary place without a dedicated analysis will be challenging. If place is indirect it could be invalidated by other assignments, it can also contain indexing projections referencing other locals that could be modified, etc.
I would probably start with locals without any projections, and in addition to the existing check, also verify that either they never have their address taken or there are no indirect assignment in the switch block.
An example that doesn't work correctly right now:
pub fn main() {
let mut a = &mut 0;
if *a == 0 {
*a = 0;
()
};
let b = &mut a;
**b = 1;
match *a {
1 => {},
_ => panic!(),
}
}
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.
Yeah, you are right. I'll revert the newest changes so that we only support statement-less targets. Then follow ups can improve the situation
☔ The latest upstream changes (presumably #79328) made this pull request unmergeable. Please resolve the merge conflicts. |
c6293b5
to
5734754
Compare
Fixed merge conflicts. Hi @tmiasko, sorry for the long wait. Would you be able to do a review? |
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit 5734754fa175f74a0081ea2823b387013c54ee10 with merge 57512cbea2265af4686716b44fd0bb86358fbcdb... |
@oli-obk the pass currently bails if mir opt level is less than 3 so I would expect no observable change in a perf run.If you want, I can remove the bail out so a perf run can be made. |
oh... oops, didn't re-check, just read your comment and started the perf run. Do you still want that perf run? If so, yea let's change it back |
@bors try- |
@oli-obk Added a commit to disable the mir-opt-level check. Can you start the run again? |
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
0a560ff
to
a6dccfe
Compare
Yea, oops, should've rechecked. @bors r+ |
📌 Commit a6dccfe has been approved by |
⌛ Testing commit a6dccfe with merge 8aa2df00d8834c83aacfb232a83b3c160eeb4dae... |
💔 Test failed - checks-actions |
@bors retry |
⌛ Testing commit a6dccfe with merge c1357d951bac5da7640b3cc5adac992277a89c22... |
💥 Test timed out |
@bors retry Only a single runner timed out. The rest passed. |
☀️ Test successful - checks-actions |
Reopening PR #77486
Fixes #77355
This pass optimizes the following sequence
into