Uh oh!
There was an error while loading. Please reload this page.
MIR: split Operand::Consume into Copy and Move. - #46142
Conversation
rust-highfive
commented
Nov 21, 2017
r? @arielb1 (rust_highfive has picked a reviewer for you, use r? to override) |
eddyb
commented
Nov 21, 2017
There was a problem hiding this comment.
Can we leave some comments explaining what these mean, in terms of the expectations they provide? I think something like this:
- Copy: The value must be available for use afterwards. This implies that the type of the lvalue must be
Copy; this is true by construction during build, but checked by the MIR type checker. - Move: The value will not be used again. Safe for values of all types (modulo future developments towards
?Move). Enforced by borrow checker. Sometimes Copy is converted to Move to enable "last-use" optimizations.
There was a problem hiding this comment.
Personally, I'd rather this exhaustive (and perhaps move the if on the arm above inside the arm. But I rate the probability of overlooking this match after some future change to Operand as fairly low, so it's not that important.
scottmcm
commented
Nov 21, 2017
FYI: If PR #46093 goes in first, I think it will conflict with this in a way that git won't notice. This line will need to become a Move: https://github.com/rust-lang/rust/pull/46093/files#diff-69bf2a484158ebf56322b7ffb03601cdR108 |
bors
commented
Nov 22, 2017
☔ The latest upstream changes (presumably #45879) made this pull request unmergeable. Please resolve the merge conflicts. |
nikomatsakis
commented
Nov 27, 2017
@bors r+ |
bors
commented
Nov 27, 2017
📌 Commit cd99774 has been approved by |
scottmcm
commented
Nov 27, 2017
Looks like this might be real? [00:19:46] error[E0599]: no associated item named `Consume` found for type `rustc::mir::Operand<'_>` in the current scope
[00:19:46] --> /checkout/src/librustc_mir/transform/add_moves_for_packed_drops.rs:135:34[00:19:46] |
[00:19:46]135 | Rvalue::Use(Operand::Consume(location.clone())));[00:19:46] | ^^^^^^^^^^^^^^^^ |
eddyb
commented
Nov 28, 2017
@bors r=nikomatsakis |
bors
commented
Nov 28, 2017
📌 Commit 56fb59c has been approved by |
bors
commented
Nov 28, 2017
☔ The latest upstream changes (presumably #46312) made this pull request unmergeable. Please resolve the merge conflicts. |
eddyb
commented
Nov 28, 2017
@bors r=nikomatsakis |
bors
commented
Nov 28, 2017
📌 Commit 919ed40 has been approved by |
bors
commented
Nov 28, 2017
MIR: split Operand::Consume into Copy and Move. By encoding the choice of leaving the source untouched (`Copy`) and invalidating it (`Move`) in MIR, we can express moves of copyable values and have MIR borrow-checking enforce them, *including* ownership transfer of stack locals in calls (when the ABI passes by indirection). Optimizations could turn a "last-use" `Copy` into a `Move`, and the MIR borrow-checker, at least within the confines of safe code, could even do this when the underlying lvalue was borrowed. (However, that last part would be the first time lifetime inference affects code generation, AFAIK). Furthermore, as `Move`s invalidate borrows as well, for any local that is initialized only once, we can ignore borrows that happened before a `Move` and safely reuse/replace its memory storage. This will allow us to perform NRVO in the presence of short-lived borrows, unlike LLVM (currently), and even compute optimal `StorageLive...StorageDead` ranges instead of discarding them.
rustc_mir: implement an "lvalue reuse" optimization (aka destination propagation aka NRVO). Replaces a chain of moves, such as `a = ...; ... b = move a; ... f(&mut b) ... c = move b`, with the final destination, i.e. only `c = ...; ... f(&mut c); ...` remains (note that borrowing is allowed). **DO NOT MERGE** only for testing atm. Based on #46142.
bors
commented
Nov 28, 2017
☀️ Test successful - status-appveyor, status-travis |
By encoding the choice of leaving the source untouched (
Copy) and invalidating it (Move) in MIR, we can express moves of copyable values and have MIR borrow-checking enforce them, including ownership transfer of stack locals in calls (when the ABI passes by indirection).Optimizations could turn a "last-use"
Copyinto aMove, and the MIR borrow-checker, at least within the confines of safe code, could even do this when the underlying lvalue was borrowed.(However, that last part would be the first time lifetime inference affects code generation, AFAIK).
Furthermore, as
Moves invalidate borrows as well, for any local that is initialized only once, we can ignore borrows that happened before aMoveand safely reuse/replace its memory storage.This will allow us to perform NRVO in the presence of short-lived borrows, unlike LLVM (currently), and even compute optimal
StorageLive...StorageDeadranges instead of discarding them.