say what kind of cache hit
This commit is contained in:
parent
a2050ba12d
commit
3587d4ced8
3 changed files with 24 additions and 11 deletions
|
@ -2,6 +2,12 @@ use super::{CanonicalInput, Certainty, Goal, NoSolution, QueryInput, QueryResult
|
||||||
use crate::ty;
|
use crate::ty;
|
||||||
use std::fmt::{Debug, Write};
|
use std::fmt::{Debug, Write};
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Hash, HashStable)]
|
||||||
|
pub enum CacheHit {
|
||||||
|
Provisional,
|
||||||
|
Global,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, HashStable)]
|
#[derive(Eq, PartialEq, Hash, HashStable)]
|
||||||
pub struct GoalEvaluation<'tcx> {
|
pub struct GoalEvaluation<'tcx> {
|
||||||
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||||
|
@ -12,7 +18,7 @@ pub struct GoalEvaluation<'tcx> {
|
||||||
/// is represented as an entry in this vec.
|
/// is represented as an entry in this vec.
|
||||||
pub evaluation_steps: Vec<GoalEvaluationStep<'tcx>>,
|
pub evaluation_steps: Vec<GoalEvaluationStep<'tcx>>,
|
||||||
|
|
||||||
pub cache_hit: bool,
|
pub cache_hit: Option<CacheHit>,
|
||||||
|
|
||||||
pub result: Option<QueryResult<'tcx>>,
|
pub result: Option<QueryResult<'tcx>>,
|
||||||
}
|
}
|
||||||
|
@ -92,8 +98,9 @@ impl ProofTreeFormatter<'_, '_> {
|
||||||
writeln!(f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?;
|
writeln!(f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?;
|
||||||
|
|
||||||
match goal.cache_hit {
|
match goal.cache_hit {
|
||||||
true => writeln!(f, "CACHE HIT: {:?}", goal.result),
|
Some(CacheHit::Global) => writeln!(f, "GLOBAL CACHE HIT: {:?}", goal.result),
|
||||||
false => {
|
Some(CacheHit::Provisional) => writeln!(f, "PROVISIONAL CACHE HIT: {:?}", goal.result),
|
||||||
|
None => {
|
||||||
for (n, step) in goal.evaluation_steps.iter().enumerate() {
|
for (n, step) in goal.evaluation_steps.iter().enumerate() {
|
||||||
let f = &mut *self.f;
|
let f = &mut *self.f;
|
||||||
writeln!(f, "REVISION {n}: {:?}", step.result.unwrap())?;
|
writeln!(f, "REVISION {n}: {:?}", step.result.unwrap())?;
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub trait InspectSolve<'tcx> {
|
||||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||||
) -> Box<dyn InspectSolve<'tcx> + 'tcx>;
|
) -> Box<dyn InspectSolve<'tcx> + 'tcx>;
|
||||||
fn canonicalized_goal(&mut self, canonical_goal: CanonicalInput<'tcx>);
|
fn canonicalized_goal(&mut self, canonical_goal: CanonicalInput<'tcx>);
|
||||||
fn cache_hit(&mut self);
|
fn cache_hit(&mut self, cache_hit: CacheHit);
|
||||||
fn goal_evaluation(&mut self, goal_evaluation: Box<dyn InspectSolve<'tcx> + 'tcx>);
|
fn goal_evaluation(&mut self, goal_evaluation: Box<dyn InspectSolve<'tcx> + 'tcx>);
|
||||||
|
|
||||||
fn new_goal_evaluation_step(
|
fn new_goal_evaluation_step(
|
||||||
|
@ -59,7 +59,7 @@ impl<'tcx> InspectSolve<'tcx> for () {
|
||||||
Box::new(())
|
Box::new(())
|
||||||
}
|
}
|
||||||
fn canonicalized_goal(&mut self, _canonical_goal: CanonicalInput<'tcx>) {}
|
fn canonicalized_goal(&mut self, _canonical_goal: CanonicalInput<'tcx>) {}
|
||||||
fn cache_hit(&mut self) {}
|
fn cache_hit(&mut self, _cache_hit: CacheHit) {}
|
||||||
fn goal_evaluation(&mut self, _goal_evaluation: Box<dyn InspectSolve<'tcx> + 'tcx>) {}
|
fn goal_evaluation(&mut self, _goal_evaluation: Box<dyn InspectSolve<'tcx> + 'tcx>) {}
|
||||||
|
|
||||||
fn new_goal_evaluation_step(
|
fn new_goal_evaluation_step(
|
||||||
|
@ -104,7 +104,7 @@ impl<'tcx> InspectSolve<'tcx> for DebugSolver<'tcx> {
|
||||||
uncanonicalized_goal: goal,
|
uncanonicalized_goal: goal,
|
||||||
canonicalized_goal: None,
|
canonicalized_goal: None,
|
||||||
evaluation_steps: vec![],
|
evaluation_steps: vec![],
|
||||||
cache_hit: false,
|
cache_hit: None,
|
||||||
result: None,
|
result: None,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -117,9 +117,11 @@ impl<'tcx> InspectSolve<'tcx> for DebugSolver<'tcx> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn cache_hit(&mut self) {
|
fn cache_hit(&mut self, cache_hit: CacheHit) {
|
||||||
match self {
|
match self {
|
||||||
DebugSolver::GoalEvaluation(goal_evaluation) => goal_evaluation.cache_hit = true,
|
DebugSolver::GoalEvaluation(goal_evaluation) => {
|
||||||
|
goal_evaluation.cache_hit = Some(cache_hit)
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod cache;
|
||||||
mod overflow;
|
mod overflow;
|
||||||
|
|
||||||
pub(super) use overflow::OverflowHandler;
|
pub(super) use overflow::OverflowHandler;
|
||||||
|
use rustc_middle::traits::solve::inspect::CacheHit;
|
||||||
|
|
||||||
use self::cache::ProvisionalEntry;
|
use self::cache::ProvisionalEntry;
|
||||||
use cache::ProvisionalCache;
|
use cache::ProvisionalCache;
|
||||||
|
@ -89,11 +90,12 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||||
/// Tries putting the new goal on the stack, returning an error if it is already cached.
|
/// Tries putting the new goal on the stack, returning an error if it is already cached.
|
||||||
///
|
///
|
||||||
/// This correctly updates the provisional cache if there is a cycle.
|
/// This correctly updates the provisional cache if there is a cycle.
|
||||||
#[instrument(level = "debug", skip(self, tcx), ret)]
|
#[instrument(level = "debug", skip(self, tcx, inspect), ret)]
|
||||||
fn try_push_stack(
|
fn try_push_stack(
|
||||||
&mut self,
|
&mut self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
input: CanonicalInput<'tcx>,
|
input: CanonicalInput<'tcx>,
|
||||||
|
inspect: &mut dyn InspectSolve<'tcx>,
|
||||||
) -> Result<(), QueryResult<'tcx>> {
|
) -> Result<(), QueryResult<'tcx>> {
|
||||||
// Look at the provisional cache to check for cycles.
|
// Look at the provisional cache to check for cycles.
|
||||||
let cache = &mut self.provisional_cache;
|
let cache = &mut self.provisional_cache;
|
||||||
|
@ -120,6 +122,8 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||||
// Finally we can return either the provisional response for that goal if we have a
|
// Finally we can return either the provisional response for that goal if we have a
|
||||||
// coinductive cycle or an ambiguous result if the cycle is inductive.
|
// coinductive cycle or an ambiguous result if the cycle is inductive.
|
||||||
Entry::Occupied(entry_index) => {
|
Entry::Occupied(entry_index) => {
|
||||||
|
inspect.cache_hit(CacheHit::Provisional);
|
||||||
|
|
||||||
let entry_index = *entry_index.get();
|
let entry_index = *entry_index.get();
|
||||||
|
|
||||||
let stack_depth = cache.depth(entry_index);
|
let stack_depth = cache.depth(entry_index);
|
||||||
|
@ -212,12 +216,12 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||||
if self.should_use_global_cache() {
|
if self.should_use_global_cache() {
|
||||||
if let Some(result) = tcx.new_solver_evaluation_cache.get(&canonical_input, tcx) {
|
if let Some(result) = tcx.new_solver_evaluation_cache.get(&canonical_input, tcx) {
|
||||||
debug!(?canonical_input, ?result, "cache hit");
|
debug!(?canonical_input, ?result, "cache hit");
|
||||||
inspect.cache_hit();
|
inspect.cache_hit(CacheHit::Global);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.try_push_stack(tcx, canonical_input) {
|
match self.try_push_stack(tcx, canonical_input, inspect) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
// Our goal is already on the stack, eager return.
|
// Our goal is already on the stack, eager return.
|
||||||
Err(response) => return response,
|
Err(response) => return response,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue