Skip to content

Commit be2a772

Browse files
committed
Auto merge of rust-lang#123058 - lukas-code:clauses, r=<try>
[perf] cache type info for ParamEnv This is an attempt to mitigate some of the perf regressions in rust-lang#122553 (comment), but seems worth to test and land separately. r? `@ghost`
2 parents 35936c4 + 4a99cdc commit be2a772

File tree

14 files changed

+374
-70
lines changed

14 files changed

+374
-70
lines changed

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,7 @@ pub(super) fn explicit_item_bounds_with_filter(
165165
ty::EarlyBinder::bind(bounds)
166166
}
167167

168-
pub(super) fn item_bounds(
169-
tcx: TyCtxt<'_>,
170-
def_id: DefId,
171-
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
168+
pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<ty::Clauses<'_>> {
172169
tcx.explicit_item_bounds(def_id).map_bound(|bounds| {
173170
tcx.mk_clauses_from_iter(util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)))
174171
})
@@ -177,7 +174,7 @@ pub(super) fn item_bounds(
177174
pub(super) fn item_super_predicates(
178175
tcx: TyCtxt<'_>,
179176
def_id: DefId,
180-
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
177+
) -> ty::EarlyBinder<ty::Clauses<'_>> {
181178
tcx.explicit_item_super_predicates(def_id).map_bound(|bounds| {
182179
tcx.mk_clauses_from_iter(
183180
util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(),
@@ -188,12 +185,12 @@ pub(super) fn item_super_predicates(
188185
pub(super) fn item_non_self_assumptions(
189186
tcx: TyCtxt<'_>,
190187
def_id: DefId,
191-
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
188+
) -> ty::EarlyBinder<ty::Clauses<'_>> {
192189
let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect();
193190
let own_bounds: FxIndexSet<_> =
194191
tcx.item_super_predicates(def_id).skip_binder().iter().collect();
195192
if all_bounds.len() == own_bounds.len() {
196-
ty::EarlyBinder::bind(ty::List::empty())
193+
ty::EarlyBinder::bind(ty::ListWithCachedTypeInfo::empty())
197194
} else {
198195
ty::EarlyBinder::bind(tcx.mk_clauses_from_iter(all_bounds.difference(&own_bounds).copied()))
199196
}

compiler/rustc_middle/src/query/erase.rs

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ impl<T> EraseType for &'_ ty::List<T> {
6767
type Result = [u8; size_of::<&'static ty::List<()>>()];
6868
}
6969

70+
impl<T> EraseType for &'_ ty::ListWithCachedTypeInfo<T> {
71+
type Result = [u8; size_of::<&'static ty::ListWithCachedTypeInfo<()>>()];
72+
}
73+
7074
impl<I: rustc_index::Idx, T> EraseType for &'_ rustc_index::IndexSlice<I, T> {
7175
type Result = [u8; size_of::<&'static rustc_index::IndexSlice<u32, ()>>()];
7276
}

compiler/rustc_middle/src/query/keys.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) {
433433
}
434434
}
435435

436-
impl<'tcx> Key for &'tcx ty::List<ty::Clause<'tcx>> {
436+
impl<'tcx> Key for ty::Clauses<'tcx> {
437437
type CacheSelector = DefaultCacheSelector<Self>;
438438

439439
fn default_span(&self, _: TyCtxt<'_>) -> Span {

compiler/rustc_middle/src/query/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -398,15 +398,15 @@ rustc_queries! {
398398
/// ```
399399
///
400400
/// Bounds from the parent (e.g. with nested impl trait) are not included.
401-
query item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<ty::Clause<'tcx>>> {
401+
query item_bounds(key: DefId) -> ty::EarlyBinder<ty::Clauses<'tcx>> {
402402
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
403403
}
404404

405-
query item_super_predicates(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<ty::Clause<'tcx>>> {
405+
query item_super_predicates(key: DefId) -> ty::EarlyBinder<ty::Clauses<'tcx>> {
406406
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
407407
}
408408

409-
query item_non_self_assumptions(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<ty::Clause<'tcx>>> {
409+
query item_non_self_assumptions(key: DefId) -> ty::EarlyBinder<ty::Clauses<'tcx>> {
410410
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
411411
}
412412

@@ -2162,7 +2162,7 @@ rustc_queries! {
21622162
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
21632163
}
21642164

2165-
query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Clause<'tcx>>) -> &'tcx ty::List<ty::Clause<'tcx>> {
2165+
query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
21662166
desc { "revealing opaque types in `{:?}`", key }
21672167
}
21682168

compiler/rustc_middle/src/ty/codec.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,9 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty
414414
}
415415
}
416416

417-
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Clause<'tcx>> {
417+
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
418+
for ty::ListWithCachedTypeInfo<ty::Clause<'tcx>>
419+
{
418420
fn decode(decoder: &mut D) -> &'tcx Self {
419421
let len = decoder.read_usize();
420422
decoder.interner().mk_clauses_from_iter(
@@ -462,7 +464,7 @@ impl_decodable_via_ref! {
462464
&'tcx mir::BorrowCheckResult<'tcx>,
463465
&'tcx mir::coverage::CodeRegion,
464466
&'tcx ty::List<ty::BoundVariableKind>,
465-
&'tcx ty::List<ty::Clause<'tcx>>,
467+
&'tcx ty::ListWithCachedTypeInfo<ty::Clause<'tcx>>,
466468
&'tcx ty::List<FieldIdx>,
467469
&'tcx ty::List<(VariantIdx, FieldIdx)>,
468470
}

compiler/rustc_middle/src/ty/context.rs

+50-9
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ use crate::traits::solve::{
2525
ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
2626
};
2727
use crate::ty::{
28-
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
29-
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
30-
PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
31-
TyKind, TyVid, TypeVisitable, Visibility,
28+
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData,
29+
GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
30+
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity, Region,
31+
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, TypeVisitable, Visibility,
3232
};
3333
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
3434
use rustc_ast::{self as ast, attr};
@@ -129,6 +129,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
129129
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
130130
type CoercePredicate = ty::CoercePredicate<'tcx>;
131131
type ClosureKind = ty::ClosureKind;
132+
type Clauses = ty::Clauses<'tcx>;
132133

133134
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
134135
self.mk_canonical_var_infos(infos)
@@ -151,7 +152,7 @@ pub struct CtxtInterners<'tcx> {
151152
region: InternedSet<'tcx, RegionKind<'tcx>>,
152153
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
153154
predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
154-
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
155+
clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
155156
projs: InternedSet<'tcx, List<ProjectionKind>>,
156157
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
157158
const_: InternedSet<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>,
@@ -285,6 +286,24 @@ impl<'tcx> CtxtInterners<'tcx> {
285286
.0,
286287
))
287288
}
289+
290+
fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
291+
if clauses.is_empty() {
292+
ListWithCachedTypeInfo::empty()
293+
} else {
294+
self.clauses
295+
.intern_ref(clauses, || {
296+
let flags = super::flags::FlagComputation::for_clauses(clauses);
297+
298+
InternedInSet(ListWithCachedTypeInfo::from_arena(
299+
&*self.arena,
300+
flags.into(),
301+
clauses,
302+
))
303+
})
304+
.0
305+
}
306+
}
288307
}
289308

290309
// For these preinterned values, an alternative would be to have
@@ -1717,6 +1736,29 @@ impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
17171736
}
17181737
}
17191738

1739+
impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1740+
fn borrow(&self) -> &[T] {
1741+
&self.0[..]
1742+
}
1743+
}
1744+
1745+
impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1746+
fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1747+
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1748+
// `x == y`.
1749+
self.0[..] == other.0[..]
1750+
}
1751+
}
1752+
1753+
impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1754+
1755+
impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1756+
fn hash<H: Hasher>(&self, s: &mut H) {
1757+
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1758+
self.0[..].hash(s)
1759+
}
1760+
}
1761+
17201762
macro_rules! direct_interners {
17211763
($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
17221764
$(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
@@ -1792,7 +1834,6 @@ slice_interners!(
17921834
type_lists: pub mk_type_list(Ty<'tcx>),
17931835
canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
17941836
poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
1795-
clauses: intern_clauses(Clause<'tcx>),
17961837
projs: pub mk_projs(ProjectionKind),
17971838
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
17981839
bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
@@ -2026,11 +2067,11 @@ impl<'tcx> TyCtxt<'tcx> {
20262067
self.intern_poly_existential_predicates(eps)
20272068
}
20282069

2029-
pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> &'tcx List<Clause<'tcx>> {
2070+
pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
20302071
// FIXME consider asking the input slice to be sorted to avoid
20312072
// re-interning permutations, in which case that would be asserted
20322073
// here.
2033-
self.intern_clauses(clauses)
2074+
self.interners.intern_clauses(clauses)
20342075
}
20352076

20362077
pub fn mk_local_def_ids(self, clauses: &[LocalDefId]) -> &'tcx List<LocalDefId> {
@@ -2094,7 +2135,7 @@ impl<'tcx> TyCtxt<'tcx> {
20942135
pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
20952136
where
20962137
I: Iterator<Item = T>,
2097-
T: CollectAndApply<Clause<'tcx>, &'tcx List<Clause<'tcx>>>,
2138+
T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
20982139
{
20992140
T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
21002141
}

compiler/rustc_middle/src/ty/flags.rs

+9
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ impl FlagComputation {
3535
result
3636
}
3737

38+
pub fn for_clauses(clauses: &[ty::Clause<'_>]) -> FlagComputation {
39+
let mut result = FlagComputation::new();
40+
for c in clauses {
41+
result.add_flags(c.as_predicate().flags());
42+
result.add_exclusive_binder(c.as_predicate().outer_exclusive_binder());
43+
}
44+
result
45+
}
46+
3847
fn add_flags(&mut self, flags: TypeFlags) {
3948
self.flags = self.flags | flags;
4049
}

compiler/rustc_middle/src/ty/impls_ty.rs

+10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ where
5555
}
5656
}
5757

58+
impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::ListWithCachedTypeInfo<T>
59+
where
60+
T: HashStable<StableHashingContext<'a>>,
61+
{
62+
#[inline]
63+
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
64+
self.as_list().hash_stable(hcx, hasher);
65+
}
66+
}
67+
5868
impl<'a> ToStableHashKey<StableHashingContext<'a>> for SimplifiedType {
5969
type KeyType = Fingerprint;
6070

0 commit comments

Comments
 (0)