-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Exhaustiveness: track overlapping ranges precisely #119396
Conversation
@bors try @rust-timer try |
…try> Experiment: track overlapping ranges precisely The `overlapping_range_endpoints` lint has false positives, e.g. rust-lang#117648. I expected that removing these false positives would have too much of a perf impact but never measured it. This PR is an experiment to see if the perf loss is manageable. r? `@ghost`
☀️ Try build successful - checks-actions |
@rust-timer queue |
This comment has been minimized.
This comment has been minimized.
3330ee9
to
80df6f9
Compare
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
…try> Experiment: track overlapping ranges precisely The `overlapping_range_endpoints` lint has false positives, e.g. rust-lang#117648. I expected that removing these false positives would have too much of a perf impact but never measured it. This PR is an experiment to see if the perf loss is manageable. r? `@ghost`
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (b58be7c): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking 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 Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
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.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 672.269s -> 668.673s (-0.53%) |
This actually looks like a very nice perf. win, |
I was not expecting a perf win wtf :D It seems running the lint separately is worse than this extra tracking I have to do |
80df6f9
to
2327f2e
Compare
Let's check I didn't break perf while cleaning up, and then this will be ready! @bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
…try> Experiment: track overlapping ranges precisely The `overlapping_range_endpoints` lint has false positives, e.g. rust-lang#117648. I expected that removing these false positives would have too much of a perf impact but never measured it. This PR is an experiment to see if the perf loss is manageable. r? `@ghost`
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (7ff489d): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking 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 Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
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.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 669.562s -> 667.015s (-0.38%) |
r? compiler @rustbot ready |
This comment was marked as off-topic.
This comment was marked as off-topic.
2327f2e
to
7931ee6
Compare
☔ The latest upstream changes (presumably #119688) made this pull request unmergeable. Please resolve the merge conflicts. |
7931ee6
to
a24f4db
Compare
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.
Not gonna lie, I only understand like a half of this 😅 I wish I had time to dive into pattern analysis more, but alas.
r=me, with/out nits
for mut new_row in row.expand_or_pat() { | ||
new_row.intersects = BitSet::new_empty(self.rows.len()); | ||
self.rows.push(new_row); | ||
} |
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.
IMO would be easier to read if it was written like
self
.rows
.extend(
row
.expand_or_pat()
.zip(self.rows.len()..)
.map(|(new_row, len)| Row { intersects: BitSet::new_empty(len), ..new_row })
);
(okay, not sure about the struct update syntax, but mutating the field here is slightly confusing) (also extend
ftw)
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 like that the two calls to push are copies of each other, makes it easier to track the invariant that the bitset always has the same length as the number of rows above this one.
cx: MatchCtxt<'a, 'p, 'tcx>, | ||
column: &PatternColumn<'p, 'tcx>, | ||
overlapping_range_endpoints: &mut Vec<rustc::OverlappingRanges<'p, 'tcx>>, |
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.
Do you think it would be a good idea to use a impl FnMut
or &mut dyn FnMut
here? I don't think lint_overlapping_range_endpoints
needs the whole collection allocated...
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.
Performance is irrelevant for this so it's a stylistic choice. I personally prefer to be computing data than calling callbacks in terms of code legibility. Otherwise I'd have made that a method on TypeCx I guess
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 it'll depend a lot of what's possible on the rust-analyzer side as well. If it fits in TypeCx on their side too I might change to that
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 don't know what I was thinking, you're quite right actually
@@ -125,7 +125,9 @@ pub fn analyze_match<'p, 'tcx>( | |||
let pat_column = PatternColumn::new(arms); | |||
|
|||
// Lint ranges that overlap on their endpoints, which is likely a mistake. | |||
lint_overlapping_range_endpoints(cx, &pat_column)?; | |||
if !report.overlapping_range_endpoints.is_empty() { |
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.
Is this if
important? lint_overlapping_range_endpoints
is just a for
loop, so for empty overlapping_range_endpoints
it will do nothing anyway...
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.
True but I have a general policy of helping both the reader and LLVM figure out that they can skip this most of the time
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.
Agreed that it's logically redundant
Thanks for the review! @bors r=WaffleLapkin |
☀️ Test successful - checks-actions |
Finished benchmarking commit (174e73a): comparison URL. Overall result: ✅ improvements - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
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.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 665.086s -> 669.852s (0.72%) |
…-errors Lint `overlapping_ranges_endpoints` directly instead of collecting into a Vec In rust-lang#119396 I was a bit silly: I was trying to avoid any lints being fired from within the exhaustiveness algorithm for some vague aesthetic/reusability reason that doesn't really hold. This PR fixes that: instead of passing a `&mut Vec` around I just added a method to the `TypeCx` trait. r? `@compiler-errors`
Rollup merge of rust-lang#120002 - Nadrieril:dont-collect, r=compiler-errors Lint `overlapping_ranges_endpoints` directly instead of collecting into a Vec In rust-lang#119396 I was a bit silly: I was trying to avoid any lints being fired from within the exhaustiveness algorithm for some vague aesthetic/reusability reason that doesn't really hold. This PR fixes that: instead of passing a `&mut Vec` around I just added a method to the `TypeCx` trait. r? `@compiler-errors`
The
overlapping_range_endpoints
lint has false positives, e.g. #117648. I expected that removing these false positives would have too much of a perf impact but never measured it. This PR is an experiment to see if the perf loss is manageable.r? @ghost