also sort fields by niche sizes to retain optimizations
This commit is contained in:
parent
a3450d060d
commit
97d8a9bdd3
@ -140,8 +140,13 @@ fn univariant_uninterned<'tcx>(
|
|||||||
let optimizing = &mut inverse_memory_index[..end];
|
let optimizing = &mut inverse_memory_index[..end];
|
||||||
let effective_field_align = |f: &TyAndLayout<'_>| {
|
let effective_field_align = |f: &TyAndLayout<'_>| {
|
||||||
if let Some(pack) = pack {
|
if let Some(pack) = pack {
|
||||||
|
// return the packed alignment in bytes
|
||||||
f.align.abi.min(pack).bytes()
|
f.align.abi.min(pack).bytes()
|
||||||
} else {
|
} else {
|
||||||
|
// returns log2(effective-align).
|
||||||
|
// This is ok since `pack` applies to all fields equally.
|
||||||
|
// The calculation assumes that size is an integer multiple of align, except for ZSTs.
|
||||||
|
//
|
||||||
// group [u8; 4] with align-4 or [u8; 6] with align-2 fields
|
// group [u8; 4] with align-4 or [u8; 6] with align-2 fields
|
||||||
f.align.abi.bytes().max(f.size.bytes()).trailing_zeros() as u64
|
f.align.abi.bytes().max(f.size.bytes()).trailing_zeros() as u64
|
||||||
}
|
}
|
||||||
@ -165,15 +170,23 @@ fn univariant_uninterned<'tcx>(
|
|||||||
optimizing.sort_by_key(|&x| {
|
optimizing.sort_by_key(|&x| {
|
||||||
// Place ZSTs first to avoid "interesting offsets",
|
// Place ZSTs first to avoid "interesting offsets",
|
||||||
// especially with only one or two non-ZST fields.
|
// especially with only one or two non-ZST fields.
|
||||||
|
// Then place largest alignments first, largest niches within an alignment group last
|
||||||
let f = &fields[x as usize];
|
let f = &fields[x as usize];
|
||||||
(!f.is_zst(), cmp::Reverse(effective_field_align(f)))
|
let niche_size = f.largest_niche.map_or(0, |n| n.available(cx));
|
||||||
|
(!f.is_zst(), cmp::Reverse(effective_field_align(f)), niche_size)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
StructKind::Prefixed(..) => {
|
StructKind::Prefixed(..) => {
|
||||||
// Sort in ascending alignment so that the layout stays optimal
|
// Sort in ascending alignment so that the layout stays optimal
|
||||||
// regardless of the prefix
|
// regardless of the prefix.
|
||||||
optimizing.sort_by_key(|&x| effective_field_align(&fields[x as usize]));
|
// And put the largest niche in an alignment group at the end
|
||||||
|
// so it can be used as discriminant in jagged enums
|
||||||
|
optimizing.sort_by_key(|&x| {
|
||||||
|
let f = &fields[x as usize];
|
||||||
|
let niche_size = f.largest_niche.map_or(0, |n| n.available(cx));
|
||||||
|
(effective_field_align(f), niche_size)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user