Skip to content

Commit e51a2aa

Browse files
authored
Rollup merge of #116313 - nnethercote:rustc_abi, r=the8472
Some small cleanups in `rustc_abi` Minor things I found while looking at this crate's code. r? `@the8472`
2 parents b0889cb + 17e3793 commit e51a2aa

File tree

2 files changed

+74
-71
lines changed

2 files changed

+74
-71
lines changed

compiler/rustc_abi/src/layout.rs

+38-38
Original file line numberDiff line numberDiff line change
@@ -53,32 +53,32 @@ pub trait LayoutCalculator {
5353
kind: StructKind,
5454
) -> Option<LayoutS> {
5555
let layout = univariant(self, dl, fields, repr, kind, NicheBias::Start);
56-
// Enums prefer niches close to the beginning or the end of the variants so that other (smaller)
57-
// data-carrying variants can be packed into the space after/before the niche.
56+
// Enums prefer niches close to the beginning or the end of the variants so that other
57+
// (smaller) data-carrying variants can be packed into the space after/before the niche.
5858
// If the default field ordering does not give us a niche at the front then we do a second
59-
// run and bias niches to the right and then check which one is closer to one of the struct's
60-
// edges.
59+
// run and bias niches to the right and then check which one is closer to one of the
60+
// struct's edges.
6161
if let Some(layout) = &layout {
6262
// Don't try to calculate an end-biased layout for unsizable structs,
6363
// otherwise we could end up with different layouts for
64-
// Foo<Type> and Foo<dyn Trait> which would break unsizing
64+
// Foo<Type> and Foo<dyn Trait> which would break unsizing.
6565
if !matches!(kind, StructKind::MaybeUnsized) {
6666
if let Some(niche) = layout.largest_niche {
6767
let head_space = niche.offset.bytes();
68-
let niche_length = niche.value.size(dl).bytes();
69-
let tail_space = layout.size.bytes() - head_space - niche_length;
68+
let niche_len = niche.value.size(dl).bytes();
69+
let tail_space = layout.size.bytes() - head_space - niche_len;
7070

71-
// This may end up doing redundant work if the niche is already in the last field
72-
// (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get
73-
// the unpadded size so we try anyway.
71+
// This may end up doing redundant work if the niche is already in the last
72+
// field (e.g. a trailing bool) and there is tail padding. But it's non-trivial
73+
// to get the unpadded size so we try anyway.
7474
if fields.len() > 1 && head_space != 0 && tail_space > 0 {
7575
let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End)
7676
.expect("alt layout should always work");
77-
let niche = alt_layout
77+
let alt_niche = alt_layout
7878
.largest_niche
7979
.expect("alt layout should have a niche like the regular one");
80-
let alt_head_space = niche.offset.bytes();
81-
let alt_niche_len = niche.value.size(dl).bytes();
80+
let alt_head_space = alt_niche.offset.bytes();
81+
let alt_niche_len = alt_niche.value.size(dl).bytes();
8282
let alt_tail_space =
8383
alt_layout.size.bytes() - alt_head_space - alt_niche_len;
8484

@@ -93,7 +93,7 @@ pub trait LayoutCalculator {
9393
alt_layout: {}\n",
9494
layout.size.bytes(),
9595
head_space,
96-
niche_length,
96+
niche_len,
9797
tail_space,
9898
alt_head_space,
9999
alt_niche_len,
@@ -684,7 +684,8 @@ pub trait LayoutCalculator {
684684
// Also do not overwrite any already existing "clever" ABIs.
685685
if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) {
686686
variant.abi = abi;
687-
// Also need to bump up the size and alignment, so that the entire value fits in here.
687+
// Also need to bump up the size and alignment, so that the entire value fits
688+
// in here.
688689
variant.size = cmp::max(variant.size, size);
689690
variant.align.abi = cmp::max(variant.align.abi, align.abi);
690691
}
@@ -868,15 +869,15 @@ fn univariant(
868869

869870
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
870871
// the field ordering to try and catch some code making assumptions about layouts
871-
// we don't guarantee
872+
// we don't guarantee.
872873
if repr.can_randomize_type_layout() && cfg!(feature = "randomize") {
873874
#[cfg(feature = "randomize")]
874875
{
875-
// `ReprOptions.layout_seed` is a deterministic seed that we can use to
876-
// randomize field ordering with
876+
// `ReprOptions.layout_seed` is a deterministic seed we can use to randomize field
877+
// ordering.
877878
let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed.as_u64());
878879

879-
// Shuffle the ordering of the fields
880+
// Shuffle the ordering of the fields.
880881
optimizing.shuffle(&mut rng);
881882
}
882883
// Otherwise we just leave things alone and actually optimize the type's fields
@@ -892,27 +893,26 @@ fn univariant(
892893
.max()
893894
.unwrap_or(0);
894895

895-
// Calculates a sort key to group fields by their alignment or possibly some size-derived
896-
// pseudo-alignment.
896+
// Calculates a sort key to group fields by their alignment or possibly some
897+
// size-derived pseudo-alignment.
897898
let alignment_group_key = |layout: Layout<'_>| {
898899
if let Some(pack) = pack {
899-
// return the packed alignment in bytes
900+
// Return the packed alignment in bytes.
900901
layout.align().abi.min(pack).bytes()
901902
} else {
902-
// returns log2(effective-align).
903-
// This is ok since `pack` applies to all fields equally.
904-
// The calculation assumes that size is an integer multiple of align, except for ZSTs.
905-
//
903+
// Returns `log2(effective-align)`. This is ok since `pack` applies to all
904+
// fields equally. The calculation assumes that size is an integer multiple of
905+
// align, except for ZSTs.
906906
let align = layout.align().abi.bytes();
907907
let size = layout.size().bytes();
908908
let niche_size = layout.largest_niche().map(|n| n.available(dl)).unwrap_or(0);
909-
// group [u8; 4] with align-4 or [u8; 6] with align-2 fields
909+
// Group [u8; 4] with align-4 or [u8; 6] with align-2 fields.
910910
let size_as_align = align.max(size).trailing_zeros();
911911
let size_as_align = if largest_niche_size > 0 {
912912
match niche_bias {
913-
// Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the array
914-
// to the front in the first case (for aligned loads) but keep the bool in front
915-
// in the second case for its niches.
913+
// Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the
914+
// array to the front in the first case (for aligned loads) but keep
915+
// the bool in front in the second case for its niches.
916916
NicheBias::Start => max_field_align.trailing_zeros().min(size_as_align),
917917
// When moving niches towards the end of the struct then for
918918
// A((u8, u8, u8, bool), (u8, bool, u8)) we want to keep the first tuple
@@ -931,14 +931,14 @@ fn univariant(
931931

932932
match kind {
933933
StructKind::AlwaysSized | StructKind::MaybeUnsized => {
934-
// Currently `LayoutS` only exposes a single niche so sorting is usually sufficient
935-
// to get one niche into the preferred position. If it ever supported multiple niches
936-
// then a more advanced pick-and-pack approach could provide better results.
937-
// But even for the single-niche cache it's not optimal. E.g. for
938-
// A(u32, (bool, u8), u16) it would be possible to move the bool to the front
939-
// but it would require packing the tuple together with the u16 to build a 4-byte
940-
// group so that the u32 can be placed after it without padding. This kind
941-
// of packing can't be achieved by sorting.
934+
// Currently `LayoutS` only exposes a single niche so sorting is usually
935+
// sufficient to get one niche into the preferred position. If it ever
936+
// supported multiple niches then a more advanced pick-and-pack approach could
937+
// provide better results. But even for the single-niche cache it's not
938+
// optimal. E.g. for A(u32, (bool, u8), u16) it would be possible to move the
939+
// bool to the front but it would require packing the tuple together with the
940+
// u16 to build a 4-byte group so that the u32 can be placed after it without
941+
// padding. This kind of packing can't be achieved by sorting.
942942
optimizing.sort_by_key(|&x| {
943943
let f = fields[x];
944944
let field_size = f.size().bytes();

compiler/rustc_abi/src/lib.rs

+36-33
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ bitflags! {
5353
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
5454
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
5555
pub enum IntegerType {
56-
/// Pointer sized integer type, i.e. isize and usize. The field shows signedness, that
57-
/// is, `Pointer(true)` is isize.
56+
/// Pointer-sized integer type, i.e. `isize` and `usize`. The field shows signedness, e.g.
57+
/// `Pointer(true)` means `isize`.
5858
Pointer(bool),
59-
/// Fix sized integer type, e.g. i8, u32, i128 The bool field shows signedness, `Fixed(I8, false)` means `u8`
59+
/// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`. The bool field shows signedness, e.g.
60+
/// `Fixed(I8, false)` means `u8`.
6061
Fixed(Integer, bool),
6162
}
6263

@@ -69,7 +70,7 @@ impl IntegerType {
6970
}
7071
}
7172

72-
/// Represents the repr options provided by the user,
73+
/// Represents the repr options provided by the user.
7374
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
7475
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
7576
pub struct ReprOptions {
@@ -139,7 +140,7 @@ impl ReprOptions {
139140
}
140141

141142
/// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
142-
/// was enabled for its declaration crate
143+
/// was enabled for its declaration crate.
143144
pub fn can_randomize_type_layout(&self) -> bool {
144145
!self.inhibit_struct_field_reordering_opt()
145146
&& self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
@@ -217,7 +218,8 @@ pub enum TargetDataLayoutErrors<'a> {
217218
}
218219

219220
impl TargetDataLayout {
220-
/// Parse data layout from an [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
221+
/// Parse data layout from an
222+
/// [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
221223
///
222224
/// This function doesn't fill `c_enum_min_size` and it will always be `I32` since it can not be
223225
/// determined from llvm string.
@@ -242,10 +244,11 @@ impl TargetDataLayout {
242244
};
243245

244246
// Parse a size string.
245-
let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
247+
let parse_size =
248+
|s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
246249

247250
// Parse an alignment string.
248-
let align = |s: &[&'a str], cause: &'a str| {
251+
let parse_align = |s: &[&'a str], cause: &'a str| {
249252
if s.is_empty() {
250253
return Err(TargetDataLayoutErrors::MissingAlignment { cause });
251254
}
@@ -269,22 +272,22 @@ impl TargetDataLayout {
269272
[p] if p.starts_with('P') => {
270273
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
271274
}
272-
["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
273-
["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?,
274-
["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?,
275+
["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?,
276+
["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?,
277+
["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?,
275278
// FIXME(erikdesjardins): we should be parsing nonzero address spaces
276279
// this will require replacing TargetDataLayout::{pointer_size,pointer_align}
277280
// with e.g. `fn pointer_size_in(AddressSpace)`
278281
[p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => {
279-
dl.pointer_size = size(s, p)?;
280-
dl.pointer_align = align(a, p)?;
282+
dl.pointer_size = parse_size(s, p)?;
283+
dl.pointer_align = parse_align(a, p)?;
281284
}
282285
[s, ref a @ ..] if s.starts_with('i') => {
283286
let Ok(bits) = s[1..].parse::<u64>() else {
284-
size(&s[1..], "i")?; // For the user error.
287+
parse_size(&s[1..], "i")?; // For the user error.
285288
continue;
286289
};
287-
let a = align(a, s)?;
290+
let a = parse_align(a, s)?;
288291
match bits {
289292
1 => dl.i1_align = a,
290293
8 => dl.i8_align = a,
@@ -301,8 +304,8 @@ impl TargetDataLayout {
301304
}
302305
}
303306
[s, ref a @ ..] if s.starts_with('v') => {
304-
let v_size = size(&s[1..], "v")?;
305-
let a = align(a, s)?;
307+
let v_size = parse_size(&s[1..], "v")?;
308+
let a = parse_align(a, s)?;
306309
if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {
307310
v.1 = a;
308311
continue;
@@ -747,7 +750,6 @@ impl Align {
747750
/// A pair of alignments, ABI-mandated and preferred.
748751
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
749752
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
750-
751753
pub struct AbiAndPrefAlign {
752754
pub abi: Align,
753755
pub pref: Align,
@@ -773,7 +775,6 @@ impl AbiAndPrefAlign {
773775
/// Integers, also used for enum discriminants.
774776
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
775777
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
776-
777778
pub enum Integer {
778779
I8,
779780
I16,
@@ -937,8 +938,7 @@ impl Primitive {
937938
}
938939

939940
/// Inclusive wrap-around range of valid values, that is, if
940-
/// start > end, it represents `start..=MAX`,
941-
/// followed by `0..=end`.
941+
/// start > end, it represents `start..=MAX`, followed by `0..=end`.
942942
///
943943
/// That is, for an i8 primitive, a range of `254..=2` means following
944944
/// sequence:
@@ -970,21 +970,21 @@ impl WrappingRange {
970970

971971
/// Returns `self` with replaced `start`
972972
#[inline(always)]
973-
pub fn with_start(mut self, start: u128) -> Self {
973+
fn with_start(mut self, start: u128) -> Self {
974974
self.start = start;
975975
self
976976
}
977977

978978
/// Returns `self` with replaced `end`
979979
#[inline(always)]
980-
pub fn with_end(mut self, end: u128) -> Self {
980+
fn with_end(mut self, end: u128) -> Self {
981981
self.end = end;
982982
self
983983
}
984984

985985
/// Returns `true` if `size` completely fills the range.
986986
#[inline]
987-
pub fn is_full_for(&self, size: Size) -> bool {
987+
fn is_full_for(&self, size: Size) -> bool {
988988
let max_value = size.unsigned_int_max();
989989
debug_assert!(self.start <= max_value && self.end <= max_value);
990990
self.start == (self.end.wrapping_add(1) & max_value)
@@ -1066,15 +1066,17 @@ impl Scalar {
10661066
}
10671067

10681068
#[inline]
1069-
/// Allows the caller to mutate the valid range. This operation will panic if attempted on a union.
1069+
/// Allows the caller to mutate the valid range. This operation will panic if attempted on a
1070+
/// union.
10701071
pub fn valid_range_mut(&mut self) -> &mut WrappingRange {
10711072
match self {
10721073
Scalar::Initialized { valid_range, .. } => valid_range,
10731074
Scalar::Union { .. } => panic!("cannot change the valid range of a union"),
10741075
}
10751076
}
10761077

1077-
/// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole layout
1078+
/// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole
1079+
/// layout.
10781080
#[inline]
10791081
pub fn is_always_valid<C: HasDataLayout>(&self, cx: &C) -> bool {
10801082
match *self {
@@ -1252,7 +1254,6 @@ impl AddressSpace {
12521254
/// in terms of categories of C types there are ABI rules for.
12531255
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
12541256
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
1255-
12561257
pub enum Abi {
12571258
Uninhabited,
12581259
Scalar(Scalar),
@@ -1457,17 +1458,19 @@ impl Niche {
14571458
return None;
14581459
}
14591460

1460-
// Extend the range of valid values being reserved by moving either `v.start` or `v.end` bound.
1461-
// Given an eventual `Option<T>`, we try to maximize the chance for `None` to occupy the niche of zero.
1462-
// This is accomplished by preferring enums with 2 variants(`count==1`) and always taking the shortest path to niche zero.
1463-
// Having `None` in niche zero can enable some special optimizations.
1461+
// Extend the range of valid values being reserved by moving either `v.start` or `v.end`
1462+
// bound. Given an eventual `Option<T>`, we try to maximize the chance for `None` to occupy
1463+
// the niche of zero. This is accomplished by preferring enums with 2 variants(`count==1`)
1464+
// and always taking the shortest path to niche zero. Having `None` in niche zero can
1465+
// enable some special optimizations.
14641466
//
14651467
// Bound selection criteria:
14661468
// 1. Select closest to zero given wrapping semantics.
14671469
// 2. Avoid moving past zero if possible.
14681470
//
1469-
// In practice this means that enums with `count > 1` are unlikely to claim niche zero, since they have to fit perfectly.
1470-
// If niche zero is already reserved, the selection of bounds are of little interest.
1471+
// In practice this means that enums with `count > 1` are unlikely to claim niche zero,
1472+
// since they have to fit perfectly. If niche zero is already reserved, the selection of
1473+
// bounds are of little interest.
14711474
let move_start = |v: WrappingRange| {
14721475
let start = v.start.wrapping_sub(count) & max_value;
14731476
Some((start, Scalar::Initialized { value, valid_range: v.with_start(start) }))

0 commit comments

Comments
 (0)