Skip to content

Commit ecb867e

Browse files
committed
Auto merge of #94690 - nnethercote:clarify-Layout-interning, r=fee1-dead
Clarify `Layout` interning. `Layout` is another type that is sometimes interned, sometimes not, and we always use references to refer to it so we can't take any advantage of the uniqueness properties for hashing or equality checks. This commit renames `Layout` as `LayoutS`, and then introduces a new `Layout` that is a newtype around an `Interned<LayoutS>`. It also interns more layouts than before. Previously layouts within layouts (via the `variants` field) were never interned, but now they are. Hence the lifetime on the new `Layout` type. Unlike other interned types, these ones are in `rustc_target` instead of `rustc_middle`. This reflects the existing structure of the code, which does layout-specific stuff in `rustc_target` while `TyAndLayout` is generic over the `Ty`, allowing the type-specific stuff to occur in `rustc_middle`. The commit also adds a `HashStable` impl for `Interned`, which was needed. It hashes the contents, unlike the `Hash` impl which hashes the pointer. r? `@fee1-dead`
2 parents d137c3a + 4f008e0 commit ecb867e

File tree

17 files changed

+177
-87
lines changed

17 files changed

+177
-87
lines changed

compiler/rustc_codegen_cranelift/src/abi/comments.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,14 @@ pub(super) fn add_local_place_comments<'tcx>(
8282
return;
8383
}
8484
let TyAndLayout { ty, layout } = place.layout();
85-
let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } =
86-
layout;
85+
let rustc_target::abi::LayoutS {
86+
size,
87+
align,
88+
abi: _,
89+
variants: _,
90+
fields: _,
91+
largest_niche: _,
92+
} = layout.0.0;
8793

8894
let (kind, extra) = match *place.inner() {
8995
CPlaceInner::Var(place_local, var) => {

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
10701070
};
10711071

10721072
raw_eq, (v lhs_ref, v rhs_ref) {
1073-
let size = fx.layout_of(substs.type_at(0)).layout.size;
1073+
let size = fx.layout_of(substs.type_at(0)).layout.size();
10741074
// FIXME add and use emit_small_memcmp
10751075
let is_eq_value =
10761076
if size == Size::ZERO {

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -272,20 +272,20 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
272272
use rustc_target::abi::Abi::*;
273273
let tp_ty = substs.type_at(0);
274274
let layout = self.layout_of(tp_ty).layout;
275-
let _use_integer_compare = match layout.abi {
275+
let _use_integer_compare = match layout.abi() {
276276
Scalar(_) | ScalarPair(_, _) => true,
277277
Uninhabited | Vector { .. } => false,
278278
Aggregate { .. } => {
279279
// For rusty ABIs, small aggregates are actually passed
280280
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
281281
// so we re-use that same threshold here.
282-
layout.size <= self.data_layout().pointer_size * 2
282+
layout.size() <= self.data_layout().pointer_size * 2
283283
}
284284
};
285285

286286
let a = args[0].immediate();
287287
let b = args[1].immediate();
288-
if layout.size.bytes() == 0 {
288+
if layout.size().bytes() == 0 {
289289
self.const_bool(true)
290290
}
291291
/*else if use_integer_compare {
@@ -301,7 +301,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
301301
let void_ptr_type = self.context.new_type::<*const ()>();
302302
let a_ptr = self.bitcast(a, void_ptr_type);
303303
let b_ptr = self.bitcast(b, void_ptr_type);
304-
let n = self.context.new_cast(None, self.const_usize(layout.size.bytes()), self.sizet_type);
304+
let n = self.context.new_cast(None, self.const_usize(layout.size().bytes()), self.sizet_type);
305305
let builtin = self.context.get_builtin_function("memcmp");
306306
let cmp = self.context.new_call(None, builtin, &[a_ptr, b_ptr, n]);
307307
self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0))

compiler/rustc_codegen_llvm/src/intrinsic.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -300,34 +300,34 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
300300
use abi::Abi::*;
301301
let tp_ty = substs.type_at(0);
302302
let layout = self.layout_of(tp_ty).layout;
303-
let use_integer_compare = match layout.abi {
303+
let use_integer_compare = match layout.abi() {
304304
Scalar(_) | ScalarPair(_, _) => true,
305305
Uninhabited | Vector { .. } => false,
306306
Aggregate { .. } => {
307307
// For rusty ABIs, small aggregates are actually passed
308308
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
309309
// so we re-use that same threshold here.
310-
layout.size <= self.data_layout().pointer_size * 2
310+
layout.size() <= self.data_layout().pointer_size * 2
311311
}
312312
};
313313

314314
let a = args[0].immediate();
315315
let b = args[1].immediate();
316-
if layout.size.bytes() == 0 {
316+
if layout.size().bytes() == 0 {
317317
self.const_bool(true)
318318
} else if use_integer_compare {
319-
let integer_ty = self.type_ix(layout.size.bits());
319+
let integer_ty = self.type_ix(layout.size().bits());
320320
let ptr_ty = self.type_ptr_to(integer_ty);
321321
let a_ptr = self.bitcast(a, ptr_ty);
322-
let a_val = self.load(integer_ty, a_ptr, layout.align.abi);
322+
let a_val = self.load(integer_ty, a_ptr, layout.align().abi);
323323
let b_ptr = self.bitcast(b, ptr_ty);
324-
let b_val = self.load(integer_ty, b_ptr, layout.align.abi);
324+
let b_val = self.load(integer_ty, b_ptr, layout.align().abi);
325325
self.icmp(IntPredicate::IntEQ, a_val, b_val)
326326
} else {
327327
let i8p_ty = self.type_i8p();
328328
let a_ptr = self.bitcast(a, i8p_ty);
329329
let b_ptr = self.bitcast(b, i8p_ty);
330-
let n = self.const_usize(layout.size.bytes());
330+
let n = self.const_usize(layout.size().bytes());
331331
let cmp = self.call_intrinsic("memcmp", &[a_ptr, b_ptr, n]);
332332
self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0))
333333
}

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ fn push_debuginfo_type_name<'tcx>(
427427

428428
// calculate the range of values for the dataful variant
429429
let dataful_discriminant_range =
430-
dataful_variant_layout.largest_niche.unwrap().scalar.valid_range;
430+
dataful_variant_layout.largest_niche().unwrap().scalar.valid_range;
431431

432432
let min = dataful_discriminant_range.start;
433433
let min = tag.value.size(&tcx).truncate(min);

compiler/rustc_data_structures/src/intern.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::stable_hasher::{HashStable, StableHasher};
12
use std::cmp::Ordering;
23
use std::hash::{Hash, Hasher};
34
use std::ops::Deref;
@@ -98,5 +99,14 @@ impl<'a, T> Hash for Interned<'a, T> {
9899
}
99100
}
100101

102+
impl<T, CTX> HashStable<CTX> for Interned<'_, T>
103+
where
104+
T: HashStable<CTX>,
105+
{
106+
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
107+
self.0.hash_stable(hcx, hasher);
108+
}
109+
}
110+
101111
#[cfg(test)]
102112
mod tests;

compiler/rustc_lint/src/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2861,8 +2861,8 @@ impl ClashingExternDeclarations {
28612861

28622862
let compare_layouts = |a, b| -> Result<bool, LayoutError<'tcx>> {
28632863
debug!("compare_layouts({:?}, {:?})", a, b);
2864-
let a_layout = &cx.layout_of(a)?.layout.abi;
2865-
let b_layout = &cx.layout_of(b)?.layout.abi;
2864+
let a_layout = &cx.layout_of(a)?.layout.abi();
2865+
let b_layout = &cx.layout_of(b)?.layout.abi();
28662866
debug!(
28672867
"comparing layouts: {:?} == {:?} = {}",
28682868
a_layout,

compiler/rustc_lint/src/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1349,7 +1349,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
13491349
let (largest, slargest, largest_index) = iter::zip(enum_definition.variants, variants)
13501350
.map(|(variant, variant_layout)| {
13511351
// Subtract the size of the enum tag.
1352-
let bytes = variant_layout.size.bytes().saturating_sub(tag_size);
1352+
let bytes = variant_layout.size().bytes().saturating_sub(tag_size);
13531353

13541354
debug!("- variant `{}` is {} bytes large", variant.ident, bytes);
13551355
bytes

compiler/rustc_metadata/src/native_libs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ impl Collector<'_> {
392392
.layout;
393393
// In both stdcall and fastcall, we always round up the argument size to the
394394
// nearest multiple of 4 bytes.
395-
(layout.size.bytes_usize() + 3) & !3
395+
(layout.size().bytes_usize() + 3) & !3
396396
})
397397
.sum()
398398
}

compiler/rustc_middle/src/arena.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
macro_rules! arena_types {
77
($macro:path) => (
88
$macro!([
9-
[] layout: rustc_target::abi::Layout,
9+
[] layout: rustc_target::abi::LayoutS<'tcx>,
1010
[] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>,
1111
// AdtDef are interned and compared by address
1212
[decode] adt_def: rustc_middle::ty::AdtDef,

compiler/rustc_middle/src/ty/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use rustc_span::def_id::{DefPathHash, StableCrateId};
5656
use rustc_span::source_map::{MultiSpan, SourceMap};
5757
use rustc_span::symbol::{kw, sym, Ident, Symbol};
5858
use rustc_span::{Span, DUMMY_SP};
59-
use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
59+
use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
6060
use rustc_target::spec::abi;
6161

6262
use rustc_type_ir::TypeFlags;
@@ -114,7 +114,7 @@ pub struct CtxtInterners<'tcx> {
114114
const_: InternedSet<'tcx, ConstS<'tcx>>,
115115
const_allocation: InternedSet<'tcx, Allocation>,
116116
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
117-
layout: InternedSet<'tcx, Layout>,
117+
layout: InternedSet<'tcx, LayoutS<'tcx>>,
118118
adt_def: InternedSet<'tcx, AdtDef>,
119119
}
120120

@@ -2146,6 +2146,7 @@ direct_interners! {
21462146
region: mk_region(RegionKind): Region -> Region<'tcx>,
21472147
const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
21482148
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2149+
layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
21492150
}
21502151

21512152
macro_rules! direct_interners_old {
@@ -2186,7 +2187,6 @@ macro_rules! direct_interners_old {
21862187

21872188
// FIXME: eventually these should all be converted to `direct_interners`.
21882189
direct_interners_old! {
2189-
layout: intern_layout(Layout),
21902190
adt_def: intern_adt_def(AdtDef),
21912191
}
21922192

0 commit comments

Comments
 (0)