Shrink TyKind::FnPtr
.
By splitting the `FnSig` within `TyKind::FnPtr` into `FnSigTys` and `FnHeader`, which can be packed more efficiently. This reduces the size of the hot `TyKind` type from 32 bytes to 24 bytes on 64-bit platforms. This reduces peak memory usage by a few percent on some benchmarks. It also reduces cache misses and page faults similarly, though this doesn't translate to clear cycles or wall-time improvements on CI.
This commit is contained in:
parent
8640998869
commit
c4717cc9d1
89 changed files with 298 additions and 201 deletions
|
@ -427,7 +427,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
|
|
|
@ -130,7 +130,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(),
|
||||
_ => "fn item".into(),
|
||||
},
|
||||
ty::FnPtr(_) => "fn pointer".into(),
|
||||
ty::FnPtr(..) => "fn pointer".into(),
|
||||
ty::Dynamic(inner, ..) if let Some(principal) = inner.principal() => {
|
||||
format!("`dyn {}`", tcx.def_path_str(principal.def_id())).into()
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(),
|
||||
_ => "fn item".into(),
|
||||
},
|
||||
ty::FnPtr(_) => "fn pointer".into(),
|
||||
ty::FnPtr(..) => "fn pointer".into(),
|
||||
ty::Dynamic(..) => "trait object".into(),
|
||||
ty::Closure(..) | ty::CoroutineClosure(..) => "closure".into(),
|
||||
ty::Coroutine(def_id, ..) => {
|
||||
|
|
|
@ -250,9 +250,9 @@ impl FlagComputation {
|
|||
self.add_args(args);
|
||||
}
|
||||
|
||||
&ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| {
|
||||
computation.add_tys(fn_sig.inputs());
|
||||
computation.add_ty(fn_sig.output());
|
||||
&ty::FnPtr(sig_tys, _) => self.bound_computation(sig_tys, |computation, sig_tys| {
|
||||
computation.add_tys(sig_tys.inputs());
|
||||
computation.add_ty(sig_tys.output());
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -801,7 +801,7 @@ where
|
|||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Never
|
||||
| ty::FnDef(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
|
@ -986,7 +986,8 @@ where
|
|||
safe: None,
|
||||
})
|
||||
}
|
||||
ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
|
||||
ty::FnPtr(sig_tys, hdr) if offset.bytes() == 0 => {
|
||||
let fn_sig = sig_tys.with(hdr);
|
||||
tcx.layout_of(param_env.and(Ty::new_fn_ptr(tcx, fn_sig))).ok().map(|layout| {
|
||||
PointeeInfo { size: layout.size, align: layout.align.abi, safe: None }
|
||||
})
|
||||
|
|
|
@ -2149,6 +2149,6 @@ mod size_asserts {
|
|||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(PredicateKind<'_>, 32);
|
||||
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 56);
|
||||
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 48);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
|
|
@ -290,7 +290,7 @@ fn characteristic_def_id_of_type_cached<'a>(
|
|||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Str
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Param(_)
|
||||
|
|
|
@ -696,7 +696,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
p!(print(sig), " {{", print_value_path(def_id, args), "}}");
|
||||
}
|
||||
}
|
||||
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
|
||||
ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))),
|
||||
ty::Infer(infer_ty) => {
|
||||
if self.should_print_verbose() {
|
||||
p!(write("{:?}", ty.kind()));
|
||||
|
@ -1678,7 +1678,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
}
|
||||
}
|
||||
}
|
||||
ty::FnPtr(_) => {
|
||||
ty::FnPtr(..) => {
|
||||
// FIXME: We should probably have a helper method to share code with the "Byte strings"
|
||||
// printing above (which also has to handle pointers to all sorts of things).
|
||||
if let Some(GlobalAlloc::Function { instance, .. }) =
|
||||
|
@ -1741,7 +1741,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
p!(write("{:?}", char::try_from(int).unwrap()))
|
||||
}
|
||||
// Pointer types
|
||||
ty::Ref(..) | ty::RawPtr(_, _) | ty::FnPtr(_) => {
|
||||
ty::Ref(..) | ty::RawPtr(_, _) | ty::FnPtr(..) => {
|
||||
let data = int.to_bits(self.tcx().data_layout.pointer_size);
|
||||
self.typed_value(
|
||||
|this| {
|
||||
|
|
|
@ -374,7 +374,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||
),
|
||||
ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
|
||||
ty::FnDef(def_id, args) => ty::FnDef(def_id, args.try_fold_with(folder)?),
|
||||
ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
|
||||
ty::FnPtr(sig_tys, hdr) => ty::FnPtr(sig_tys.try_fold_with(folder)?, hdr),
|
||||
ty::Ref(r, ty, mutbl) => {
|
||||
ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||
}
|
||||
ty::Tuple(ts) => ts.visit_with(visitor),
|
||||
ty::FnDef(_, args) => args.visit_with(visitor),
|
||||
ty::FnPtr(ref f) => f.visit_with(visitor),
|
||||
ty::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor),
|
||||
ty::Ref(r, ty, _) => {
|
||||
try_visit!(r.visit_with(visitor));
|
||||
ty.visit_with(visitor)
|
||||
|
|
|
@ -658,7 +658,8 @@ impl<'tcx> Ty<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||
Ty::new(tcx, FnPtr(fty))
|
||||
let (sig_tys, hdr) = fty.split();
|
||||
Ty::new(tcx, FnPtr(sig_tys, hdr))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1182,7 +1183,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
| Float(_)
|
||||
| Uint(_)
|
||||
| FnDef(..)
|
||||
| FnPtr(_)
|
||||
| FnPtr(..)
|
||||
| RawPtr(_, _)
|
||||
| Infer(IntVar(_) | FloatVar(_))
|
||||
)
|
||||
|
@ -1333,7 +1334,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
|
||||
match self.kind() {
|
||||
FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args),
|
||||
FnPtr(f) => *f,
|
||||
FnPtr(sig_tys, hdr) => sig_tys.with(*hdr),
|
||||
Error(_) => {
|
||||
// ignore errors (#54954)
|
||||
Binder::dummy(ty::FnSig {
|
||||
|
@ -1352,12 +1353,12 @@ impl<'tcx> Ty<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn is_fn(self) -> bool {
|
||||
matches!(self.kind(), FnDef(..) | FnPtr(_))
|
||||
matches!(self.kind(), FnDef(..) | FnPtr(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_fn_ptr(self) -> bool {
|
||||
matches!(self.kind(), FnPtr(_))
|
||||
matches!(self.kind(), FnPtr(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1599,7 +1600,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
|
@ -1791,7 +1792,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
|
@ -1941,7 +1942,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
| RawPtr(_, _)
|
||||
| Ref(_, _, _)
|
||||
| FnDef(_, _)
|
||||
| FnPtr(_)
|
||||
| FnPtr(..)
|
||||
| Dynamic(_, _, _)
|
||||
| Closure(_, _)
|
||||
| CoroutineClosure(_, _)
|
||||
|
@ -1972,6 +1973,6 @@ mod size_asserts {
|
|||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(ty::RegionKind<'_>, 24);
|
||||
static_assert_size!(ty::TyKind<'_>, 32);
|
||||
static_assert_size!(ty::TyKind<'_>, 24);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
|
|
@ -1282,7 +1282,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
| ty::RawPtr(_, _)
|
||||
| ty::FnDef(..)
|
||||
| ty::Error(_)
|
||||
| ty::FnPtr(_) => true,
|
||||
| ty::FnPtr(..) => true,
|
||||
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_freeze),
|
||||
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_freeze(),
|
||||
ty::Adt(..)
|
||||
|
@ -1322,7 +1322,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
| ty::RawPtr(_, _)
|
||||
| ty::FnDef(..)
|
||||
| ty::Error(_)
|
||||
| ty::FnPtr(_) => true,
|
||||
| ty::FnPtr(..) => true,
|
||||
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_unpin),
|
||||
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_unpin(),
|
||||
ty::Adt(..)
|
||||
|
@ -1361,7 +1361,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
| ty::Ref(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop,
|
||||
|
||||
|
@ -1544,7 +1544,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
ty::Pat(..) | ty::Ref(..) | ty::Array(..) | ty::Slice(_) | ty::Tuple(..) => true,
|
||||
|
||||
// Raw pointers use bitwise comparison.
|
||||
ty::RawPtr(_, _) | ty::FnPtr(_) => true,
|
||||
ty::RawPtr(_, _) | ty::FnPtr(..) => true,
|
||||
|
||||
// Floating point numbers are not `Eq`.
|
||||
ty::Float(_) => false,
|
||||
|
@ -1675,7 +1675,7 @@ pub fn needs_drop_components_with_async<'tcx>(
|
|||
| ty::Float(_)
|
||||
| ty::Never
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Char
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
|
@ -1742,7 +1742,7 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
|
|||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Never
|
||||
| ty::Foreign(_) => true,
|
||||
|
||||
|
|
|
@ -189,9 +189,12 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
|||
stack.extend(args.iter().rev());
|
||||
}
|
||||
ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)),
|
||||
ty::FnPtr(sig) => {
|
||||
stack.push(sig.skip_binder().output().into());
|
||||
stack.extend(sig.skip_binder().inputs().iter().copied().rev().map(|ty| ty.into()));
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
let fn_sig = sig_tys.with(hdr);
|
||||
stack.push(fn_sig.skip_binder().output().into());
|
||||
stack.extend(
|
||||
fn_sig.skip_binder().inputs().iter().copied().rev().map(|ty| ty.into()),
|
||||
);
|
||||
}
|
||||
},
|
||||
GenericArgKind::Lifetime(_) => {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue