-
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
At debuginfo=0, don't inline debuginfo when inlining #123949
At debuginfo=0, don't inline debuginfo when inlining #123949
Conversation
8f9e4a5
to
d4344e6
Compare
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
…o-when-inlined, r=<try> At debuginfo=0, don't inline debuginfo when inlining r? ghost
This comment has been minimized.
This comment has been minimized.
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (00b13bc): comparison URL. Overall result: ❌✅ regressions and improvements - 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. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @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 sizeResultsThis 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.
Bootstrap: 675.963s -> 672.737s (-0.48%) |
This comment has been minimized.
This comment has been minimized.
557265d
to
83f97a0
Compare
r? @cjgillot Notably, it makes a big difference in removing unnecessary things for common things like If you look at pub fn demo(x: &usize, y: &usize) -> bool {
x == y
} today, it keeps a whole bunch of unnecessary things in MIR https://rust.godbolt.org/z/Y6xjcn6fb fn demo(_1: &usize, _2: &usize) -> bool {
debug x => _1;
debug y => _2;
let mut _0: bool;
let mut _3: &&usize;
let mut _4: &&usize;
scope 1 (inlined std::cmp::impls::<impl PartialEq for &usize>::eq) {
debug self => _3;
debug other => _4;
let mut _5: &usize;
let mut _6: &usize;
scope 2 (inlined std::cmp::impls::<impl PartialEq for usize>::eq) {
debug self => _5;
debug other => _6;
let mut _7: usize;
let mut _8: usize;
}
}
bb0: {
StorageLive(_3);
_3 = &_1;
StorageLive(_4);
_4 = &_2;
StorageLive(_5);
StorageLive(_6);
_5 = _1;
_6 = _2;
StorageLive(_7);
_7 = (*_5);
StorageLive(_8);
_8 = (*_6);
_0 = Eq(move _7, move _8);
StorageDead(_8);
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageDead(_4);
StorageDead(_3);
return;
}
} In particular, those Similarly, changes like this are great because the scope 6 (inlined NonNull::<[u8]>::as_ptr) {
- debug self => _5;
let mut _12: *const [u8];
} helps reduce that extra cost of using helpers, to avoid the "should we just use But those locals are only kept around because of the debuginfo pointing at them. They're otherwise dead, and existing MIR optimizations know that. So this PR makes just one tiny change: when inlining things in MIR, don't inline the debuginfo into the caller if the caller is using But it doesn't remove all the debug info. The debuginfo for the original function is still kept, for example. It's only when inlining that it disappears. Which is hopefully a good tradeoff anyway, since if things are small enough to be inlined they're often not interesting to debug into anyway. But we also don't remove all the debug info, so there will still be some step-into-it debug info available if you inline a That'll hopefully help avoid the impact that ended up with me not figuring out how to land that previous PR. And it'll still address the main pain point of compiled-with-debuginfo-std keeping a bunch of unnecessary stuff when inlined into your release-without-debuginfo build -- and, as the perf run shows, saving a bunch of instructions and binary size as it does so. |
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
_6 = &mut _5; | ||
StorageLive(_12); | ||
StorageLive(_11); | ||
StorageLive(_7); | ||
_7 = &(_5.0: u32); | ||
StorageLive(_8); | ||
_8 = &(_5.1: u32); |
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.
These references are another good example -- nothing actually needed them other than the inlined debuginfo, so they just disappear entirely.
StorageLive(_2); | ||
_2 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind unreachable]; | ||
} | ||
|
||
bb1: { | ||
_3 = &_2; |
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.
Another nice concrete example: using Option::is_some
used to leave a reference to the option in the statements here, even though that was never used for anything.
scope 1 { | ||
} |
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 related to PR, but this empty scopes looks useless, is they needed?
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.
These empty ones that aren't from inlining do seem useless to me, but I don't know.
As you say, not this PR, so can you open an issue or a zulip thread about this? Cleaning up these scopes after SimplifyLocals
, or something, does seem like a reasonable option.
This is 4 lines of "real" code and 2000 lines of test updates, so |
…o-when-inlined, r=oli-obk At debuginfo=0, don't inline debuginfo when inlining See rust-lang#123949 (comment) for info.
This comment has been minimized.
This comment has been minimized.
💔 Test failed - checks-actions |
5d5b1d4
to
b8ac5c0
Compare
Rebased to pick up the @bors r=oli-obk,onur-ozkan |
☀️ Test successful - checks-actions |
Finished benchmarking commit (3412f01): comparison URL. Overall result: ❌✅ regressions and improvements - ACTION NEEDEDNext Steps: If you can justify the regressions found in this perf run, please indicate this with @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 sizeResultsThis 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.
Bootstrap: 676.731s -> 672.221s (-0.67%) |
Whee, finally... 🕺🏻 |
Seems like @oli-obk signed off on the perf regressions seen here since the improvements outweighed them. @rustbot label: +perf-regression-triaged |
.opts | ||
.unstable_opts | ||
.inline_mir_preserve_debug | ||
.unwrap_or(self.tcx.sess.opts.debuginfo != DebugInfo::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.
Why isn't this == DebugInfo::Full
? Isn't this current implementation retaining variable debuginfo when compiling with line-tables-only
?
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, it was always copied during inlining, so it at least shouldn't be a regression, right? And when the debuginfo is not set to generate variable debuginfo, shouldn't var_debug_info
be empty 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.
so it at least shouldn't be a regression, right?
Yeah, this ought not to be a regression, but I was reading this code and this condition is surprising.
And when the debuginfo is not set to generate variable debuginfo, shouldn't
var_debug_info
be empty anyway?
When we load optimized_mir
for the standard library, it should always have variable debuginfo.
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.
Oh, I see. So, I thought about familiarizing myself a bit with the debuginfo handling, I'll try to send a PR that improves this then.
See #123949 (comment) for info.