1
Fork 0

Compute query vtable manually.

This commit is contained in:
Camille GILLOT 2021-07-11 20:08:17 +02:00
parent 69a3594635
commit df71d0874a
2 changed files with 29 additions and 27 deletions

View file

@ -24,6 +24,7 @@ pub(crate) struct QueryVtable<CTX: QueryContext, K, V> {
pub dep_kind: CTX::DepKind, pub dep_kind: CTX::DepKind,
pub eval_always: bool, pub eval_always: bool,
pub compute: fn(CTX::DepContext, K) -> V,
pub hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>, pub hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,
pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V, pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V,
pub cache_on_disk: fn(CTX, &K, Option<&V>) -> bool, pub cache_on_disk: fn(CTX, &K, Option<&V>) -> bool,
@ -38,6 +39,10 @@ impl<CTX: QueryContext, K, V> QueryVtable<CTX, K, V> {
DepNode::construct(tcx, self.dep_kind, key) DepNode::construct(tcx, self.dep_kind, key)
} }
pub(crate) fn compute(&self, tcx: CTX::DepContext, key: K) -> V {
(self.compute)(tcx, key)
}
pub(crate) fn cache_on_disk(&self, tcx: CTX, key: &K, value: Option<&V>) -> bool { pub(crate) fn cache_on_disk(&self, tcx: CTX, key: &K, value: Option<&V>) -> bool {
(self.cache_on_disk)(tcx, key, value) (self.cache_on_disk)(tcx, key, value)
} }
@ -87,7 +92,7 @@ pub trait QueryDescription<CTX: QueryContext>: QueryAccessors<CTX> {
} }
pub(crate) trait QueryVtableExt<CTX: QueryContext, K, V> { pub(crate) trait QueryVtableExt<CTX: QueryContext, K, V> {
const VTABLE: QueryVtable<CTX, K, V>; fn make_vtable(tcx: CTX, key: &K) -> QueryVtable<CTX, K, V>;
} }
impl<CTX, Q> QueryVtableExt<CTX, Q::Key, Q::Value> for Q impl<CTX, Q> QueryVtableExt<CTX, Q::Key, Q::Value> for Q
@ -95,13 +100,16 @@ where
CTX: QueryContext, CTX: QueryContext,
Q: QueryDescription<CTX>, Q: QueryDescription<CTX>,
{ {
const VTABLE: QueryVtable<CTX, Q::Key, Q::Value> = QueryVtable { fn make_vtable(tcx: CTX, key: &Q::Key) -> QueryVtable<CTX, Q::Key, Q::Value> {
anon: Q::ANON, QueryVtable {
dep_kind: Q::DEP_KIND, anon: Q::ANON,
eval_always: Q::EVAL_ALWAYS, dep_kind: Q::DEP_KIND,
hash_result: Q::HASH_RESULT, eval_always: Q::EVAL_ALWAYS,
handle_cycle_error: Q::handle_cycle_error, hash_result: Q::HASH_RESULT,
cache_on_disk: Q::cache_on_disk, compute: Q::compute_fn(tcx, key),
try_load_from_disk: Q::try_load_from_disk, handle_cycle_error: Q::handle_cycle_error,
}; cache_on_disk: Q::cache_on_disk,
try_load_from_disk: Q::try_load_from_disk,
}
}
} }

View file

@ -382,7 +382,6 @@ fn try_execute_query<CTX, C>(
lookup: QueryLookup, lookup: QueryLookup,
dep_node: Option<DepNode<CTX::DepKind>>, dep_node: Option<DepNode<CTX::DepKind>>,
query: &QueryVtable<CTX, C::Key, C::Value>, query: &QueryVtable<CTX, C::Key, C::Value>,
compute: fn(CTX::DepContext, C::Key) -> C::Value,
) -> (C::Stored, Option<DepNodeIndex>) ) -> (C::Stored, Option<DepNodeIndex>)
where where
C: QueryCache, C: QueryCache,
@ -398,7 +397,7 @@ where
query.dep_kind, query.dep_kind,
) { ) {
TryGetJob::NotYetStarted(job) => { TryGetJob::NotYetStarted(job) => {
let (result, dep_node_index) = execute_job(tcx, key, dep_node, query, job.id, compute); let (result, dep_node_index) = execute_job(tcx, key, dep_node, query, job.id);
let result = job.complete(cache, result, dep_node_index); let result = job.complete(cache, result, dep_node_index);
(result, Some(dep_node_index)) (result, Some(dep_node_index))
} }
@ -429,7 +428,6 @@ fn execute_job<CTX, K, V>(
mut dep_node_opt: Option<DepNode<CTX::DepKind>>, mut dep_node_opt: Option<DepNode<CTX::DepKind>>,
query: &QueryVtable<CTX, K, V>, query: &QueryVtable<CTX, K, V>,
job_id: QueryJobId<CTX::DepKind>, job_id: QueryJobId<CTX::DepKind>,
compute: fn(CTX::DepContext, K) -> V,
) -> (V, DepNodeIndex) ) -> (V, DepNodeIndex)
where where
K: Clone + DepNodeParams<CTX::DepContext>, K: Clone + DepNodeParams<CTX::DepContext>,
@ -441,7 +439,7 @@ where
// Fast path for when incr. comp. is off. // Fast path for when incr. comp. is off.
if !dep_graph.is_fully_enabled() { if !dep_graph.is_fully_enabled() {
let prof_timer = tcx.dep_context().profiler().query_provider(); let prof_timer = tcx.dep_context().profiler().query_provider();
let result = tcx.start_query(job_id, None, || compute(*tcx.dep_context(), key)); let result = tcx.start_query(job_id, None, || query.compute(*tcx.dep_context(), key));
let dep_node_index = dep_graph.next_virtual_depnode_index(); let dep_node_index = dep_graph.next_virtual_depnode_index();
prof_timer.finish_with_query_invocation_id(dep_node_index.into()); prof_timer.finish_with_query_invocation_id(dep_node_index.into());
return (result, dep_node_index); return (result, dep_node_index);
@ -455,7 +453,7 @@ where
// The diagnostics for this query will be promoted to the current session during // The diagnostics for this query will be promoted to the current session during
// `try_mark_green()`, so we can ignore them here. // `try_mark_green()`, so we can ignore them here.
if let Some(ret) = tcx.start_query(job_id, None, || { if let Some(ret) = tcx.start_query(job_id, None, || {
try_load_from_disk_and_cache_in_memory(tcx, &key, &dep_node, query, compute) try_load_from_disk_and_cache_in_memory(tcx, &key, &dep_node, query)
}) { }) {
return ret; return ret;
} }
@ -467,14 +465,14 @@ where
let (result, dep_node_index) = tcx.start_query(job_id, Some(&diagnostics), || { let (result, dep_node_index) = tcx.start_query(job_id, Some(&diagnostics), || {
if query.anon { if query.anon {
return dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || { return dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || {
compute(*tcx.dep_context(), key) query.compute(*tcx.dep_context(), key)
}); });
} }
// `to_dep_node` is expensive for some `DepKind`s. // `to_dep_node` is expensive for some `DepKind`s.
let dep_node = dep_node_opt.unwrap_or_else(|| query.to_dep_node(*tcx.dep_context(), &key)); let dep_node = dep_node_opt.unwrap_or_else(|| query.to_dep_node(*tcx.dep_context(), &key));
dep_graph.with_task(dep_node, *tcx.dep_context(), key, compute, query.hash_result) dep_graph.with_task(dep_node, *tcx.dep_context(), key, query.compute, query.hash_result)
}); });
prof_timer.finish_with_query_invocation_id(dep_node_index.into()); prof_timer.finish_with_query_invocation_id(dep_node_index.into());
@ -498,7 +496,6 @@ fn try_load_from_disk_and_cache_in_memory<CTX, K, V>(
key: &K, key: &K,
dep_node: &DepNode<CTX::DepKind>, dep_node: &DepNode<CTX::DepKind>,
query: &QueryVtable<CTX, K, V>, query: &QueryVtable<CTX, K, V>,
compute: fn(CTX::DepContext, K) -> V,
) -> Option<(V, DepNodeIndex)> ) -> Option<(V, DepNodeIndex)>
where where
K: Clone, K: Clone,
@ -544,7 +541,7 @@ where
let prof_timer = tcx.dep_context().profiler().query_provider(); let prof_timer = tcx.dep_context().profiler().query_provider();
// The dep-graph for this computation is already in-place. // The dep-graph for this computation is already in-place.
let result = dep_graph.with_ignore(|| compute(*tcx.dep_context(), key.clone())); let result = dep_graph.with_ignore(|| query.compute(*tcx.dep_context(), key.clone()));
prof_timer.finish_with_query_invocation_id(dep_node_index.into()); prof_timer.finish_with_query_invocation_id(dep_node_index.into());
@ -682,9 +679,9 @@ where
Q::Key: DepNodeParams<CTX::DepContext>, Q::Key: DepNodeParams<CTX::DepContext>,
CTX: QueryContext, CTX: QueryContext,
{ {
let query = &Q::VTABLE; let query = Q::make_vtable(tcx, &key);
let dep_node = if let QueryMode::Ensure = mode { let dep_node = if let QueryMode::Ensure = mode {
let (must_run, dep_node) = ensure_must_run(tcx, &key, query); let (must_run, dep_node) = ensure_must_run(tcx, &key, &query);
if !must_run { if !must_run {
return None; return None;
} }
@ -694,7 +691,6 @@ where
}; };
debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME, key, span); debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME, key, span);
let compute = Q::compute_fn(tcx, &key);
let (result, dep_node_index) = try_execute_query( let (result, dep_node_index) = try_execute_query(
tcx, tcx,
Q::query_state(tcx), Q::query_state(tcx),
@ -703,8 +699,7 @@ where
key, key,
lookup, lookup,
dep_node, dep_node,
query, &query,
compute,
); );
if let Some(dep_node_index) = dep_node_index { if let Some(dep_node_index) = dep_node_index {
tcx.dep_context().dep_graph().read_index(dep_node_index) tcx.dep_context().dep_graph().read_index(dep_node_index)
@ -718,7 +713,6 @@ where
Q::Key: DepNodeParams<CTX::DepContext>, Q::Key: DepNodeParams<CTX::DepContext>,
CTX: QueryContext, CTX: QueryContext,
{ {
let query = &Q::VTABLE;
debug_assert!(!Q::ANON); debug_assert!(!Q::ANON);
// We may be concurrently trying both execute and force a query. // We may be concurrently trying both execute and force a query.
@ -735,7 +729,7 @@ where
Err(lookup) => lookup, Err(lookup) => lookup,
}; };
let compute = Q::compute_fn(tcx, &key); let query = Q::make_vtable(tcx, &key);
let state = Q::query_state(tcx); let state = Q::query_state(tcx);
try_execute_query(tcx, state, cache, DUMMY_SP, key, lookup, Some(dep_node), query, compute); try_execute_query(tcx, state, cache, DUMMY_SP, key, lookup, Some(dep_node), &query);
} }