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 eval_always: bool,
pub compute: fn(CTX::DepContext, K) -> V,
pub hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,
pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V,
pub cache_on_disk: fn(CTX, &K, Option<&V>) -> bool,
@ -38,6 +39,10 @@ pub(crate) fn to_dep_node(&self, tcx: CTX::DepContext, key: &K) -> DepNode<CTX::
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 {
(self.cache_on_disk)(tcx, key, value)
}
@ -87,7 +92,7 @@ fn try_load_from_disk(_: CTX, _: SerializedDepNodeIndex) -> Option<Self::Value>
}
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
@ -95,13 +100,16 @@ impl<CTX, Q> QueryVtableExt<CTX, Q::Key, Q::Value> for Q
CTX: QueryContext,
Q: QueryDescription<CTX>,
{
const VTABLE: QueryVtable<CTX, Q::Key, Q::Value> = QueryVtable {
anon: Q::ANON,
dep_kind: Q::DEP_KIND,
eval_always: Q::EVAL_ALWAYS,
hash_result: Q::HASH_RESULT,
handle_cycle_error: Q::handle_cycle_error,
cache_on_disk: Q::cache_on_disk,
try_load_from_disk: Q::try_load_from_disk,
};
fn make_vtable(tcx: CTX, key: &Q::Key) -> QueryVtable<CTX, Q::Key, Q::Value> {
QueryVtable {
anon: Q::ANON,
dep_kind: Q::DEP_KIND,
eval_always: Q::EVAL_ALWAYS,
hash_result: Q::HASH_RESULT,
compute: Q::compute_fn(tcx, key),
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,
dep_node: Option<DepNode<CTX::DepKind>>,
query: &QueryVtable<CTX, C::Key, C::Value>,
compute: fn(CTX::DepContext, C::Key) -> C::Value,
) -> (C::Stored, Option<DepNodeIndex>)
where
C: QueryCache,
@ -398,7 +397,7 @@ fn try_execute_query<CTX, C>(
query.dep_kind,
) {
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);
(result, Some(dep_node_index))
}
@ -429,7 +428,6 @@ fn execute_job<CTX, K, V>(
mut dep_node_opt: Option<DepNode<CTX::DepKind>>,
query: &QueryVtable<CTX, K, V>,
job_id: QueryJobId<CTX::DepKind>,
compute: fn(CTX::DepContext, K) -> V,
) -> (V, DepNodeIndex)
where
K: Clone + DepNodeParams<CTX::DepContext>,
@ -441,7 +439,7 @@ fn execute_job<CTX, K, V>(
// Fast path for when incr. comp. is off.
if !dep_graph.is_fully_enabled() {
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();
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
return (result, dep_node_index);
@ -455,7 +453,7 @@ fn execute_job<CTX, K, V>(
// The diagnostics for this query will be promoted to the current session during
// `try_mark_green()`, so we can ignore them here.
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;
}
@ -467,14 +465,14 @@ fn execute_job<CTX, K, V>(
let (result, dep_node_index) = tcx.start_query(job_id, Some(&diagnostics), || {
if query.anon {
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.
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());
@ -498,7 +496,6 @@ fn try_load_from_disk_and_cache_in_memory<CTX, K, V>(
key: &K,
dep_node: &DepNode<CTX::DepKind>,
query: &QueryVtable<CTX, K, V>,
compute: fn(CTX::DepContext, K) -> V,
) -> Option<(V, DepNodeIndex)>
where
K: Clone,
@ -544,7 +541,7 @@ fn try_load_from_disk_and_cache_in_memory<CTX, K, V>(
let prof_timer = tcx.dep_context().profiler().query_provider();
// 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());
@ -682,9 +679,9 @@ pub fn get_query<Q, CTX>(
Q::Key: DepNodeParams<CTX::DepContext>,
CTX: QueryContext,
{
let query = &Q::VTABLE;
let query = Q::make_vtable(tcx, &key);
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 {
return None;
}
@ -694,7 +691,6 @@ pub fn get_query<Q, CTX>(
};
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(
tcx,
Q::query_state(tcx),
@ -703,8 +699,7 @@ pub fn get_query<Q, CTX>(
key,
lookup,
dep_node,
query,
compute,
&query,
);
if let Some(dep_node_index) = dep_node_index {
tcx.dep_context().dep_graph().read_index(dep_node_index)
@ -718,7 +713,6 @@ pub fn force_query<Q, CTX>(tcx: CTX, key: Q::Key, dep_node: DepNode<CTX::DepKind
Q::Key: DepNodeParams<CTX::DepContext>,
CTX: QueryContext,
{
let query = &Q::VTABLE;
debug_assert!(!Q::ANON);
// We may be concurrently trying both execute and force a query.
@ -735,7 +729,7 @@ pub fn force_query<Q, CTX>(tcx: CTX, key: Q::Key, dep_node: DepNode<CTX::DepKind
Err(lookup) => lookup,
};
let compute = Q::compute_fn(tcx, &key);
let query = Q::make_vtable(tcx, &key);
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);
}