say what kind of cache hit

This commit is contained in:
Boxy 2023-06-08 19:21:55 +01:00
parent a2050ba12d
commit 3587d4ced8
3 changed files with 24 additions and 11 deletions

View file

@ -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())?;

View file

@ -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!(),
}; };
} }

View file

@ -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,