Skip to content

Commit

Permalink
Auto merge of rust-lang#94690 - nnethercote:clarify-Layout-interning,…
Browse files Browse the repository at this point in the history
… 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`
  • Loading branch information
bors committed Mar 7, 2022
2 parents d137c3a + 4f008e0 commit ecb867e
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 87 deletions.
10 changes: 8 additions & 2 deletions compiler/rustc_codegen_cranelift/src/abi/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,14 @@ pub(super) fn add_local_place_comments<'tcx>(
return;
}
let TyAndLayout { ty, layout } = place.layout();
let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } =
layout;
let rustc_target::abi::LayoutS {
size,
align,
abi: _,
variants: _,
fields: _,
largest_niche: _,
} = layout.0.0;

let (kind, extra) = match *place.inner() {
CPlaceInner::Var(place_local, var) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
};

raw_eq, (v lhs_ref, v rhs_ref) {
let size = fx.layout_of(substs.type_at(0)).layout.size;
let size = fx.layout_of(substs.type_at(0)).layout.size();
// FIXME add and use emit_small_memcmp
let is_eq_value =
if size == Size::ZERO {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,20 +272,20 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
use rustc_target::abi::Abi::*;
let tp_ty = substs.type_at(0);
let layout = self.layout_of(tp_ty).layout;
let _use_integer_compare = match layout.abi {
let _use_integer_compare = match layout.abi() {
Scalar(_) | ScalarPair(_, _) => true,
Uninhabited | Vector { .. } => false,
Aggregate { .. } => {
// For rusty ABIs, small aggregates are actually passed
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
// so we re-use that same threshold here.
layout.size <= self.data_layout().pointer_size * 2
layout.size() <= self.data_layout().pointer_size * 2
}
};

let a = args[0].immediate();
let b = args[1].immediate();
if layout.size.bytes() == 0 {
if layout.size().bytes() == 0 {
self.const_bool(true)
}
/*else if use_integer_compare {
Expand All @@ -301,7 +301,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
let void_ptr_type = self.context.new_type::<*const ()>();
let a_ptr = self.bitcast(a, void_ptr_type);
let b_ptr = self.bitcast(b, void_ptr_type);
let n = self.context.new_cast(None, self.const_usize(layout.size.bytes()), self.sizet_type);
let n = self.context.new_cast(None, self.const_usize(layout.size().bytes()), self.sizet_type);
let builtin = self.context.get_builtin_function("memcmp");
let cmp = self.context.new_call(None, builtin, &[a_ptr, b_ptr, n]);
self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0))
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,34 +300,34 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
use abi::Abi::*;
let tp_ty = substs.type_at(0);
let layout = self.layout_of(tp_ty).layout;
let use_integer_compare = match layout.abi {
let use_integer_compare = match layout.abi() {
Scalar(_) | ScalarPair(_, _) => true,
Uninhabited | Vector { .. } => false,
Aggregate { .. } => {
// For rusty ABIs, small aggregates are actually passed
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
// so we re-use that same threshold here.
layout.size <= self.data_layout().pointer_size * 2
layout.size() <= self.data_layout().pointer_size * 2
}
};

let a = args[0].immediate();
let b = args[1].immediate();
if layout.size.bytes() == 0 {
if layout.size().bytes() == 0 {
self.const_bool(true)
} else if use_integer_compare {
let integer_ty = self.type_ix(layout.size.bits());
let integer_ty = self.type_ix(layout.size().bits());
let ptr_ty = self.type_ptr_to(integer_ty);
let a_ptr = self.bitcast(a, ptr_ty);
let a_val = self.load(integer_ty, a_ptr, layout.align.abi);
let a_val = self.load(integer_ty, a_ptr, layout.align().abi);
let b_ptr = self.bitcast(b, ptr_ty);
let b_val = self.load(integer_ty, b_ptr, layout.align.abi);
let b_val = self.load(integer_ty, b_ptr, layout.align().abi);
self.icmp(IntPredicate::IntEQ, a_val, b_val)
} else {
let i8p_ty = self.type_i8p();
let a_ptr = self.bitcast(a, i8p_ty);
let b_ptr = self.bitcast(b, i8p_ty);
let n = self.const_usize(layout.size.bytes());
let n = self.const_usize(layout.size().bytes());
let cmp = self.call_intrinsic("memcmp", &[a_ptr, b_ptr, n]);
self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0))
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ fn push_debuginfo_type_name<'tcx>(

// calculate the range of values for the dataful variant
let dataful_discriminant_range =
dataful_variant_layout.largest_niche.unwrap().scalar.valid_range;
dataful_variant_layout.largest_niche().unwrap().scalar.valid_range;

let min = dataful_discriminant_range.start;
let min = tag.value.size(&tcx).truncate(min);
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_data_structures/src/intern.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::stable_hasher::{HashStable, StableHasher};
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
Expand Down Expand Up @@ -98,5 +99,14 @@ impl<'a, T> Hash for Interned<'a, T> {
}
}

impl<T, CTX> HashStable<CTX> for Interned<'_, T>
where
T: HashStable<CTX>,
{
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
self.0.hash_stable(hcx, hasher);
}
}

#[cfg(test)]
mod tests;
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2861,8 +2861,8 @@ impl ClashingExternDeclarations {

let compare_layouts = |a, b| -> Result<bool, LayoutError<'tcx>> {
debug!("compare_layouts({:?}, {:?})", a, b);
let a_layout = &cx.layout_of(a)?.layout.abi;
let b_layout = &cx.layout_of(b)?.layout.abi;
let a_layout = &cx.layout_of(a)?.layout.abi();
let b_layout = &cx.layout_of(b)?.layout.abi();
debug!(
"comparing layouts: {:?} == {:?} = {}",
a_layout,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
let (largest, slargest, largest_index) = iter::zip(enum_definition.variants, variants)
.map(|(variant, variant_layout)| {
// Subtract the size of the enum tag.
let bytes = variant_layout.size.bytes().saturating_sub(tag_size);
let bytes = variant_layout.size().bytes().saturating_sub(tag_size);

debug!("- variant `{}` is {} bytes large", variant.ident, bytes);
bytes
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ impl Collector<'_> {
.layout;
// In both stdcall and fastcall, we always round up the argument size to the
// nearest multiple of 4 bytes.
(layout.size.bytes_usize() + 3) & !3
(layout.size().bytes_usize() + 3) & !3
})
.sum()
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
macro_rules! arena_types {
($macro:path) => (
$macro!([
[] layout: rustc_target::abi::Layout,
[] layout: rustc_target::abi::LayoutS<'tcx>,
[] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>,
// AdtDef are interned and compared by address
[decode] adt_def: rustc_middle::ty::AdtDef,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use rustc_span::def_id::{DefPathHash, StableCrateId};
use rustc_span::source_map::{MultiSpan, SourceMap};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;

use rustc_type_ir::TypeFlags;
Expand Down Expand Up @@ -114,7 +114,7 @@ pub struct CtxtInterners<'tcx> {
const_: InternedSet<'tcx, ConstS<'tcx>>,
const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, Layout>,
layout: InternedSet<'tcx, LayoutS<'tcx>>,
adt_def: InternedSet<'tcx, AdtDef>,
}

Expand Down Expand Up @@ -2146,6 +2146,7 @@ direct_interners! {
region: mk_region(RegionKind): Region -> Region<'tcx>,
const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
}

macro_rules! direct_interners_old {
Expand Down Expand Up @@ -2186,7 +2187,6 @@ macro_rules! direct_interners_old {

// FIXME: eventually these should all be converted to `direct_interners`.
direct_interners_old! {
layout: intern_layout(Layout),
adt_def: intern_adt_def(AdtDef),
}

Expand Down
Loading

0 comments on commit ecb867e

Please sign in to comment.