new solver: add a separate cache for coherence
This commit is contained in:
parent
78f97c9b25
commit
303af36be7
@ -569,6 +569,7 @@ pub struct GlobalCtxt<'tcx> {
|
|||||||
|
|
||||||
/// Caches the results of goal evaluation in the new solver.
|
/// Caches the results of goal evaluation in the new solver.
|
||||||
pub new_solver_evaluation_cache: solve::EvaluationCache<'tcx>,
|
pub new_solver_evaluation_cache: solve::EvaluationCache<'tcx>,
|
||||||
|
pub new_solver_coherence_evaluation_cache: solve::EvaluationCache<'tcx>,
|
||||||
|
|
||||||
/// Data layout specification for the current target.
|
/// Data layout specification for the current target.
|
||||||
pub data_layout: TargetDataLayout,
|
pub data_layout: TargetDataLayout,
|
||||||
@ -680,10 +681,12 @@ pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> {
|
|||||||
value.lift_to_tcx(self)
|
value.lift_to_tcx(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a type context and call the closure with a `TyCtxt` reference
|
/// Creates a type context. To use the context call `fn enter` which
|
||||||
/// to the context. The closure enforces that the type context and any interned
|
/// provides a `TyCtxt`.
|
||||||
/// value (types, args, etc.) can only be used while `ty::tls` has a valid
|
///
|
||||||
/// reference to the context, to allow formatting values that need it.
|
/// By only providing the `TyCtxt` inside of the closure we enforce that the type
|
||||||
|
/// context and any interned alue (types, args, etc.) can only be used while `ty::tls`
|
||||||
|
/// has a valid reference to the context, to allow formatting values that need it.
|
||||||
pub fn create_global_ctxt(
|
pub fn create_global_ctxt(
|
||||||
s: &'tcx Session,
|
s: &'tcx Session,
|
||||||
lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
|
lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
|
||||||
@ -721,6 +724,7 @@ pub fn create_global_ctxt(
|
|||||||
selection_cache: Default::default(),
|
selection_cache: Default::default(),
|
||||||
evaluation_cache: Default::default(),
|
evaluation_cache: Default::default(),
|
||||||
new_solver_evaluation_cache: Default::default(),
|
new_solver_evaluation_cache: Default::default(),
|
||||||
|
new_solver_coherence_evaluation_cache: Default::default(),
|
||||||
data_layout,
|
data_layout,
|
||||||
alloc_map: Lock::new(interpret::AllocMap::new()),
|
alloc_map: Lock::new(interpret::AllocMap::new()),
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
use overflow::OverflowData;
|
use overflow::OverflowData;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_middle::dep_graph::DepKind;
|
use rustc_middle::dep_graph::DepKind;
|
||||||
use rustc_middle::traits::solve::{CanonicalInput, Certainty, MaybeCause, QueryResult};
|
use rustc_middle::traits::solve::{
|
||||||
|
CanonicalInput, Certainty, EvaluationCache, MaybeCause, QueryResult,
|
||||||
|
};
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use std::{collections::hash_map::Entry, mem};
|
use std::{collections::hash_map::Entry, mem};
|
||||||
|
|
||||||
@ -58,10 +60,10 @@ pub(super) fn solver_mode(&self) -> SolverMode {
|
|||||||
///
|
///
|
||||||
/// We could add another global cache for coherence instead,
|
/// We could add another global cache for coherence instead,
|
||||||
/// but that's effort so let's only do it if necessary.
|
/// but that's effort so let's only do it if necessary.
|
||||||
pub(super) fn should_use_global_cache(&self) -> bool {
|
pub(super) fn global_cache(&self, tcx: TyCtxt<'tcx>) -> &'tcx EvaluationCache<'tcx> {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
SolverMode::Normal => true,
|
SolverMode::Normal => &tcx.new_solver_evaluation_cache,
|
||||||
SolverMode::Coherence => false,
|
SolverMode::Coherence => &tcx.new_solver_coherence_evaluation_cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,8 +215,8 @@ pub(super) fn with_new_goal(
|
|||||||
inspect: &mut ProofTreeBuilder<'tcx>,
|
inspect: &mut ProofTreeBuilder<'tcx>,
|
||||||
mut loop_body: impl FnMut(&mut Self, &mut ProofTreeBuilder<'tcx>) -> QueryResult<'tcx>,
|
mut loop_body: impl FnMut(&mut Self, &mut ProofTreeBuilder<'tcx>) -> QueryResult<'tcx>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
if self.should_use_global_cache() && inspect.use_global_cache() {
|
if inspect.use_global_cache() {
|
||||||
if let Some(result) = tcx.new_solver_evaluation_cache.get(&canonical_input, tcx) {
|
if let Some(result) = self.global_cache(tcx).get(&canonical_input, tcx) {
|
||||||
debug!(?canonical_input, ?result, "cache hit");
|
debug!(?canonical_input, ?result, "cache hit");
|
||||||
inspect.cache_hit(CacheHit::Global);
|
inspect.cache_hit(CacheHit::Global);
|
||||||
return result;
|
return result;
|
||||||
@ -278,13 +280,10 @@ pub(super) fn with_new_goal(
|
|||||||
// dependencies, our non-root goal may no longer appear as child of the root goal.
|
// dependencies, our non-root goal may no longer appear as child of the root goal.
|
||||||
//
|
//
|
||||||
// See https://github.com/rust-lang/rust/pull/108071 for some additional context.
|
// See https://github.com/rust-lang/rust/pull/108071 for some additional context.
|
||||||
let can_cache = !self.overflow_data.did_overflow() || self.stack.is_empty();
|
let can_cache = inspect.use_global_cache()
|
||||||
if self.should_use_global_cache() && can_cache {
|
&& (!self.overflow_data.did_overflow() || self.stack.is_empty());
|
||||||
tcx.new_solver_evaluation_cache.insert(
|
if can_cache {
|
||||||
current_goal.input,
|
self.global_cache(tcx).insert(current_goal.input, dep_node, current_goal.response)
|
||||||
dep_node,
|
|
||||||
current_goal.response,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user