Skip to content

Commit c4d9ada

Browse files
committed
rustc: place ZSTs first during struct field reordering.
1 parent cdeb4b0 commit c4d9ada

File tree

1 file changed

+19
-22
lines changed

1 file changed

+19
-22
lines changed

src/librustc/ty/layout.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -964,40 +964,37 @@ impl<'a, 'tcx> CachedLayout {
964964
let mut align = base_align;
965965
let mut primitive_align = base_align;
966966
let mut sized = true;
967+
let mut offsets = vec![Size::from_bytes(0); fields.len()];
968+
let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
967969

968970
// Anything with repr(C) or repr(packed) doesn't optimize.
969-
// Neither do 1-member and 2-member structs.
970-
// In addition, code in trans assume that 2-element structs can become pairs.
971-
// It's easier to just short-circuit here.
972-
let (mut optimize, sort_ascending) = match kind {
971+
let optimize = match kind {
973972
StructKind::AlwaysSized |
974-
StructKind::MaybeUnsized => (fields.len() > 2, false),
975-
StructKind::EnumVariant(discr) => {
976-
(discr.size().bytes() == 1, true)
973+
StructKind::MaybeUnsized |
974+
StructKind::EnumVariant(I8) => {
975+
(repr.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty()
977976
}
977+
StructKind::EnumVariant(_) => false
978978
};
979-
980-
optimize &= (repr.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty();
981-
982-
let mut offsets = vec![Size::from_bytes(0); fields.len()];
983-
let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
984-
985979
if optimize {
986980
let end = if let StructKind::MaybeUnsized = kind {
987981
fields.len() - 1
988982
} else {
989983
fields.len()
990984
};
991-
if end > 0 {
992-
let optimizing = &mut inverse_memory_index[..end];
993-
if sort_ascending {
985+
let optimizing = &mut inverse_memory_index[..end];
986+
match kind {
987+
StructKind::AlwaysSized |
988+
StructKind::MaybeUnsized => {
989+
optimizing.sort_by_key(|&x| {
990+
// Place ZSTs first to avoid "interesting offsets",
991+
// especially with only one or two non-ZST fields.
992+
let f = &fields[x as usize];
993+
(!f.is_zst(), cmp::Reverse(f.align.abi()))
994+
})
995+
}
996+
StructKind::EnumVariant(_) => {
994997
optimizing.sort_by_key(|&x| fields[x as usize].align.abi());
995-
} else {
996-
optimizing.sort_by(| &a, &b | {
997-
let a = fields[a as usize].align.abi();
998-
let b = fields[b as usize].align.abi();
999-
b.cmp(&a)
1000-
});
1001998
}
1002999
}
10031000
}

0 commit comments

Comments
 (0)