Pre-intern some ReVars and ReLateBounds.

This commit is contained in:
Nicholas Nethercote 2023-02-13 15:37:44 +11:00
parent cef9004f5a
commit a4d3c9a1a4

View File

@ -243,11 +243,20 @@ fn intern_predicate(
} }
} }
// For these preinterned values, an alternative would be to have
// variable-length vectors that grow as needed. But that turned out to be
// slightly more complex and no faster.
const NUM_PREINTERNED_TY_VARS: u32 = 100; const NUM_PREINTERNED_TY_VARS: u32 = 100;
const NUM_PREINTERNED_FRESH_TYS: u32 = 20; const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3; const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3; const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
// This number may seem high, but it is reached in all but the smallest crates.
const NUM_PREINTERNED_RE_VARS: u32 = 500;
const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2;
const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20;
pub struct CommonTypes<'tcx> { pub struct CommonTypes<'tcx> {
pub unit: Ty<'tcx>, pub unit: Ty<'tcx>,
pub bool: Ty<'tcx>, pub bool: Ty<'tcx>,
@ -295,6 +304,14 @@ pub struct CommonLifetimes<'tcx> {
/// Erased region, used outside of type inference. /// Erased region, used outside of type inference.
pub re_erased: Region<'tcx>, pub re_erased: Region<'tcx>,
/// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`.
pub re_vars: Vec<Region<'tcx>>,
/// Pre-interned values of the form:
/// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(v, None) })
/// for small values of `i` and `v`.
pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
} }
pub struct CommonConsts<'tcx> { pub struct CommonConsts<'tcx> {
@ -358,7 +375,31 @@ fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
)) ))
}; };
CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) } let re_vars =
(0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I)
.map(|i| {
(0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
.map(|v| {
mk(ty::ReLateBound(
ty::DebruijnIndex::from(i),
ty::BoundRegion {
var: ty::BoundVar::from(v),
kind: ty::BrAnon(v, None),
},
))
})
.collect()
})
.collect();
CommonLifetimes {
re_static: mk(ty::ReStatic),
re_erased: mk(ty::ReErased),
re_vars,
re_late_bounds,
}
} }
} }
@ -2002,7 +2043,16 @@ pub fn mk_re_late_bound(
debruijn: ty::DebruijnIndex, debruijn: ty::DebruijnIndex,
bound_region: ty::BoundRegion, bound_region: ty::BoundRegion,
) -> Region<'tcx> { ) -> Region<'tcx> {
self.intern_region(ty::ReLateBound(debruijn, bound_region)) // Use a pre-interned one when possible.
if let ty::BoundRegion { var, kind: ty::BrAnon(v, None) } = bound_region
&& var.as_u32() == v
&& let Some(inner) = self.lifetimes.re_late_bounds.get(debruijn.as_usize())
&& let Some(re) = inner.get(v as usize).copied()
{
re
} else {
self.intern_region(ty::ReLateBound(debruijn, bound_region))
}
} }
#[inline] #[inline]
@ -2011,8 +2061,13 @@ pub fn mk_re_free(self, scope: DefId, bound_region: ty::BoundRegionKind) -> Regi
} }
#[inline] #[inline]
pub fn mk_re_var(self, vid: ty::RegionVid) -> Region<'tcx> { pub fn mk_re_var(self, v: ty::RegionVid) -> Region<'tcx> {
self.intern_region(ty::ReVar(vid)) // Use a pre-interned one when possible.
self.lifetimes
.re_vars
.get(v.as_usize())
.copied()
.unwrap_or_else(|| self.intern_region(ty::ReVar(v)))
} }
#[inline] #[inline]