Mark more locals as moved to avoid building drops for them.#158281
Mark more locals as moved to avoid building drops for them.#158281cjgillot wants to merge 3 commits into
Conversation
|
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
|
r? @JohnTitor rustbot has assigned @JohnTitor. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
Does this have user-visible behavior changes? e.g., see #156713 |
|
Yes. With this change, both cases in #156713 pass. We also have a few user-visible consequences with the drop order lint. |
|
@rustbot reroll |
51861b3 to
d128dba
Compare
This comment has been minimized.
This comment has been minimized.
a5dd21c to
4ff8c26
Compare
This comment has been minimized.
This comment has been minimized.
4ff8c26 to
90e4893
Compare
This comment has been minimized.
This comment has been minimized.
90e4893 to
a851b9e
Compare
This comment has been minimized.
This comment has been minimized.
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Mark more locals as moved to avoid building drops for them.
|
Since this PR has insta-stable changes, I think this will need to go through an FCP. Could you describe what the user-facing changes are, and lang-nominate the PR? |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (9ef0dc4): comparison URL. Overall result: ❌✅ regressions and improvements - please read:Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf. Next, please: If you can, justify the regressions found in this try perf run in writing along with @bors rollup=never Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary -1.2%, secondary 0.6%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 4.5%, secondary 75.6%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (primary 0.0%, secondary 0.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 488.761s -> 487.76s (-0.20%) |
a851b9e to
650bed1
Compare
This comment has been minimized.
This comment has been minimized.
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Mark more locals as moved to avoid building drops for them.
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (68a2829): comparison URL. Overall result: ❌✅ regressions and improvements - please read:Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf. Next, please: If you can, justify the regressions found in this try perf run in writing along with @bors rollup=never Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary 1.7%, secondary 2.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary 6.5%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 489.809s -> 489.874s (0.01%) |
This comment has been minimized.
This comment has been minimized.
And some more cases along the way. We have a specific optimization to avoid generating useless drops, use it. In particular, aggregate construction are very similar to function calls for which this is designed.
650bed1 to
e8296a0
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
| // look for moves of a local variable, like `MOVE(_X)` | ||
| let locals_moved = operands.iter().flat_map(|operand| match operand.node { | ||
| let local_moved = match operand { | ||
| Operand::Copy(_) | Operand::Constant(_) | Operand::RuntimeChecks(_) => None, | ||
| Operand::Move(place) => place.as_local(), | ||
| }); | ||
| }; | ||
|
|
||
| for local in locals_moved { | ||
| if let Some(local) = local_moved { | ||
| // check if we have a Drop for this operand and -- if so | ||
| // -- add it to the list of moved operands. Note that this | ||
| // local might not have been an operand created for this | ||
| // call, it could come from other places too. | ||
| if scope.drops.iter().any(|drop| drop.local == local && drop.kind == DropKind::Value) { | ||
| scope.moved_locals.push(local); | ||
| } | ||
| scope.moved_locals.insert(local); | ||
| } |
There was a problem hiding this comment.
Nit: it looks like these matches could be combined.
Also, could you update the comments?
| //! Regression test for issue #156713. In the `fails` case, borrowck was trying to check liveness | ||
| //! of `bar` which had been moved to a match scrutinee. |
There was a problem hiding this comment.
I think it's slightly subtler than this: as I understand it, the problem with fails was the unwind edge from the drop of the operand of the tuple constructor. Since borrowck doesn't ignore dead unwind edges and the drop order on the unwind path from that was bad (it dropped foo before the match scrutinee temporary), we got an error.
| // This compiles | ||
| fn works() { | ||
| let foo = Foo; | ||
| let bar = Bar(&foo); | ||
| drop(match { (bar,) } { | ||
| args => args, | ||
| }) | ||
| } |
There was a problem hiding this comment.
Maybe a nit, but I'm not sure works fits as a test here. As I understand, the reason it compiled successfully before this PR is a longstanding MIR building bug: #47949 made it so the unwind path from the drop of the operand to the tuple constructor was missing the drop of the match scrutinee temporary, meaning there was no error from the match scrutinee being dropped after foo.
Having a test means we'll make sure it still works after #47949 is fixed, but then it feels like a more specific version of fails.
View all comments
MIR building skips generating drops for moved-from locals in the topmost scope. This was only used for call terminators, but can be generalized to many other moves. This PR generalizes this to aggregate construction and many other assignments.
This avoids generating drops that would then be removed by drop elaboration.
This PR changes borrowck behaviour: some programs that were rejected are now accepted, see the last commit. That particular case was wrongly rejected.
Fixes #156713
Based on #158279 to remove a lint false-positive