From 5a501f73ff753109c7e73d4981fe011633bd8e84 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Sun, 22 Aug 2021 21:46:03 +0200 Subject: Use custom wrap-around type instead of Range --- compiler/rustc_codegen_llvm/src/builder.rs | 4 ++-- compiler/rustc_codegen_llvm/src/consts.rs | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_codegen_llvm') diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2139f9776b7..2b72b167426 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -462,7 +462,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { load: &'ll Value, scalar: &abi::Scalar, ) { - let vr = scalar.valid_range.clone(); + let vr = scalar.valid_range; match scalar.value { abi::Int(..) => { let range = scalar.valid_range_exclusive(bx); @@ -470,7 +470,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { bx.range_metadata(load, range); } } - abi::Pointer if vr.start() < vr.end() && !vr.contains(&0) => { + abi::Pointer if vr.start < vr.end && !vr.contains(0) => { bx.nonnull_metadata(load); } _ => {} diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index e1baf95e1d9..01a93dd8857 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -16,7 +16,9 @@ use rustc_middle::mir::interpret::{ use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, span_bug}; -use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size}; +use rustc_target::abi::{ + AddressSpace, Align, AllocationRange, HasDataLayout, LayoutOf, Primitive, Scalar, Size, +}; use tracing::debug; pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value { @@ -59,7 +61,10 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Pointer::new(alloc_id, Size::from_bytes(ptr_offset)), &cx.tcx, ), - &Scalar { value: Primitive::Pointer, valid_range: 0..=!0 }, + &Scalar { + value: Primitive::Pointer, + valid_range: AllocationRange { start: 0, end: !0 }, + }, cx.type_i8p_ext(address_space), )); next_offset = offset + pointer_size; -- cgit 1.4.1-3-g733a5 From 70433955f4531f2742ddeb986e6ac19a8fd4792f Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 14:20:38 +0200 Subject: implement contains_zero method --- compiler/rustc_codegen_llvm/src/builder.rs | 3 +-- compiler/rustc_middle/src/ty/layout.rs | 6 ++---- compiler/rustc_target/src/abi/mod.rs | 12 +++++++++--- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'compiler/rustc_codegen_llvm') diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2b72b167426..7986d1d9cb2 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -462,7 +462,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { load: &'ll Value, scalar: &abi::Scalar, ) { - let vr = scalar.valid_range; match scalar.value { abi::Int(..) => { let range = scalar.valid_range_exclusive(bx); @@ -470,7 +469,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { bx.range_metadata(load, range); } } - abi::Pointer if vr.start < vr.end && !vr.contains(0) => { + abi::Pointer if !scalar.valid_range.contains_zero() => { bx.nonnull_metadata(load); } _ => {} diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 671f956bf31..c6caab3e798 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2857,10 +2857,8 @@ where return; } - if scalar.valid_range.start < scalar.valid_range.end { - if scalar.valid_range.start > 0 { - attrs.set(ArgAttribute::NonNull); - } + if !scalar.valid_range.contains_zero() { + attrs.set(ArgAttribute::NonNull); } if let Some(pointee) = layout.pointee_info_at(cx, offset) { diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index c3ec9bb8233..5ce8906e6ac 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -688,7 +688,7 @@ impl Primitive { /// /// This is intended specifically to mirror LLVM’s `!range` metadata, /// semantics. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable_Generic)] pub struct AllocationRange { pub start: u128, @@ -705,6 +705,13 @@ impl AllocationRange { self.start <= v || v <= self.end } } + + /// Returns `true` if zero is contained in the range. + /// Equal to `range.contains(0)` but should be faster. + #[inline] + pub fn contains_zero(&self) -> bool { + !(self.start <= self.end && self.start != 0) + } } /// Information about one scalar component of a Rust type. @@ -1222,9 +1229,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { { let scalar_allows_raw_init = move |s: &Scalar| -> bool { if zero { - let range = &s.valid_range; // The range must contain 0. - range.contains(0) || (range.start > range.end) // wrap-around allows 0 + s.valid_range.contains_zero() } else { // The range must include all values. `valid_range_exclusive` handles // the wrap-around using target arithmetic; with wrap-around then the full -- cgit 1.4.1-3-g733a5 From e8e6d9bd86c9cf685666718ca99e016275e1751b Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 14:24:34 +0200 Subject: Rename to WrappingRange --- compiler/rustc_codegen_llvm/src/consts.rs | 7 ++----- compiler/rustc_middle/src/ty/layout.rs | 16 ++++++++-------- compiler/rustc_mir/src/interpret/validity.rs | 8 ++++---- compiler/rustc_target/src/abi/mod.rs | 10 +++++----- 4 files changed, 19 insertions(+), 22 deletions(-) (limited to 'compiler/rustc_codegen_llvm') diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 01a93dd8857..ec92bd686d2 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{ - AddressSpace, Align, AllocationRange, HasDataLayout, LayoutOf, Primitive, Scalar, Size, + AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size, WrappingRange, }; use tracing::debug; @@ -61,10 +61,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Pointer::new(alloc_id, Size::from_bytes(ptr_offset)), &cx.tcx, ), - &Scalar { - value: Primitive::Pointer, - valid_range: AllocationRange { start: 0, end: !0 }, - }, + &Scalar { value: Primitive::Pointer, valid_range: WrappingRange { start: 0, end: !0 } }, cx.type_i8p_ext(address_space), )); next_offset = offset + pointer_size; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index c6caab3e798..6b628cb041b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -499,7 +499,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let scalar_unit = |value: Primitive| { let bits = value.size(dl).bits(); assert!(bits <= 128); - Scalar { value, valid_range: AllocationRange { start: 0, end: (!0 >> (128 - bits)) } } + Scalar { value, valid_range: WrappingRange { start: 0, end: (!0 >> (128 - bits)) } } }; let scalar = |value: Primitive| tcx.intern_layout(Layout::scalar(self, scalar_unit(value))); @@ -512,13 +512,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Basic scalars. ty::Bool => tcx.intern_layout(Layout::scalar( self, - Scalar { value: Int(I8, false), valid_range: AllocationRange { start: 0, end: 1 } }, + Scalar { value: Int(I8, false), valid_range: WrappingRange { start: 0, end: 1 } }, )), ty::Char => tcx.intern_layout(Layout::scalar( self, Scalar { value: Int(I32, false), - valid_range: AllocationRange { start: 0, end: 0x10FFFF }, + valid_range: WrappingRange { start: 0, end: 0x10FFFF }, }, )), ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)), @@ -529,7 +529,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }), ty::FnPtr(_) => { let mut ptr = scalar_unit(Pointer); - ptr.valid_range = AllocationRange { start: 1, end: ptr.valid_range.end }; + ptr.valid_range = WrappingRange { start: 1, end: ptr.valid_range.end }; tcx.intern_layout(Layout::scalar(self, ptr)) } @@ -548,7 +548,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let mut data_ptr = scalar_unit(Pointer); if !ty.is_unsafe_ptr() { data_ptr.valid_range = - AllocationRange { start: 1, end: data_ptr.valid_range.end }; + WrappingRange { start: 1, end: data_ptr.valid_range.end }; } let pointee = tcx.normalize_erasing_regions(param_env, pointee); @@ -565,7 +565,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ty::Dynamic(..) => { let mut vtable = scalar_unit(Pointer); vtable.valid_range = - AllocationRange { start: 1, end: vtable.valid_range.end }; + WrappingRange { start: 1, end: vtable.valid_range.end }; vtable } _ => return Err(LayoutError::Unknown(unsized_part)), @@ -1261,7 +1261,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let tag_mask = !0u128 >> (128 - ity.size().bits()); let tag = Scalar { value: Int(ity, signed), - valid_range: AllocationRange { + valid_range: WrappingRange { start: (min as u128 & tag_mask), end: (max as u128 & tag_mask), }, @@ -1545,7 +1545,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let discr_int_ty = discr_int.to_ty(tcx, false); let tag = Scalar { value: Primitive::Int(discr_int, false), - valid_range: AllocationRange { start: 0, end: max_discr }, + valid_range: WrappingRange { start: 0, end: max_discr }, }; let tag_layout = self.tcx.intern_layout(Layout::scalar(self, tag.clone())); let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout }; diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index bf34430cece..3ff149d6a7a 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -15,7 +15,7 @@ use rustc_middle::ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{ - Abi, AllocationRange, LayoutOf, Scalar as ScalarAbi, Size, VariantIdx, Variants, + Abi, LayoutOf, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange, }; use std::hash::Hash; @@ -184,8 +184,8 @@ fn write_path(out: &mut String, path: &[PathElem]) { // Formats such that a sentence like "expected something {}" to mean // "expected something " makes sense. -fn wrapping_range_format(r: AllocationRange, max_hi: u128) -> String { - let AllocationRange { start: lo, end: hi } = r; +fn wrapping_range_format(r: WrappingRange, max_hi: u128) -> String { + let WrappingRange { start: lo, end: hi } = r; assert!(hi <= max_hi); if lo > hi { format!("less or equal to {}, or greater or equal to {}", hi, lo) @@ -624,7 +624,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' ) -> InterpResult<'tcx> { let value = self.read_scalar(op)?; let valid_range = scalar_layout.valid_range.clone(); - let AllocationRange { start: lo, end: hi } = valid_range; + let WrappingRange { start: lo, end: hi } = valid_range; // Determine the allowed range // `max_hi` is as big as the size fits let max_hi = u128::MAX >> (128 - op.layout.size.bits()); diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 5ce8906e6ac..d29b731e4f1 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -690,12 +690,12 @@ impl Primitive { /// semantics. #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable_Generic)] -pub struct AllocationRange { +pub struct WrappingRange { pub start: u128, pub end: u128, } -impl AllocationRange { +impl WrappingRange { /// Returns `true` if `v` is contained in the range. #[inline] pub fn contains(&self, v: u128) -> bool { @@ -723,13 +723,13 @@ pub struct Scalar { // FIXME(eddyb) always use the shortest range, e.g., by finding // the largest space between two consecutive valid values and // taking everything else as the (shortest) valid range. - pub valid_range: AllocationRange, + pub valid_range: WrappingRange, } impl Scalar { pub fn is_bool(&self) -> bool { matches!(self.value, Int(I8, false)) - && matches!(self.valid_range, AllocationRange { start: 0, end: 1 }) + && matches!(self.valid_range, WrappingRange { start: 0, end: 1 }) } /// Returns the valid range as a `x..y` range. @@ -1022,7 +1022,7 @@ impl Niche { return None; } - Some((start, Scalar { value, valid_range: AllocationRange { start: v.start, end } })) + Some((start, Scalar { value, valid_range: WrappingRange { start: v.start, end } })) } } -- cgit 1.4.1-3-g733a5