-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Shrink from_raw_parts
's MIR so that Vec::deref
MIR-inlines again
#123190
Conversation
This comment has been minimized.
This comment has been minimized.
fcea56f
to
3e4a577
Compare
This comment has been minimized.
This comment has been minimized.
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.
The new MIR looks a lot nicer; the previous MIR I think had a lot of union juggling that we don't have a MIR opt to clean up. The codegen test here demonstrates the improvement to inlining but can you post the before and after Vec::deref so everyone can see?
Hm, I'm not happy with making our libcore a tangled mess just to get the MIR a bit nicer. That's a maintenance nightmare... |
🤷 I'm leaving that decision up to libs. It's possible to get the inlining here by other means, but I'm not sure what MIR optimizations are required to clean up |
a3bb26f
to
e27ce30
Compare
I've pushed a rearrangement of things to attempt to address the "tangled mess" concerns. There's now a (non-exported) The resulting diffs outside the new module, such as pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
- from_raw_parts(data.cast(), len)
+ internal_repr::from_raw_parts(data, len)
} seem entirely fine to me. Like the previous iteration, there's no more need for Personally I rather like it, since it lets stuff elsewhere in the library keep using the pointers they already have, rather than needing to cast them or wrap/unwrap them. (For all that an extra |
This comment has been minimized.
This comment has been minimized.
#122975 means that what you see below is very different from the previous nightly, but that change on its own isn't enough to get Before this PR, with adding bb0: {
StorageLive(_4);
StorageLive(_2);
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
StorageLive(_3);
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
_4 = (_3.0: *const u8);
StorageDead(_3);
StorageDead(_2);
StorageLive(_5);
_5 = ((*_1).1: usize);
StorageLive(_6);
_6 = _4 as *const () (PtrToPtr);
StorageLive(_8);
StorageLive(_7);
_7 = std::ptr::metadata::PtrComponents::<[u8]> { data_pointer: _6, metadata: _5 };
_8 = std::ptr::metadata::PtrRepr::<[u8]> { const_ptr: move _7 };
StorageDead(_7);
_9 = (_8.0: *const [u8]);
StorageDead(_8);
StorageDead(_6);
StorageDead(_5);
StorageDead(_4);
_0 = &(*_9);
return;
} After this PR: bb0: {
StorageLive(_4);
StorageLive(_2);
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
StorageLive(_3);
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
_4 = (_3.0: *const u8);
StorageDead(_3);
StorageDead(_2);
StorageLive(_5);
_5 = ((*_1).1: usize);
StorageLive(_6);
_6 = std::ptr::internal_repr::PtrComponents::<*const u8, usize> { data_pointer: _4, metadata: _5 };
_7 = move _6 as *const [u8] (Transmute);
StorageDead(_6);
StorageDead(_5);
StorageDead(_4);
_0 = &(*_7);
return;
} After the post-inlining simplifications the difference is just that one less cast and a |
e27ce30
to
013c383
Compare
Should we have a pass that turns transmute-via-union into a transmute statement? |
I'd love to have a real InstCombine pass that can easily look at multiple statements at once. Any progress on one since #105808? |
Not from me. Anyone can resurrect the general strategy in that PR, so long as they have a fix for the storage liveness issue @cjgillot pointed out. It's somewhere in the PR comments, I can't load the page right now to find it. |
Taking a step back, we may need to rethink how we create and use wide pointers in MIR. I wonder if we should go towards:
The fact that Vec::deref would look something like:
Bonus: this may allow to simplify slice construction, as current GVN is unable to understand the union dance. |
It doesn't make much sense to have slice construction implemented in the library like it is now. I'm pretty sure |
☔ The latest upstream changes (presumably #123484) made this pull request unmergeable. Please resolve the merge conflicts. |
Closing in favour of #123840 |
…gillot Add an intrinsic for `ptr::from_raw_parts(_mut)` Fixes rust-lang#123174 cc `@CAD97` `@saethlin` r? `@cjgillot` As suggested in rust-lang#123190 (comment), this adds a new `AggregateKind::RawPtr` for creating a pointer from its data pointer and its metadata. That means that `slice::from_raw_parts` and friends no longer need to hard-code pointer layout into `libcore`, and because it no longer does union hacks the MIR is shorter and more amenable to optimizations.
…cjgillot Add an intrinsic for `ptr::from_raw_parts(_mut)` Fixes rust-lang#123174 cc `@CAD97` `@saethlin` r? `@cjgillot` As suggested in rust-lang#123190 (comment), this adds a new `AggregateKind::RawPtr` for creating a pointer from its data pointer and its metadata. That means that `slice::from_raw_parts` and friends no longer need to hard-code pointer layout into `libcore`, and because it no longer does union hacks the MIR is shorter and more amenable to optimizations.
…cjgillot Add an intrinsic for `ptr::from_raw_parts(_mut)` Fixes rust-lang#123174 cc `@CAD97` `@saethlin` r? `@cjgillot` As suggested in rust-lang#123190 (comment), this adds a new `AggregateKind::RawPtr` for creating a pointer from its data pointer and its metadata. That means that `slice::from_raw_parts` and friends no longer need to hard-code pointer layout into `libcore`, and because it no longer does union hacks the MIR is shorter and more amenable to optimizations.
Rollup merge of rust-lang#123840 - scottmcm:aggregate-kind-rawptr, r=cjgillot Add an intrinsic for `ptr::from_raw_parts(_mut)` Fixes rust-lang#123174 cc `@CAD97` `@saethlin` r? `@cjgillot` As suggested in rust-lang#123190 (comment), this adds a new `AggregateKind::RawPtr` for creating a pointer from its data pointer and its metadata. That means that `slice::from_raw_parts` and friends no longer need to hard-code pointer layout into `libcore`, and because it no longer does union hacks the MIR is shorter and more amenable to optimizations.
Fixes #123174
cc @CAD97
Two commits; the first adds the codegen test so that you can see the diff clearly in the second commit.