-
Notifications
You must be signed in to change notification settings - Fork 59
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
Place semantics of function parameters (optimizing pass-by-value) #429
Comments
For unsized values this is already effectively guaranteed to not copy. Copying unsized values when doing argument passing is not possible without unsized locals, which no backend other than the LLVM backend supports. |
Also there has been a lot of discussion about the semantics of calls before. |
If by value unsized parameters get (necessarily) passed in their existing place rather than a fresh one, that definitely pushes me towards thinking that temporary/call semantics should be such that sized values also have the option of place colocation. Although:
I'd expect this to be formalized along the lines of that a parameter of "kind" place is handled directly as a place (when the generic type is not In MIR termsCurrently, the MIR for _2: *const Data = ((((
_1: std::boxed::Box<Data>)
.0: std::ptr::Unique<Data>)
.0: std::ptr::NonNull<Data>)
.0: *const Data);
_3: Data = move (*_2);
_4: () = consume(move _3) -> [return: bb1, unwind: bb2]; Instead of introducing the temporary place _2: *const Data = ((((
_1: std::boxed::Box<Data>)
.0: std::ptr::Unique<Data>)
.0: std::ptr::NonNull<Data>)
.0: *const Data);
_4: () = consume(move (*_2)) -> [return: bb1, unwind: bb2]; This is, if I'm not mistaken, the MIR already produced for unsized parameters. Though somewhat interestingly, there seems to be a difference in how the box itself gets treated? (In the sized case, it's left in the argument place, but in the unsized case, it's If I hack this in with This has a somewhat unfortunate effect that extracting a temporary variable has a pessimizing effect, but when dealing with address stability/disjointedness, it's to be expected. ( I've been meaning to familiarize myself with big-picture how MIR is generated; perhaps I could experiment with making this change in MIR generation (but still gated behind Since it's on my mind, this would be another difference with how |
Related to (and potentially duplicate of) #416 and/or the other issues it trees out to. |
Yeah I think this is basically a duplicate of #416 and rust-lang/rust#71117. Should we close it as a duplicate? FWIW, I just opened rust-lang/rust#113569 which I think justifies the semantics you describe except for address identity issues. The MIR way of expressing this is awkward (I'm hoping to sketch a syntax better reflecting the semantics in MiniRust); basically if the argument is of the shape |
Yeah, I think between those what I was looking at here gets covered. The core question of "can we allow this" is answered and #416 serves fine to track the "do we" part. |
This ties into place/address uniqueness discussions.
Consider that we have some type
Data
which has pass-by-reference ABI and isn'tCopy
. We have code with the shape:Using
&move
to represent the ABI, this lowers to roughly look like:Optimized MIR
My question: would it be a valid optimization to remove the temporary place and instead directly call
consume(&move *data)
? [context]Reasons for:
Box
, is known to be uniquely accessible byfn entry
.Pin
involved, SHOULD be the case.Reasons against:
Obviously, being able to prove more about the code (i.e. that the address of one or the other place isn't observed) would permit this copy elision optimization. I'm specifically curious about the know-nothing case.
If we categorically forbid live places from (observably) having the same address, then I believe this optimization would indeed be incorrect. If we can't perform this optimization automatically, that could serve as partial motivation for the introduction of a surface level
&move
which would permit such (well-scoped) place colocation.(This is not the place to discuss the exact semantics of
&move
. Just to determine if something like&move
would be required to do this optimization of logical ownership transfer but concrete place reuse.)The text was updated successfully, but these errors were encountered: