-
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
UnreachableProp: Preserve unreachable branches for multiple targets #99762
Conversation
r? @oli-obk (rust-highfive has picked a reviewer for you, use r? to override) |
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
abc735d
to
4e6a828
Compare
This comment has been minimized.
This comment has been minimized.
4e6a828
to
7eaab22
Compare
Isn't the issue that it becomes And if that's indeed the problem, we could theoretically encode |
@eddyb agreed, especially because |
7eaab22
to
b100b4d
Compare
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit b100b4de35c0f64b160da79c678e3719281ca810 with merge a7fcf124a326d3a6b66d44389da7b1b49d5493ac... |
☀️ Try build successful - checks-actions |
Queued a7fcf124a326d3a6b66d44389da7b1b49d5493ac with parent c9b3183, future comparison URL. |
Finished benchmarking commit (a7fcf124a326d3a6b66d44389da7b1b49d5493ac): comparison url. Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results
CyclesResults
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Footnotes |
That's not bad, but also not great. I could try to also look at |
We shouldn't special case the intrinsic in this pass - we should instead add it to the lower intrinsics pass we have already (if it's not in there) |
The lower intrinsics pass does indeed lower unreachable already, so no improvements can be made there (assuming it runs before this pass, which it probably does). |
// } | ||
// | ||
// This generates a `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]`, which allows us or LLVM to | ||
// turn it into just `x` later. Without the unreachable, such a transformation would be illegal. |
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 statement is only true because we don't have enough range information available, right?
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.
(Also: please add a codegen test showing this opt)
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.
src/test/codegen/match-optimizes-away.rs
is the test for this, and found this issue in the opt originally. And this doesn't necessarily have to do with range information only, it could also be an unreachable_unchecked
the user wrote themselves to enable another optimization. Deleting unreachable branches like this just isn't a good idea because it loses information.
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 statement is only true because we don't have enough range information available, right?
Potentially, but IMO it's a bad idea to turn this:
match x {
Enum::A => 1,
Enum::B => 2,
Enum::C => 3,
// Not in the user's code, but added for switchInt's "otherwise" target:
// _ => unreachable_unchecked(),
}
into:
match x {
Enum::A => 1,
Enum::B => 2,
_ => 3,
}
It's erasing the refinement that the third case is only reachable when x
is Enum::C
.
You can recompute this refinement with an analysis, but why erase it in the first place?
See also #99762 (comment) where I suggest a solution (make otherwise
optional).
b100b4d
to
6ec07a8
Compare
And the merge conflicts are fixed |
☔ The latest upstream changes (presumably #100087) made this pull request unmergeable. Please resolve the merge conflicts. |
6ec07a8
to
ace7e18
Compare
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit ace7e18a3e510b6e9851f073a64701ae63cc568c with merge 8a6fa0c7e08655ea76a5f9071ddeccf6ebe68ec2... |
☀️ Try build successful - checks-actions |
Queued 8a6fa0c7e08655ea76a5f9071ddeccf6ebe68ec2 with parent f03ce30, future comparison URL. |
Finished benchmarking commit (8a6fa0c7e08655ea76a5f9071ddeccf6ebe68ec2): comparison url. Instruction count
Max RSS (memory usage)Results
CyclesThis benchmark run did not return any relevant results for this metric. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Footnotes |
Before, UnreachablePropagation removed all unreachable branches. This was a pessimization, as it removed information about reachability that was used later in the optimization pipeline. For example, this code ```rust pub enum Two { A, B } pub fn identity(x: Two) -> Two { match x { Two::A => Two::A, Two::B => Two::B, } } ``` basically has `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]` for the match. This allows it to be transformed into a simple `x`. If we remove the unreachable branch, the transformation becomes illegal.
It was disabled because of pathological behaviour of LLVM in some benchmarks. As of rust-lang#77680, this has been fixed. The problem there was that it caused pessimizations in some cases. These have now been fixed as well.
ace7e18
to
18bfcd3
Compare
curious ctfe stress test regression.
seems ok to me, but weird that it doesn't show up in the details of perfbots webpage. |
@bors r+ |
☀️ Test successful - checks-actions |
Finished benchmarking commit (015a824): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Footnotes |
TerminatorKind::Unreachable | ||
} else if is_unreachable(otherwise) { | ||
// If there are multiple targets, don't delete unreachable branches (like an unreachable otherwise) | ||
// unless otherwise is unrachable, in which case deleting a normal branch causes it to be merged with |
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.
*unreachable
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.
Before, UnreachablePropagation removed all unreachable branches. This was a pessimization, as it removed information about reachability that was used later in the optimization pipeline.
For example, this code
basically has
switchInt() -> [0: 0, 1: 1, otherwise: unreachable]
for the match. This allows it to be transformed into a simplex
. If we remove the unreachable branch, the transformation becomes illegal.This was the problem keeping
UnreachablePropagation
from being enabled, so we can enable it now.Something similar already happened in #77800, but it did not show a perf improvement there. Let's try it again anyways!
Fixes #68105, although that issue has been fixed for a long time (see #77680).