Skip to content

Commit a4d3c9a

Browse files
committed
Pre-intern some ReVars and ReLateBounds.
1 parent cef9004 commit a4d3c9a

File tree

1 file changed

+59
-4
lines changed

1 file changed

+59
-4
lines changed

compiler/rustc_middle/src/ty/context.rs

+59-4
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,20 @@ impl<'tcx> CtxtInterners<'tcx> {
243243
}
244244
}
245245

246+
// For these preinterned values, an alternative would be to have
247+
// variable-length vectors that grow as needed. But that turned out to be
248+
// slightly more complex and no faster.
249+
246250
const NUM_PREINTERNED_TY_VARS: u32 = 100;
247251
const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
248252
const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
249253
const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
250254

255+
// This number may seem high, but it is reached in all but the smallest crates.
256+
const NUM_PREINTERNED_RE_VARS: u32 = 500;
257+
const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2;
258+
const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20;
259+
251260
pub struct CommonTypes<'tcx> {
252261
pub unit: Ty<'tcx>,
253262
pub bool: Ty<'tcx>,
@@ -295,6 +304,14 @@ pub struct CommonLifetimes<'tcx> {
295304

296305
/// Erased region, used outside of type inference.
297306
pub re_erased: Region<'tcx>,
307+
308+
/// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`.
309+
pub re_vars: Vec<Region<'tcx>>,
310+
311+
/// Pre-interned values of the form:
312+
/// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(v, None) })
313+
/// for small values of `i` and `v`.
314+
pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
298315
}
299316

300317
pub struct CommonConsts<'tcx> {
@@ -358,7 +375,31 @@ impl<'tcx> CommonLifetimes<'tcx> {
358375
))
359376
};
360377

361-
CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) }
378+
let re_vars =
379+
(0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
380+
381+
let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I)
382+
.map(|i| {
383+
(0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
384+
.map(|v| {
385+
mk(ty::ReLateBound(
386+
ty::DebruijnIndex::from(i),
387+
ty::BoundRegion {
388+
var: ty::BoundVar::from(v),
389+
kind: ty::BrAnon(v, None),
390+
},
391+
))
392+
})
393+
.collect()
394+
})
395+
.collect();
396+
397+
CommonLifetimes {
398+
re_static: mk(ty::ReStatic),
399+
re_erased: mk(ty::ReErased),
400+
re_vars,
401+
re_late_bounds,
402+
}
362403
}
363404
}
364405

@@ -2002,7 +2043,16 @@ impl<'tcx> TyCtxt<'tcx> {
20022043
debruijn: ty::DebruijnIndex,
20032044
bound_region: ty::BoundRegion,
20042045
) -> Region<'tcx> {
2005-
self.intern_region(ty::ReLateBound(debruijn, bound_region))
2046+
// Use a pre-interned one when possible.
2047+
if let ty::BoundRegion { var, kind: ty::BrAnon(v, None) } = bound_region
2048+
&& var.as_u32() == v
2049+
&& let Some(inner) = self.lifetimes.re_late_bounds.get(debruijn.as_usize())
2050+
&& let Some(re) = inner.get(v as usize).copied()
2051+
{
2052+
re
2053+
} else {
2054+
self.intern_region(ty::ReLateBound(debruijn, bound_region))
2055+
}
20062056
}
20072057

20082058
#[inline]
@@ -2011,8 +2061,13 @@ impl<'tcx> TyCtxt<'tcx> {
20112061
}
20122062

20132063
#[inline]
2014-
pub fn mk_re_var(self, vid: ty::RegionVid) -> Region<'tcx> {
2015-
self.intern_region(ty::ReVar(vid))
2064+
pub fn mk_re_var(self, v: ty::RegionVid) -> Region<'tcx> {
2065+
// Use a pre-interned one when possible.
2066+
self.lifetimes
2067+
.re_vars
2068+
.get(v.as_usize())
2069+
.copied()
2070+
.unwrap_or_else(|| self.intern_region(ty::ReVar(v)))
20162071
}
20172072

20182073
#[inline]

0 commit comments

Comments
 (0)