Skip to content

Commit 4fb039e

Browse files
committed
recover null-ptr optimization by adding a special case to the niching logic
1 parent 76c49ae commit 4fb039e

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

compiler/rustc_abi/src/lib.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,16 +1503,21 @@ impl Niche {
15031503

15041504
pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> {
15051505
assert!(count > 0);
1506+
if count > self.available(cx) {
1507+
return None;
1508+
}
15061509

15071510
let Self { value, valid_range: v, .. } = *self;
1508-
let size = value.size(cx);
1509-
assert!(size.bits() <= 128);
1510-
let max_value = size.unsigned_int_max();
1511+
let max_value = value.size(cx).unsigned_int_max();
1512+
let distance_end_zero = max_value - v.end;
15111513

1512-
let niche = v.end.wrapping_add(1)..v.start;
1513-
let available = niche.end.wrapping_sub(niche.start) & max_value;
1514-
if count > available {
1515-
return None;
1514+
// Null-pointer optimization. This is guaranteed by Rust (at least for `Option<_>`),
1515+
// and offers better codegen opportunities.
1516+
if count == 1 && matches!(value, Pointer(_)) && !v.contains(0) {
1517+
// Select which bound to move to minimize the number of lost niches.
1518+
let valid_range =
1519+
if v.start - 1 > distance_end_zero { v.with_end(0) } else { v.with_start(0) };
1520+
return Some((0, Scalar::Initialized { value, valid_range }));
15161521
}
15171522

15181523
// Extend the range of valid values being reserved by moving either `v.start` or `v.end` bound.
@@ -1535,7 +1540,6 @@ impl Niche {
15351540
let end = v.end.wrapping_add(count) & max_value;
15361541
Some((start, Scalar::Initialized { value, valid_range: v.with_end(end) }))
15371542
};
1538-
let distance_end_zero = max_value - v.end;
15391543
if v.start > v.end {
15401544
// zero is unavailable because wrapping occurs
15411545
move_end(v)

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,7 @@ where
10871087
// this will continue to work as long as we don't start
10881088
// using more niches than just null (e.g., the first page of
10891089
// the address space, or unaligned pointers).
1090+
// FIXME(reference_niches): well, the day has come...
10901091
Variants::Multiple {
10911092
tag_encoding: TagEncoding::Niche { untagged_variant, .. },
10921093
tag_field,

0 commit comments

Comments
 (0)