-
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
Preserve argument indexes when inlining MIR #109466
Preserve argument indexes when inlining MIR #109466
Conversation
r? @wesleywiser (rustbot has picked a reviewer for you, use r? to override) |
17a3e99
to
d45dae6
Compare
Great work @davidlattimore! 💯 Sorry for the delay in reviewing. @bors r+ |
📌 Commit d45dae666996f51afa6355168265666d7ed8a47d has been approved by It is now in the queue for this repository. |
⌛ Testing commit d45dae666996f51afa6355168265666d7ed8a47d with merge d660e8aee40cb06996960ecf2720939ede35a557... |
💔 Test failed - checks-actions |
This comment has been minimized.
This comment has been minimized.
Looks like it's breaking compilation of a particular async function in Tokio. Specifically some code in use std::future::Future;
pub fn poll_recv() {
let _: Box<dyn Future<Output = ()>> = Box::new(recv_unit());
}
async fn recv_unit() {
std::future::ready(()).await;
} This fails with:
Line 7 here is If I compile the same code with stable (1.68.2), I still see two local variables:
But here, the one with the name doesn't have an arg index set. The extra |
d45dae6
to
6c84ccb
Compare
I think I understand what's happening now.
We've got a few options for how to fix this:
Option 2 is simple (3 extra lines), but I don't really like it because it seems easy for something else to do the same thing (demote an argument to be not an argument). Option 3 I haven't tried writing yet, but it's plausible that creating VarDebugInfo instances without a name (or with an empty name) could have unintended side effects. Option 1 currently is my preferred option. Who doesn't like deleting code? For now, I've added a commit that goes with this option. I put it before the original commit. Affect on lldb of not emitting debug information for unnamed argumentsSuppose we have the following code fn foo((aaa, bbb): (i32, i32), ccc: i32) -> i32 {
aaa + bbb + ccc
} If we set a breakpoint inside
Without debug info for unnamed arguments, the first line goes away. This doesn't seem like a big loss to me - the information you want is still there in the variables with the names that user gave them - |
This comment has been minimized.
This comment has been minimized.
Looks like we do need to emit debug info for unnamed arguments, otherwise gdb doesn't include the argument types in the function signature. So just deleting that code isn't an option. I guess I'll go with one of the other options. |
6c84ccb
to
484bc35
Compare
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
Option 3 didn't really work out, so I went with option 2. A fourth option occurred to me in the process. We could change |
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.
Would you mind adding the minimal repro you found for the failure as another test in this PR? It would be good to make sure that is caught before perf.rlo runs.
We store argument indexes on VarDebugInfo. Unlike the previous method of relying on the variable index to know whether a variable is an argument, this survives MIR inlining. We also no longer check if var.source_info.scope is the outermost scope. When a function gets inlined, the arguments to the inner function will no longer be in the outermost scope. What we care about though is whether they were in the outermost scope prior to inlining, which we know by whether we assigned an argument index.
484bc35
to
a629267
Compare
Good idea, done. I confirmed that the added test fails without my change to |
Great work @davidlattimore! Thanks so much 😄 @bors r+ |
…debug-info, r=wesleywiser Preserve argument indexes when inlining MIR We store argument indexes on VarDebugInfo. Unlike the previous method of relying on the variable index to know whether a variable is an argument, this survives MIR inlining. We also no longer check if var.source_info.scope is the outermost scope. When a function gets inlined, the arguments to the inner function will no longer be in the outermost scope. What we care about though is whether they were in the outermost scope prior to inlining, which we know by whether we assigned an argument index. Fixes rust-lang#83217 I considered using `Option<NonZeroU16>` instead of `Option<u16>` to store the index. I didn't because `TypeFoldable` isn't implemented for `NonZeroU16` and because it looks like due to padding, it currently wouldn't make any difference. But I indexed from 1 anyway because (a) it'll make it easier if later it becomes worthwhile to use a `NonZeroU16` and because the arguments were previously indexed from 1, so it made for a smaller change. This is my first PR on rust-lang/rust, so apologies if I've gotten anything not quite right.
☀️ Test successful - checks-actions |
Finished benchmarking commit (d8fc819): 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.
|
We store argument indexes on VarDebugInfo. Unlike the previous method of relying on the variable index to know whether a variable is an argument, this survives MIR inlining.
We also no longer check if var.source_info.scope is the outermost scope. When a function gets inlined, the arguments to the inner function will no longer be in the outermost scope. What we care about though is whether they were in the outermost scope prior to inlining, which we know by whether we assigned an argument index.
Fixes #83217
I considered using
Option<NonZeroU16>
instead ofOption<u16>
to store the index. I didn't becauseTypeFoldable
isn't implemented forNonZeroU16
and because it looks like due to padding, it currently wouldn't make any difference. But I indexed from 1 anyway because (a) it'll make it easier if later it becomes worthwhile to use aNonZeroU16
and because the arguments were previously indexed from 1, so it made for a smaller change.This is my first PR on rust-lang/rust, so apologies if I've gotten anything not quite right.