Skip to content
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

We don't need NonNull::as_ptr debuginfo #133899

Merged
merged 1 commit into from
Dec 13, 2024

Conversation

scottmcm
Copy link
Member

@scottmcm scottmcm commented Dec 5, 2024

In order to stop pessimizing the use of local variables in core, skip debug info for MIR temporaries in tiny (single-BB) functions.

For functions as simple as this -- Pin::new, etc -- nobody every actually wants debuginfo for them in the first place. They're more like intrinsics than real functions, and stepping over them is good.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 5, 2024
@scottmcm
Copy link
Member Author

scottmcm commented Dec 5, 2024

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Dec 5, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 5, 2024
[EXPERIMENT] We don't need `NonNull::as_ptr` debuginfo

Stop pessimizing the use of local variables in core by skipping debug info for MIR temporaries in tiny (single-BB) functions.

For functions as simple as this -- `Pin::new`, etc -- nobody every actually wants debuginfo for them in the first place.  They're more like intrinsics than real functions, and stepping over them is good.

r? ghost
@bors
Copy link
Contributor

bors commented Dec 5, 2024

⌛ Trying commit 49b1b09 with merge fe36381...

@fmease
Copy link
Member

fmease commented Dec 5, 2024

sync @bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 5, 2024
@bors
Copy link
Contributor

bors commented Dec 5, 2024

☀️ Try build successful - checks-actions
Build commit: fe36381 (fe36381f279b8d83a2a75289c291c8962f09421f)

@rust-timer

This comment has been minimized.

@fmease fmease added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 5, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (fe36381): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

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.

Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please fix the regressions and do another perf run. If the next run shows neutral or positive results, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

This is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.

mean range count
Regressions ❌
(primary)
0.9% [0.9%, 0.9%] 1
Regressions ❌
(secondary)
0.4% [0.2%, 1.2%] 6
Improvements ✅
(primary)
-1.0% [-2.2%, -0.1%] 35
Improvements ✅
(secondary)
-3.0% [-3.2%, -2.7%] 2
All ❌✅ (primary) -0.9% [-2.2%, 0.9%] 36

Max RSS (memory usage)

Results (primary -2.3%, secondary -3.4%)

This 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.

mean range count
Regressions ❌
(primary)
1.9% [1.2%, 2.6%] 3
Regressions ❌
(secondary)
2.9% [2.9%, 2.9%] 1
Improvements ✅
(primary)
-3.5% [-7.2%, -0.7%] 10
Improvements ✅
(secondary)
-6.5% [-8.0%, -4.9%] 2
All ❌✅ (primary) -2.3% [-7.2%, 2.6%] 13

Cycles

Results (primary -1.3%, secondary -1.3%)

This 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.

mean range count
Regressions ❌
(primary)
1.1% [1.1%, 1.1%] 1
Regressions ❌
(secondary)
1.8% [1.8%, 1.8%] 1
Improvements ✅
(primary)
-1.6% [-2.4%, -1.0%] 9
Improvements ✅
(secondary)
-2.8% [-3.5%, -2.1%] 2
All ❌✅ (primary) -1.3% [-2.4%, 1.1%] 10

Binary size

Results (primary -1.4%, secondary -0.8%)

This 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.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-1.4% [-6.0%, -0.0%] 90
Improvements ✅
(secondary)
-0.8% [-6.6%, -0.0%] 44
All ❌✅ (primary) -1.4% [-6.0%, -0.0%] 90

Bootstrap: 768.023s -> 767.749s (-0.04%)
Artifact size: 330.84 MiB -> 330.73 MiB (-0.03%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Dec 5, 2024
@scottmcm scottmcm marked this pull request as ready for review December 5, 2024 16:19
@rustbot
Copy link
Collaborator

rustbot commented Dec 5, 2024

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@scottmcm
Copy link
Member Author

scottmcm commented Dec 5, 2024

Oh, I'm quite happy with those perf results :) 560,934 bytes off hyper-debug.

r? mir

@scottmcm scottmcm changed the title [EXPERIMENT] We don't need NonNull::as_ptr debuginfo We don't need NonNull::as_ptr debuginfo Dec 5, 2024
@Kobzol
Copy link
Contributor

Kobzol commented Dec 5, 2024

The (especially binary size) wins look awesome! Just thinking out loud, I wonder if there's a way to evaluate the debugging impact of these changes though? I noticed that in recent Rust versions debugging stepping regressed for me, with stepping over (a line without await) suddenly starting to jump into some assembly instructions or going inside functions unnecessarily.

@scottmcm
Copy link
Member Author

scottmcm commented Dec 5, 2024

My saying "strip" here might have made it sound like it's doing more than it is.

The following are unchanged, and should continue to work exactly as before:

  • Anything in your own code, as this behaviour is only enabled while building the sysroot (core+alloc+std)
  • Anything related to line/column information about the execution, because this still preserves all the spans of the statements in the function
  • When you step into a core function that loops, you can still debug that loop, since any function with more than one basic block will be unchanged by this PR.
  • When you step into a core function from your own code, looking at the values of the parameters to the function will still work, as this always leaves that debuginfo intact as well

What doesn't work:

  • When you've stepped into a core function, looking at the values of local variables that are not parameters
  • If you step into a core function from another core function (like stepping into Pin::new_unchecked from Pin::new), you might not be able to see the value of the sub-function's parameters.

For a specific example, my argument is that while it's true that there's a local in NonNull::dangling

pub const fn dangling() -> Self {
// SAFETY: ptr::dangling_mut() returns a non-null well-aligned pointer.
unsafe {
let ptr = crate::ptr::dangling_mut::<T>();
NonNull::new_unchecked(ptr)
}
}

I don't think anyone's ever cared about that in the debuginfo, since it's a trivial straight-line function (even though we do have six inlined function call scopes in it today).

@Kobzol
Copy link
Contributor

Kobzol commented Dec 5, 2024

I see, thanks for clarifying! That makes sense, I agree that this kind of local variable debuginfo is not very useful. In fact, I think that it would be nice if we had a way to skip generating such information for all libraries that a crate depends on, to improve compile times and reduce binary size of debug builds, as these are relatively rarely needed for actual stepping (as opposed to the user's own code). But that's a separate discussion.

@@ -16,7 +16,6 @@
+ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new) {
+ debug pointer => _3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this one also be gone? Pin::new (after inlining the function call in its body and stripping debug info) is just the same as Pin::new_unchecked, but its debug info seems to stay around.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pointer is the parameter to Pin::new, so it's not removed

pub const fn new(pointer: Ptr) -> Pin<Ptr> {

(Rather than if it were a local in the function)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But isn't the same true for the pointer arg of new_unchecked?

Ah, if the currently-being-optimized function were in libcore, the arg of new would also be gone...

Makes sense, but subtle

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, definitely subtle. We could be less subtle by just removing all the debuginfo from trivial functions, but I thought it would be worth allowing at least that outer bit so that if you're unsure what you're calling into core with, that first step in having those arguments visible seemed potentially useful.

Basically I'm trying to make as small a change as I can while still avoiding the bad incentive of local variables in core making the compiler slower.

@scottmcm scottmcm added the perf-regression-triaged The performance regression has been triaged. label Dec 9, 2024
@oli-obk
Copy link
Contributor

oli-obk commented Dec 9, 2024

@bors r+

@bors
Copy link
Contributor

bors commented Dec 9, 2024

📌 Commit 49b1b09 has been approved by oli-obk

It is now in the queue for this repository.

@ChrisDenton ChrisDenton added CI-spurious-fail-mingw CI spurious failure: target env mingw and removed CI-spurious-fail-msvc CI spurious failure: target env msvc labels Dec 11, 2024
@scottmcm
Copy link
Member Author

Ok, failure was spurious, so back into the queue.
@bors r=oli-obk

@bors
Copy link
Contributor

bors commented Dec 11, 2024

📌 Commit a7fc76a has been approved by oli-obk

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 11, 2024
@jyn514
Copy link
Member

jyn514 commented Dec 12, 2024

In fact, I think that it would be nice if we had a way to skip generating such information for all libraries that a crate depends on, to improve compile times and reduce binary size of debug builds, as these are relatively rarely needed for actual stepping (as opposed to the user's own code)

FWIW i use a debugger on rust binaries somewhat frequently and almost always i’m doing so because one of my dependencies does something i don’t understand or expect. so removing that debuginfo would make my life harder.

if you intend this to be the default for profile = dev that seems ok. but i really would want it to have an opt-out.

@jyn514
Copy link
Member

jyn514 commented Dec 12, 2024

i think you could solve the problem you’re talking about more directly if gdb/lldb had a command for “never step into functions defined in this crate”. maybe that already exists today, i’m not sure.

@Kobzol
Copy link
Contributor

Kobzol commented Dec 12, 2024

I meant it as the opposite, i.e. by default build all debuginfo, but have an opt-in mechanism to skip debuginfo of dependencies.

@jyn514
Copy link
Member

jyn514 commented Dec 12, 2024

I meant it as the opposite, i.e. by default build all debuginfo, but have an opt-in mechanism to skip debuginfo of dependencies.

you can already do this today, no?

[profile.release]
debug = true

// disable debug symbols for all packages except this one
[profile.release.package."*"]
debug = false

@jyn514
Copy link
Member

jyn514 commented Dec 12, 2024

i think you could solve the problem you’re talking about more directly if gdb/lldb had a command for “never step into functions defined in this crate”. maybe that already exists today, i’m not sure.

yeah here we go: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Skipping-Over-Functions-and-Files.html
we could set this by default in rust-gdb so it skips "uninteresting" frames.

@Kobzol
Copy link
Contributor

Kobzol commented Dec 12, 2024

I meant it as the opposite, i.e. by default build all debuginfo, but have an opt-in mechanism to skip debuginfo of dependencies.

you can already do this today, no?

[profile.release]
debug = true

// disable debug symbols for all packages except this one
[profile.release.package."*"]
debug = false

Ah, I forgot about this, good point!

yeah here we go: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Skipping-Over-Functions-and-Files.html
we could set this by default in rust-gdb so it skips "uninteresting" frames.

Yeah, that's useful, I think I used this in the IJ Rust plugin when implementing an option to skip stepping through stdlib sources. Hard to say which functions to mark as being auto skippable though.

bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 13, 2024
We don't need `NonNull::as_ptr` debuginfo

In order to stop pessimizing the use of local variables in core, skip debug info for MIR temporaries in tiny (single-BB) functions.

For functions as simple as this -- `Pin::new`, etc -- nobody every actually wants debuginfo for them in the first place.  They're more like intrinsics than real functions, and stepping over them is good.
@bors
Copy link
Contributor

bors commented Dec 13, 2024

⌛ Testing commit a7fc76a with merge 7a5dab9...

@rust-log-analyzer
Copy link
Collaborator

The job i686-mingw failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bors
Copy link
Contributor

bors commented Dec 13, 2024

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Dec 13, 2024
@scottmcm
Copy link
Member Author

That job just passed in test-with-try above #133899 (comment) so sounds spurious again :/

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 13, 2024
@bors
Copy link
Contributor

bors commented Dec 13, 2024

⌛ Testing commit a7fc76a with merge dd436ae...

@bors
Copy link
Contributor

bors commented Dec 13, 2024

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing dd436ae to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Dec 13, 2024
@bors bors merged commit dd436ae into rust-lang:master Dec 13, 2024
7 checks passed
@rustbot rustbot added this to the 1.85.0 milestone Dec 13, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (dd436ae): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Our benchmarks found a performance regression caused by this PR.
This might be an actual regression, but it can also be just noise.

Next Steps:

  • If the regression was expected or you think it can be justified,
    please write a comment with sufficient written justification, and add
    @rustbot label: +perf-regression-triaged to it, to mark the regression as triaged.
  • If you think that you know of a way to resolve the regression, try to create
    a new PR with a fix for the regression.
  • If you do not understand the regression or you think that it is just noise,
    you can ask the @rust-lang/wg-compiler-performance working group for help (members of this group
    were already notified of this PR).

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

This is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.

mean range count
Regressions ❌
(primary)
0.6% [0.2%, 0.9%] 2
Regressions ❌
(secondary)
0.5% [0.2%, 1.1%] 4
Improvements ✅
(primary)
-0.9% [-2.1%, -0.3%] 34
Improvements ✅
(secondary)
-2.7% [-3.0%, -2.5%] 2
All ❌✅ (primary) -0.9% [-2.1%, 0.9%] 36

Max RSS (memory usage)

Results (primary -2.3%, secondary -4.7%)

This 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.

mean range count
Regressions ❌
(primary)
2.1% [1.0%, 3.2%] 2
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-3.3% [-7.0%, -0.9%] 9
Improvements ✅
(secondary)
-4.7% [-7.9%, -2.3%] 3
All ❌✅ (primary) -2.3% [-7.0%, 3.2%] 11

Cycles

Results (primary -1.2%, secondary -2.4%)

This 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.

mean range count
Regressions ❌
(primary)
1.1% [1.1%, 1.1%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-1.4% [-2.3%, -0.8%] 11
Improvements ✅
(secondary)
-2.4% [-2.9%, -1.9%] 2
All ❌✅ (primary) -1.2% [-2.3%, 1.1%] 12

Binary size

Results (primary -1.3%, secondary -0.9%)

This 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.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-1.3% [-6.1%, -0.0%] 93
Improvements ✅
(secondary)
-0.9% [-6.6%, -0.0%] 36
All ❌✅ (primary) -1.3% [-6.1%, -0.0%] 93

Bootstrap: 769.59s -> 770.497s (0.12%)
Artifact size: 331.01 MiB -> 330.36 MiB (-0.20%)

@scottmcm scottmcm deleted the strip-mir-debuginfo branch December 14, 2024 02:10
@Kobzol
Copy link
Contributor

Kobzol commented Dec 23, 2024

More improvements than regressions, and in particular very nice binary size wins.

@rustbot label: +perf-regression-triaged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI-spurious-fail-mingw CI spurious failure: target env mingw merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.