Skip to content

Commit 9d1834c

Browse files
committed
Auto merge of #162031 - laundmo:opt-next-solver-memory, r=<try>
Reduce next-solver memory usage by interning CanonicalQueryInput
2 parents 5321a4f + b9978df commit 9d1834c

10 files changed

Lines changed: 86 additions & 26 deletions

File tree

compiler/rustc_middle/src/query/keys.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,24 @@ impl<'tcx, T: QueryKeyBounds> QueryKey for (CanonicalQueryInput<'tcx, T>, usize)
346346
}
347347
}
348348

349+
impl<'tcx> QueryKey for crate::traits::solve::CanonicalInput<'tcx> {
350+
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
351+
DUMMY_SP
352+
}
353+
}
354+
355+
impl<'tcx> QueryKey for (crate::traits::solve::CanonicalInput<'tcx>, bool) {
356+
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
357+
DUMMY_SP
358+
}
359+
}
360+
361+
impl<'tcx> QueryKey for (crate::traits::solve::CanonicalInput<'tcx>, usize) {
362+
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
363+
DUMMY_SP
364+
}
365+
}
366+
349367
impl<'tcx> QueryKey for (Ty<'tcx>, rustc_abi::VariantIdx) {
350368
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
351369
DUMMY_SP

compiler/rustc_middle/src/traits/solve.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ pub type Goal<'tcx, P> = ir::solve::Goal<TyCtxt<'tcx>, P>;
1212
pub type QueryInput<'tcx, P> = ir::solve::QueryInput<TyCtxt<'tcx>, P>;
1313
pub type QueryResult<'tcx> = ir::solve::QueryResult<TyCtxt<'tcx>>;
1414
pub type CandidateSource<'tcx> = ir::solve::CandidateSource<TyCtxt<'tcx>>;
15-
pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir::solve::CanonicalInput<TyCtxt<'tcx>, P>;
15+
pub type CanonicalInputRaw<'tcx, P = ty::Predicate<'tcx>> =
16+
ir::solve::CanonicalInput<TyCtxt<'tcx>, P>;
1617
pub type CanonicalResponse<'tcx> = ir::solve::CanonicalResponse<TyCtxt<'tcx>>;
1718
pub type FetchEligibleAssocItemResponse<'tcx> =
1819
ir::solve::FetchEligibleAssocItemResponse<TyCtxt<'tcx>>;
@@ -23,6 +24,17 @@ pub type SucceededInErased<'tcx> = ir::solve::SucceededInErased<TyCtxt<'tcx>>;
2324

2425
pub type PredefinedOpaques<'tcx> = &'tcx ty::List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>;
2526

27+
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, StableHash)]
28+
pub struct CanonicalInput<'tcx>(pub(crate) Interned<'tcx, CanonicalInputData<TyCtxt<'tcx>>>);
29+
30+
impl<'tcx> std::ops::Deref for CanonicalInput<'tcx> {
31+
type Target = CanonicalInputData<TyCtxt<'tcx>>;
32+
33+
fn deref(&self) -> &Self::Target {
34+
&self.0
35+
}
36+
}
37+
2638
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, StableHash)]
2739
pub struct ExternalConstraints<'tcx>(
2840
pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,

compiler/rustc_middle/src/ty/context.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
6363
use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
6464
use crate::thir::Thir;
6565
use crate::traits;
66-
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
66+
use crate::traits::solve::{
67+
CanonicalInput, CanonicalInputData, ExternalConstraints, ExternalConstraintsData,
68+
PredefinedOpaques,
69+
};
6770
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
6871
use crate::ty::region::RegionExt;
6972
use crate::ty::{
@@ -162,6 +165,7 @@ pub struct CtxtInterners<'tcx> {
162165
valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
163166
patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
164167
outlives: InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>>,
168+
canonical_inputs: InternedSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>,
165169
}
166170

167171
impl<'tcx> CtxtInterners<'tcx> {
@@ -200,6 +204,7 @@ impl<'tcx> CtxtInterners<'tcx> {
200204
valtree: InternedSet::with_capacity(N),
201205
patterns: InternedSet::with_capacity(N),
202206
outlives: InternedSet::with_capacity(N),
207+
canonical_inputs: InternedSet::with_capacity(N),
203208
}
204209
}
205210

@@ -1990,6 +1995,7 @@ direct_interners! {
19901995
adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
19911996
external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
19921997
ExternalConstraints -> ExternalConstraints<'tcx>,
1998+
canonical_inputs: intern_canonical_input(CanonicalInputData<TyCtxt<'tcx>>): CanonicalInput -> CanonicalInput<'tcx>,
19931999
}
19942000

19952001
macro_rules! slice_interners {

compiler/rustc_middle/src/ty/context/impl_interner.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir::def::{CtorKind, DefKind};
1010
use rustc_hir::def_id::{DefId, LocalDefId};
1111
use rustc_span::{DUMMY_SP, Span, Symbol};
1212
use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
13+
use rustc_type_ir::solve::CanonicalInputData;
1314
use rustc_type_ir::{
1415
BoundVar, CollectAndApply, DebruijnIndex, Interner, TypeFoldable, Unnormalized, VisitorResult,
1516
search_graph, try_visit,
@@ -664,6 +665,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
664665
fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
665666
self.arena.alloc(probe)
666667
}
668+
type CanonicalInput = CanonicalInput<'tcx>;
669+
fn mk_canonical_input(self, data: impl Into<CanonicalInputData<Self>>) -> CanonicalInput<'tcx> {
670+
self.intern_canonical_input(data.into())
671+
}
667672
fn evaluate_root_goal_for_proof_tree_raw(
668673
self,
669674
canonical_goal: CanonicalInput<'tcx>,

compiler/rustc_next_trait_solver/src/canonical/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ use tracing::instrument;
2626

2727
use crate::delegate::SolverDelegate;
2828
use crate::solve::{
29-
CanonicalInput, CanonicalResponse, Certainty, ExternalConstraintsData,
30-
ExternalRegionConstraints, Goal, NestedNormalizationGoals, QueryInput, Response,
31-
VisibleForLeakCheck, inspect,
29+
CanonicalResponse, Certainty, ExternalConstraintsData, ExternalRegionConstraints, Goal,
30+
NestedNormalizationGoals, QueryInput, Response, VisibleForLeakCheck, inspect,
3231
};
3332

3433
pub mod canonicalizer;
@@ -58,7 +57,7 @@ pub(super) fn canonicalize_goal<D, I>(
5857
goal: Goal<I, I::Predicate>,
5958
opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)],
6059
typing_mode: TypingMode<I>,
61-
) -> (ThinVec<I::GenericArg>, CanonicalInput<I, I::Predicate>)
60+
) -> (ThinVec<I::GenericArg>, I::CanonicalInput)
6261
where
6362
D: SolverDelegate<Interner = I>,
6463
I: Interner,
@@ -71,8 +70,10 @@ where
7170
},
7271
);
7372

74-
let query_input =
75-
ty::CanonicalQueryInput { canonical, typing_mode: TypingModeEqWrapper(typing_mode) };
73+
let query_input = delegate.cx().mk_canonical_input(ty::CanonicalQueryInput {
74+
canonical,
75+
typing_mode: TypingModeEqWrapper(typing_mode),
76+
});
7677
(orig_values, query_input)
7778
}
7879

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ use crate::solve::fast_path::compute_goal_fast_path_cold;
4141
use crate::solve::search_graph::SearchGraph;
4242
use crate::solve::ty::may_use_unstable_feature;
4343
use crate::solve::{
44-
CanonicalInput, CanonicalResponse, Certainty, ExternalConstraintsData, FIXPOINT_STEP_LIMIT,
45-
Goal, GoalEvaluation, GoalSource, GoalStalledOn, GoalStalledOnOpaques, HasChanged, MaybeCause,
44+
CanonicalResponse, Certainty, ExternalConstraintsData, FIXPOINT_STEP_LIMIT, Goal,
45+
GoalEvaluation, GoalSource, GoalStalledOn, GoalStalledOnOpaques, HasChanged, MaybeCause,
4646
NestedNormalizationGoals, NoSolution, QueryInput, QueryResult, Response, SucceededInErased,
4747
VisibleForLeakCheck, inspect,
4848
};
@@ -516,7 +516,7 @@ where
516516
pub(super) fn enter_canonical<T>(
517517
cx: I,
518518
search_graph: &'a mut SearchGraph<D>,
519-
canonical_input: CanonicalInput<I>,
519+
canonical_input: I::CanonicalInput,
520520
proof_tree_builder: &mut inspect::ProofTreeBuilder<D>,
521521
f: impl FnOnce(
522522
&mut EvalCtxt<'_, D>,
@@ -833,7 +833,7 @@ where
833833

834834
fn build_stalled_on(
835835
&self,
836-
canonical_goal: CanonicalInput<I>,
836+
canonical_goal: I::CanonicalInput,
837837
maybe_info: MaybeInfo,
838838
stalled_vars: ThinVec<I::GenericArg>,
839839
previously_succeeded_in_erased: SucceededInErased<I>,
@@ -1827,7 +1827,7 @@ pub fn evaluate_root_goal_for_proof_tree_raw_provider<
18271827
I: Interner,
18281828
>(
18291829
cx: I,
1830-
canonical_goal: CanonicalInput<I>,
1830+
canonical_goal: I::CanonicalInput,
18311831
root_depth: usize,
18321832
) -> (QueryResult<I>, I::Probe, RequiredDepth) {
18331833
let mut inspect = inspect::ProofTreeBuilder::new();

compiler/rustc_next_trait_solver/src/solve/search_graph.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ use std::convert::Infallible;
22
use std::marker::PhantomData;
33

44
use rustc_type_ir::search_graph::{self, PathKind};
5-
use rustc_type_ir::solve::{
6-
AccessedOpaques, CanonicalInput, Certainty, NoSolution, QueryResult, RerunResultExt,
7-
};
5+
use rustc_type_ir::solve::{AccessedOpaques, Certainty, NoSolution, QueryResult, RerunResultExt};
86
use rustc_type_ir::{Interner, MayBeErased, TypingMode};
97

108
use crate::canonical::response_no_constraints_raw;
@@ -30,7 +28,7 @@ where
3028
type ValidationScope = Infallible;
3129
fn enter_validation_scope(
3230
_cx: Self::Cx,
33-
_input: CanonicalInput<I>,
31+
_input: I::CanonicalInput,
3432
) -> Option<Self::ValidationScope> {
3533
None
3634
}
@@ -47,7 +45,7 @@ where
4745
fn initial_provisional_result(
4846
cx: I,
4947
kind: PathKind,
50-
input: CanonicalInput<I>,
48+
input: I::CanonicalInput,
5149
) -> (QueryResult<I>, AccessedOpaques<I>) {
5250
match kind {
5351
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
@@ -101,15 +99,15 @@ where
10199

102100
fn stack_overflow_result(
103101
cx: I,
104-
input: CanonicalInput<I>,
102+
input: I::CanonicalInput,
105103
) -> (QueryResult<I>, AccessedOpaques<I>) {
106104
response_no_constraints(cx, input, Certainty::overflow(true))
107105
}
108106

109107
const FIXPOINT_OVERFLOW_AMBIGUITY_KIND: Certainty = Certainty::overflow(false);
110108
fn fixpoint_overflow_result(
111109
cx: I,
112-
input: CanonicalInput<I>,
110+
input: I::CanonicalInput,
113111
) -> (QueryResult<I>, AccessedOpaques<I>) {
114112
response_no_constraints(cx, input, Certainty::overflow(false))
115113
}
@@ -129,7 +127,7 @@ where
129127
fn compute_goal(
130128
search_graph: &mut SearchGraph<D>,
131129
cx: I,
132-
input: CanonicalInput<I>,
130+
input: I::CanonicalInput,
133131
inspect: &mut Self::ProofTreeBuilder,
134132
) -> (QueryResult<I>, AccessedOpaques<I>) {
135133
EvalCtxt::enter_canonical(cx, search_graph, input, inspect, |ecx, goal| {
@@ -144,7 +142,7 @@ where
144142

145143
fn response_no_constraints<I: Interner>(
146144
cx: I,
147-
input: CanonicalInput<I>,
145+
input: I::CanonicalInput,
148146
certainty: Certainty,
149147
) -> (QueryResult<I>, AccessedOpaques<I>) {
150148
(

compiler/rustc_trait_selection/src/solve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub use select::InferCtxtSelectExt;
1919

2020
fn evaluate_root_goal_for_proof_tree_raw<'tcx>(
2121
tcx: TyCtxt<'tcx>,
22-
key: (CanonicalInput<TyCtxt<'tcx>>, usize),
22+
key: (rustc_middle::traits::solve::CanonicalInput<'tcx>, usize),
2323
) -> (QueryResult<TyCtxt<'tcx>>, &'tcx inspect::Probe<TyCtxt<'tcx>>, RequiredDepth) {
2424
evaluate_root_goal_for_proof_tree_raw_provider::<SolverDelegate<'tcx>, TyCtxt<'tcx>>(
2525
tcx, key.0, key.1,

compiler/rustc_type_ir/src/interner.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTrait
1717
use crate::relate::Relate;
1818
use crate::search_graph::RequiredDepth;
1919
use crate::solve::{
20-
AccessedOpaques, CanonicalInput, Certainty, ExternalConstraintsData, QueryResult, inspect,
20+
AccessedOpaques, CanonicalInputData, Certainty, ExternalConstraintsData, QueryResult, inspect,
2121
};
2222
use crate::visit::{Flags, TypeVisitable};
2323
use crate::{
@@ -499,7 +499,7 @@ pub trait Interner:
499499
fn mk_probe(self, probe: inspect::Probe<Self>) -> Self::Probe;
500500
fn evaluate_root_goal_for_proof_tree_raw(
501501
self,
502-
canonical_goal: CanonicalInput<Self>,
502+
canonical_goal: Self::CanonicalInput,
503503
root_depth: usize,
504504
) -> (QueryResult<Self>, Self::Probe, RequiredDepth);
505505

@@ -520,6 +520,9 @@ pub trait Interner:
520520
) -> Region<Self>;
521521

522522
fn intern_canonical_bound(self, var: BoundVar) -> Region<Self>;
523+
524+
type CanonicalInput: Copy + Debug + Hash + Eq + Deref<Target = CanonicalInputData<Self>>;
525+
fn mk_canonical_input(self, data: impl Into<CanonicalInputData<Self>>) -> Self::CanonicalInput;
523526
}
524527

525528
macro_rules! declare_lift_into {
@@ -711,7 +714,7 @@ impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
711714
}
712715

713716
impl<I: Interner> search_graph::Cx for I {
714-
type Input = CanonicalInput<I>;
717+
type Input = I::CanonicalInput;
715718
type Result = (QueryResult<I>, AccessedOpaques<I>);
716719
type AmbiguityKind = Certainty;
717720

compiler/rustc_type_ir/src/solve/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,23 @@ impl<I: Interner> ExternalConstraintsData<I> {
662662
}
663663
}
664664

665+
#[derive_where(Clone, Hash, PartialEq, Eq, Debug; I: Interner)]
666+
#[derive_where(Copy; <I as Interner>::Predicate)]
667+
#[cfg_attr(feature = "nightly", derive(StableHash_NoContext))]
668+
pub struct CanonicalInputData<I: Interner>(pub(crate) CanonicalInput<I>);
669+
impl<I: Interner> From<CanonicalInput<I>> for CanonicalInputData<I> {
670+
fn from(value: CanonicalInput<I>) -> Self {
671+
CanonicalInputData(value)
672+
}
673+
}
674+
675+
impl<I: Interner> std::ops::Deref for CanonicalInputData<I> {
676+
type Target = CanonicalInput<I>;
677+
678+
fn deref(&self) -> &Self::Target {
679+
&self.0
680+
}
681+
}
665682
/// Whether the given region constraint should be considered/ignored for
666683
/// leak check. In most part of the compiler, this should be `Yes`, except
667684
/// for applying constraints from the nested goals in next-solver.

0 commit comments

Comments
 (0)