-
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 pass to optimize if
conditions on integrals to switches on the integer
#75370
New pass to optimize if
conditions on integrals to switches on the integer
#75370
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @oli-obk (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
- // + literal: Const { ty: u32, val: Value(Scalar(0x00000015)) } | ||
- StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:42:21: 42:22 | ||
- switchInt(_4) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/if-condition-int.rs:42:12: 46:6 | ||
+ switchInt(move _5) -> [21_u32: bb3, otherwise: bb4]; // scope 0 at $DIR/if-condition-int.rs:42:12: 46:6 |
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.
A further optimization would be to fold the targets of this switch into the terminator of bb0. That could be a separate PR though?
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, please leave it to a separate PR
I'm amazed this didn't touch any other tests. Let's see what the effect of this optimization has on perf, I think it should save us from doing this dance in LLVM everywhere. @bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit e80c2609f5619e9b06f0f18864c60fc507578ce1 with merge 1aa291e337fc2d554250e6d7160484f473e4e131... |
☀️ Try build successful - checks-actions, checks-azure |
Queued 1aa291e337fc2d554250e6d7160484f473e4e131 with parent 441fd22, future comparison URL. |
Finished benchmarking try commit (1aa291e337fc2d554250e6d7160484f473e4e131): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
looks like many smaller (< 1%) improvements. Not sure what's up with |
e80c260
to
a53a2b8
Compare
@oli-obk Fixed all but your comment about moving the match to a function, which I didn't understand. Can you expand on that? |
a53a2b8
to
97eb1c2
Compare
I have fixed everything pointed out in the review, but the scalar_to_u128 function, which I don't know how to resolve, help needed. |
}; | ||
|
||
// delete comparison statement | ||
bb.statements.remove(opt.bin_op_stmt_idx); |
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.
Make sure that previous SwitchInt used move operand before removing the comparison statement, since it might be used in other place:
pub fn f(a: i8) -> i32 {
let b = a == 17;
match b {
false => 10 + b as i32,
true => 100 + b as i32,
}
}
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.
Thanks, fixed this and added test for it. Interestingly enough, looking at the opt-diffs, the value being switched on is not being moved into the switch even if it is not being used later on. Is that a bug?
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.
Yea, we may be able to fix MIR building here to use a move instead of a copy, but let's do that in a separate PR
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 created issue #75993 to track fixing MIR building
97eb1c2
to
7c6d7f3
Compare
Hi @oli-obk To resolve @tmiasko 's comment about not removing the comparison statement (Eq/Ne), I only remove it if the place of comparison result is being moved into the switchInt. That does leave the comparison undeleted in e.g. https://github.com/rust-lang/rust/pull/75370/files#diff-6577b789c4b8ff0d4a014be7009d43afR14 . Is it a problem that my current optimization actually leaves the MIR in a place where _3 is being moved twice? If it is indeed a problem, I suggest either
What do you think? |
PR failed probably because MIR comments are being removed. I will rebase on master when @oli-obk have had time to review my latest commits |
We haven't really specified the semantics yet, but I believe we'll want to enforce that you can't move things twice some time in the future. One thing you could do is to replace the moves with copies and then leave any further cleanups to later mir optimizations |
This is now implemented in the latest commit |
Thanks! It looks like CI is failing now due to a change in our mir printing. Please rebase again and rebless the tests (for 32 bit and 64 bit both). @bors delegate+ You can now |
✌️ @simonvandel can now approve this pull request |
c8d92ef
to
1073901
Compare
Rebased, squashed and CI green. |
📌 Commit 10739016390affa75934f12bb876a85fa57d2500 has been approved by |
⌛ Testing commit 10739016390affa75934f12bb876a85fa57d2500 with merge 765fa323886208e51383cdb65b45931d74ff5b11... |
💔 Test failed - checks-actions |
1073901
to
23dda1b
Compare
Tests failed in the noopt tester that expected CheckedAdd in the MIR output instead of Add. I added |
📌 Commit 23dda1b has been approved by |
☀️ Test successful - checks-actions, checks-azure |
FWIW, this change is actually non-canonical, and LLVM will undo it (replace the switch with an icmp+br). |
Fixes #75144
Pass to convert
if
conditions on integrals into switches on the integral.For an example, it turns something like
into: