-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Shrink from_raw_parts
's MIR so that Vec::deref
MIR-inlines again
#123190
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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.