diff options
| author | Andreas Liljeqvist <bonega@gmail.com> | 2021-08-22 21:46:03 +0200 |
|---|---|---|
| committer | Andreas Liljeqvist <bonega@gmail.com> | 2021-08-22 21:46:03 +0200 |
| commit | 5a501f73ff753109c7e73d4981fe011633bd8e84 (patch) | |
| tree | 4e687cca63f5373b65fc93056107eafcb2756e86 /compiler/rustc_target | |
| parent | 7481e6d1a415853a96dcec11a052caaa02859b5a (diff) | |
| download | rust-5a501f73ff753109c7e73d4981fe011633bd8e84.tar.gz rust-5a501f73ff753109c7e73d4981fe011633bd8e84.zip | |
Use custom wrap-around type instead of Range
Diffstat (limited to 'compiler/rustc_target')
| -rw-r--r-- | compiler/rustc_target/src/abi/mod.rs | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 8ef6e142cae..07687a4b104 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -677,32 +677,52 @@ impl Primitive { } } +/// Inclusive wrap-around range of valid values, that is, if +/// start > end, it represents `start..=MAX`, +/// followed by `0..=end`. +/// +/// That is, for an i8 primitive, a range of `254..=2` means following +/// sequence: +/// +/// 254 (-2), 255 (-1), 0, 1, 2 +/// +/// This is intended specifically to mirror LLVM’s `!range` metadata, +/// semantics. +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[derive(HashStable_Generic)] +pub struct AllocationRange { + pub start: u128, + pub end: u128, +} + +impl AllocationRange { + /// Returns `true` if `v` is contained in the range. + #[inline] + pub fn contains(&self, v: u128) -> bool { + if self.start <= self.end { + self.start <= v && v <= self.end + } else { + self.start <= v || v <= self.end + } + } +} + /// Information about one scalar component of a Rust type. #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable_Generic)] pub struct Scalar { pub value: Primitive, - /// Inclusive wrap-around range of valid values, that is, if - /// start > end, it represents `start..=MAX`, - /// followed by `0..=end`. - /// - /// That is, for an i8 primitive, a range of `254..=2` means following - /// sequence: - /// - /// 254 (-2), 255 (-1), 0, 1, 2 - /// - /// This is intended specifically to mirror LLVM’s `!range` metadata, - /// semantics. // 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: RangeInclusive<u128>, + pub valid_range: AllocationRange, } impl Scalar { pub fn is_bool(&self) -> bool { - matches!(self.value, Int(I8, false)) && self.valid_range == (0..=1) + matches!(self.value, Int(I8, false)) + && matches!(self.valid_range, AllocationRange { start: 0, end: 1 }) } /// Returns the valid range as a `x..y` range. @@ -715,8 +735,8 @@ impl Scalar { let bits = self.value.size(cx).bits(); assert!(bits <= 128); let mask = !0u128 >> (128 - bits); - let start = *self.valid_range.start(); - let end = *self.valid_range.end(); + let start = self.valid_range.start; + let end = self.valid_range.end; assert_eq!(start, start & mask); assert_eq!(end, end & mask); start..(end.wrapping_add(1) & mask) @@ -965,20 +985,20 @@ impl Niche { } pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 { - let Scalar { value, valid_range: ref v } = self.scalar; + let Scalar { value, valid_range: v } = self.scalar; let bits = value.size(cx).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); // Find out how many values are outside the valid range. - let niche = v.end().wrapping_add(1)..*v.start(); + let niche = v.end.wrapping_add(1)..v.start; niche.end.wrapping_sub(niche.start) & max_value } pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> { assert!(count > 0); - let Scalar { value, valid_range: ref v } = self.scalar; + let Scalar { value, valid_range: v } = self.scalar; let bits = value.size(cx).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); @@ -988,24 +1008,17 @@ impl Niche { } // Compute the range of invalid values being reserved. - let start = v.end().wrapping_add(1) & max_value; - let end = v.end().wrapping_add(count) & max_value; + let start = v.end.wrapping_add(1) & max_value; + let end = v.end.wrapping_add(count) & max_value; // If the `end` of our range is inside the valid range, // then we ran out of invalid values. // FIXME(eddyb) abstract this with a wraparound range type. - let valid_range_contains = |x| { - if v.start() <= v.end() { - *v.start() <= x && x <= *v.end() - } else { - *v.start() <= x || x <= *v.end() - } - }; - if valid_range_contains(end) { + if v.contains(end) { return None; } - Some((start, Scalar { value, valid_range: *v.start()..=end })) + Some((start, Scalar { value, valid_range: AllocationRange { start: v.start, end } })) } } @@ -1214,7 +1227,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { if zero { let range = &s.valid_range; // The range must contain 0. - range.contains(&0) || (*range.start() > *range.end()) // wrap-around allows 0 + range.contains(0) || (range.start > range.end) // wrap-around allows 0 } else { // The range must include all values. `valid_range_exclusive` handles // the wrap-around using target arithmetic; with wrap-around then the full |
