-
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
Add range metadata to slice lengths #116542
base: master
Are you sure you want to change the base?
Conversation
r? @cjgillot (rustbot has picked a reviewer for you, use r? to override) |
Changes to the size of AST and/or HIR nodes. cc @nnethercote |
This comment has been minimized.
This comment has been minimized.
Note that doing this for raw slice pointers would be unsound, since slice_from_raw_parts is safe. So this PR must be introducing (for the first time) a difference in metadata validity for raw pointers vs references. Are we sure we want that? |
compiler/rustc_middle/src/ty/sty.rs
Outdated
| ty::RawPtr(..) | ||
| ty::Char | ||
| ty::Ref(..) | ||
| ty::Closure(..) => true, |
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.
Closure
could be a ZST I think, if the environment is empty.
compiler/rustc_middle/src/ty/sty.rs
Outdated
ty::Tuple(tys) => tys.iter().any(|ty| ty.is_trivially_non_zst(tcx)), | ||
ty::Adt(def, args) => def.all_fields().any(|field| { | ||
let ty = field.ty(tcx, args); | ||
ty.is_trivially_non_zst(tcx) |
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.
This is non-obvious and deserves a comment. It relies on Result<(), (!, i32)>
not removing the Err
variant entirely (which plausibly it could do due to it being uninhabited -- but that would also cause issues in MIR).
return Err(error(cx, LayoutError::Unknown(pointee))); | ||
}; | ||
|
||
if !ty.is_unsafe_ptr() { | ||
match pointee.kind() { | ||
ty::Slice(element) => { |
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.
So &[i32]
is getting the optimization but &(bool, [i32])
is not? That seems odd?
ty::Slice(element) => { | ||
let mut metadata = scalar_unit(Int(dl.ptr_sized_integer(), false)); | ||
if !ty.is_unsafe_ptr() && !element.is_trivially_non_zst(tcx) { | ||
metadata.valid_range_mut().end = dl.ptr_sized_integer().signed_max() as u128; |
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.
Why do we have this logic duplicated here?
I think the test failure indicates that I've already broken something because |
tests/ui/stats/hir-stats.rs
Outdated
@@ -1,7 +1,7 @@ | |||
// check-pass | |||
// compile-flags: -Zhir-stats | |||
// only-x86_64 | |||
|
|||
// ignore-stage1 |
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.
If this is needed temporarily, can you add a comment saying that?
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.
write this as a cfg(bootstrap) so that it gets picked up during the version bump
My approach probably is too naive. Apparently Though I'm a bit surprised that all the stage 2 UI/codegen/std tests pass and it "merely" fails in rustc_graphviz. |
Yes With your PR this means that |
Having Could we cheat by adding the annotation in codegen, on the code we generate for |
We don't necessarily need the full layout if we limit ourselves to adding an isize::MAX range annotation - computing more accurate, size-based ranges would require the layout - then we only need to know whether A is certainly ZST or non-ZST. since
Yeah, that's the fallback solution if I can't get this to work. It'll be simpler but lose the niches |
☔ The latest upstream changes (presumably #119258) made this pull request unmergeable. Please resolve the merge conflicts. |
f18bdd5
to
9fb9beb
Compare
This comment has been minimized.
This comment has been minimized.
9fb9beb
to
dc27f9d
Compare
This comment has been minimized.
This comment has been minimized.
dc27f9d
to
e47adf2
Compare
This comment has been minimized.
This comment has been minimized.
Back to a broken rustc_graphviz . I'm not sure how I'm breaking it. Maybe something about enum discriminants or about |
@the8472 any updates on this? thanks |
c0e2e89
to
f6c6fd2
Compare
This comment has been minimized.
This comment has been minimized.
f6c6fd2
to
907a078
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #131458) made this pull request unmergeable. Please resolve the merge conflicts. |
2b66bb6
to
d1794d3
Compare
This comment has been minimized.
This comment has been minimized.
d1794d3
to
6671c90
Compare
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
Add range metadata to slice lengths This adds range information to the slice-len in fat pointers if we can conservatively determine that the pointee is not a ZST without having to normalize the pointee type. I only intended to pass the `!range` to llvm but apparently this also lets the length in fat pointers be used for its niches 😅. Ideally this would use the naive-layout computation from rust-lang#113166 to calculate a better approximation of the pointee size, but that PR got reverted.
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (9a4ff20): comparison URL. Overall result: ❌✅ regressions and improvements - please read the text belowBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary -1.1%, secondary -0.9%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary 0.6%, secondary 0.4%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeResults (primary 0.3%, secondary 1.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Bootstrap: 781.528s -> 782.278s (0.10%) |
With additional range metadata the lengh of a wide ref can become the niche and therefore the pointer will be the padding instead.
6671c90
to
598d653
Compare
@@ -88,8 +89,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||
} | |||
} | |||
|
|||
fn size_to_bits(size: Size) -> u128 { |
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.
Given that https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/struct.Size.html#method.bits and bits_usize
already exist, maybe put a method over with them instead? Or if you're already relying on the 2⁴⁸ limit anyway, maybe just use size.bits()
and deal in u64
?
// Try to display a sensible error with as much information as possible. | ||
let skeleton_string = |ty: Ty<'tcx>, sk: Result<_, &_>| match sk { | ||
Ok(SizeSkeleton::Pointer { tail, known_size: Some(size), .. }) => { | ||
format!("{} bits, pointer to `{tail}`", size_to_bits(size)) | ||
} | ||
Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), | ||
Ok(SizeSkeleton::Known(size, _)) => { | ||
if let Some(v) = u128::from(size.bytes()).checked_mul(8) { |
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.
...oh, looks like down here also should be using such a thing
@@ -20,7 +21,7 @@ pub fn chunks4(x: &[u8]) -> &[[u8; 4]] { | |||
// CHECK-LABEL: @chunks4_with_remainder | |||
#[no_mangle] | |||
pub fn chunks4_with_remainder(x: &[u8]) -> (&[[u8; 4]], &[u8]) { | |||
// CHECK-DAG: and i64 %x.1, -4 | |||
// CHECK-DAG: and i64 %x.1, 9223372036854775804 |
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.
ymmv: You can use a numeric pattern to writes this in hex, which I think is easier to read here:
// CHECK-DAG: and i64 %x.1, 9223372036854775804 | |
// CHECK-DAG: and i64 %x.1, [[#0x7FFFFFFFFFFFFFFC]] |
(I learned this trying to make a similar change in https://github.com/rust-lang/rust/pull/122926/files#diff-1f5fbc02acba64b04fe4b9ccdb433dcaa57f5ff617088895a87c03ff104ef03cR24 🙂)
☔ The latest upstream changes (presumably #131949) made this pull request unmergeable. Please resolve the merge conflicts. |
This adds range information to the slice-len in fat pointers if we can conservatively determine that the pointee is not a ZST without having to normalize the pointee type.
I only intended to pass the
!range
to llvm but apparently this also lets the length in fat pointers be used for its niches 😅.Ideally this would use the naive-layout computation from #113166 to calculate a better approximation of the pointee size, but that PR got reverted.