Skip to content

Commit ed788a6

Browse files
committed
rustc: store CachedLayout for each variant of enum Layout's instead of Struct.
1 parent bd51a2b commit ed788a6

File tree

8 files changed

+134
-178
lines changed

8 files changed

+134
-178
lines changed

src/librustc/ty/context.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ use hir;
7878
/// Internal storage
7979
pub struct GlobalArenas<'tcx> {
8080
// internings
81-
layout: TypedArena<Layout>,
81+
layout: TypedArena<Layout<'tcx>>,
8282

8383
// references
8484
generics: TypedArena<ty::Generics>,
@@ -918,7 +918,7 @@ pub struct GlobalCtxt<'tcx> {
918918

919919
stability_interner: RefCell<FxHashSet<&'tcx attr::Stability>>,
920920

921-
layout_interner: RefCell<FxHashSet<&'tcx Layout>>,
921+
layout_interner: RefCell<FxHashSet<&'tcx Layout<'tcx>>>,
922922

923923
/// A vector of every trait accessible in the whole crate
924924
/// (i.e. including those from subcrates). This is used only for
@@ -1016,7 +1016,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10161016
interned
10171017
}
10181018

1019-
pub fn intern_layout(self, layout: Layout) -> &'gcx Layout {
1019+
pub fn intern_layout(self, layout: Layout<'gcx>) -> &'gcx Layout<'gcx> {
10201020
if let Some(layout) = self.layout_interner.borrow().get(&layout) {
10211021
return layout;
10221022
}

src/librustc/ty/layout.rs

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ pub const FAT_PTR_ADDR: usize = 0;
10041004
pub const FAT_PTR_EXTRA: usize = 1;
10051005

10061006
/// Describes how the fields of a type are located in memory.
1007-
#[derive(Copy, Clone, Debug)]
1007+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
10081008
pub enum FieldPlacement<'a> {
10091009
/// Array-like placement. Can also express
10101010
/// unions, by using a stride of zero bytes.
@@ -1058,7 +1058,7 @@ impl<'a> FieldPlacement<'a> {
10581058

10591059
/// Describes how values of the type are passed by target ABIs,
10601060
/// in terms of categories of C types there are ABI rules for.
1061-
#[derive(Copy, Clone, Debug)]
1061+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
10621062
pub enum Abi {
10631063
Scalar(Primitive),
10641064
Vector {
@@ -1141,8 +1141,8 @@ impl Abi {
11411141
/// For ADTs, it also includes field placement and enum optimizations.
11421142
/// NOTE: Because Layout is interned, redundant information should be
11431143
/// kept to a minimum, e.g. it includes no sub-component Ty or Layout.
1144-
#[derive(Debug, PartialEq, Eq, Hash)]
1145-
pub enum Layout {
1144+
#[derive(PartialEq, Eq, Hash, Debug)]
1145+
pub enum Layout<'a> {
11461146
/// TyBool, TyChar, TyInt, TyUint, TyFloat, TyRawPtr, TyRef or TyFnPtr.
11471147
Scalar(Primitive),
11481148

@@ -1184,7 +1184,7 @@ pub enum Layout {
11841184
// the largest space between two consecutive discriminants and
11851185
// taking everything else as the (shortest) discriminant range.
11861186
discr_range: RangeInclusive<u64>,
1187-
variants: Vec<Struct>,
1187+
variants: Vec<CachedLayout<'a>>,
11881188
size: Size,
11891189
align: Align,
11901190
primitive_align: Align,
@@ -1202,7 +1202,7 @@ pub enum Layout {
12021202
nndiscr: u64,
12031203
discr: Primitive,
12041204
discr_offset: Size,
1205-
variants: Vec<Struct>,
1205+
variants: Vec<CachedLayout<'a>>,
12061206
size: Size,
12071207
align: Align,
12081208
primitive_align: Align,
@@ -1228,9 +1228,9 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
12281228
}
12291229
}
12301230

1231-
#[derive(Copy, Clone, Debug)]
1231+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
12321232
pub struct CachedLayout<'tcx> {
1233-
pub layout: &'tcx Layout,
1233+
pub layout: &'tcx Layout<'tcx>,
12341234
pub fields: FieldPlacement<'tcx>,
12351235
pub abi: Abi,
12361236
}
@@ -1262,7 +1262,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
12621262
};
12631263
}
12641264

1265-
impl<'a, 'tcx> Layout {
1265+
impl<'a, 'tcx> Layout<'tcx> {
12661266
fn compute_uncached(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12671267
param_env: ty::ParamEnv<'tcx>,
12681268
ty: Ty<'tcx>)
@@ -1624,7 +1624,9 @@ impl<'a, 'tcx> Layout {
16241624
size: st[discr].stride(),
16251625
align,
16261626
primitive_align,
1627-
variants: st,
1627+
variants: st.into_iter().map(|variant| {
1628+
success(Univariant(variant))
1629+
}).collect::<Result<Vec<_>, _>>()?,
16281630
});
16291631
}
16301632
}
@@ -1730,7 +1732,9 @@ impl<'a, 'tcx> Layout {
17301732

17311733
// FIXME: should be u128?
17321734
discr_range: (min as u64)..=(max as u64),
1733-
variants,
1735+
variants: variants.into_iter().map(|variant| {
1736+
success(Univariant(variant))
1737+
}).collect::<Result<Vec<_>, _>>()?,
17341738
size,
17351739
align,
17361740
primitive_align,
@@ -1897,6 +1901,10 @@ impl<'a, 'tcx> Layout {
18971901
.iter()
18981902
.map(|f| (f.name, f.ty(tcx, substs)))
18991903
.collect();
1904+
let variant_layout = match *variant_layout.layout {
1905+
Univariant(ref variant) => variant,
1906+
_ => bug!()
1907+
};
19001908
build_variant_info(Some(variant_def.name),
19011909
&fields,
19021910
variant_layout)
@@ -2084,7 +2092,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
20842092
pub struct FullLayout<'tcx> {
20852093
pub ty: Ty<'tcx>,
20862094
pub variant_index: Option<usize>,
2087-
pub layout: &'tcx Layout,
2095+
pub layout: &'tcx Layout<'tcx>,
20882096
pub fields: FieldPlacement<'tcx>,
20892097
pub abi: Abi,
20902098
}
@@ -2198,27 +2206,22 @@ impl<'a, 'tcx> FullLayout<'tcx> {
21982206
variants[variant_index].fields.len()
21992207
};
22002208

2201-
let (fields, abi) = match *self.layout {
2202-
Univariant(_) => (self.fields, self.abi),
2209+
let (layout, fields, abi) = match *self.layout {
2210+
Univariant(_) => (self.layout, self.fields, self.abi),
22032211

22042212
NullablePointer { ref variants, .. } |
22052213
General { ref variants, .. } => {
2206-
let variant = &variants[variant_index];
2207-
(FieldPlacement::Arbitrary {
2208-
offsets: &variant.offsets
2209-
}, Abi::Aggregate {
2210-
sized: true,
2211-
align: variant.align,
2212-
primitive_align: variant.primitive_align,
2213-
size: variant.stride(),
2214-
})
2214+
let variant = variants[variant_index];
2215+
(variant.layout, variant.fields, variant.abi)
22152216
}
22162217

2217-
_ => (FieldPlacement::union(count), self.abi)
2218+
_ => bug!()
22182219
};
2220+
assert_eq!(fields.count(), count);
22192221

22202222
FullLayout {
22212223
variant_index: Some(variant_index),
2224+
layout,
22222225
fields,
22232226
abi,
22242227
..*self
@@ -2348,8 +2351,7 @@ impl<'a, 'tcx> FullLayout<'tcx> {
23482351
}
23492352
}
23502353

2351-
impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout
2352-
{
2354+
impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout<'gcx> {
23532355
fn hash_stable<W: StableHasherResult>(&self,
23542356
hcx: &mut StableHashingContext<'gcx>,
23552357
hasher: &mut StableHasher<W>) {

src/librustc_lint/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
764764
.zip(variants)
765765
.map(|(variant, variant_layout)| {
766766
// Subtract the size of the enum discriminant
767-
let bytes = variant_layout.min_size
767+
let bytes = variant_layout.abi.size(cx.tcx)
768768
.bytes()
769769
.saturating_sub(discr_size);
770770

src/librustc_trans/adt.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
8787
} else {
8888
l
8989
};
90-
llty.set_struct_body(&struct_llfields(cx, variant_layout, variant), variant.packed)
90+
llty.set_struct_body(&struct_llfields(cx, variant_layout), variant.packed)
9191
},
9292
_ => bug!("This function cannot handle {} with layout {:#?}", t, l)
9393
}
@@ -105,8 +105,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
105105
layout::Univariant(ref variant) => {
106106
match name {
107107
None => {
108-
Type::struct_(cx, &struct_llfields(cx, l, &variant),
109-
variant.packed)
108+
Type::struct_(cx, &struct_llfields(cx, l), variant.packed)
110109
}
111110
Some(name) => {
112111
Type::named_struct(cx, name)
@@ -166,8 +165,11 @@ pub fn memory_index_to_gep(index: u64) -> u64 {
166165
}
167166

168167
pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
169-
layout: FullLayout<'tcx>,
170-
variant: &layout::Struct) -> Vec<Type> {
168+
layout: FullLayout<'tcx>) -> Vec<Type> {
169+
let variant = match *layout.layout {
170+
layout::Univariant(ref variant) => variant,
171+
_ => bug!("unexpected {:#?}", layout)
172+
};
171173
let field_count = layout.fields.count();
172174
debug!("struct_llfields: variant: {:?}", variant);
173175
let mut offset = Size::from_bytes(0);

0 commit comments

Comments
 (0)