]> git.lizzy.rs Git - rust.git/commitdiff
Generalise Query starting.
authorCamille GILLOT <gillot.camille@gmail.com>
Thu, 19 Mar 2020 17:31:17 +0000 (18:31 +0100)
committerCamille GILLOT <gillot.camille@gmail.com>
Thu, 26 Mar 2020 08:22:46 +0000 (09:22 +0100)
src/librustc/dep_graph/mod.rs
src/librustc/ty/query/config.rs
src/librustc/ty/query/plumbing.rs
src/librustc_query_system/dep_graph/mod.rs

index dfb962227ffe3abe80ddb7ba100b944337e98313..556b1479b613a2afd8f86a110bd9df73b3dc7905 100644 (file)
@@ -166,6 +166,10 @@ fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec<D
         self.queries.on_disk_cache.store_diagnostics(dep_node_index, diagnostics)
     }
 
+    fn store_diagnostics_for_anon_node(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec<Diagnostic>) {
+        self.queries.on_disk_cache.store_diagnostics_for_anon_node(dep_node_index, diagnostics)
+    }
+
     fn profiler(&self) -> &SelfProfilerRef {
         &self.prof
     }
index 04662986702a935a0168b6ae50df8c7e5a480150..91e82858b0b5a7c0ca86c92289c59d5a29f12426 100644 (file)
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::HashStable;
-use rustc_query_system::dep_graph::{DepContext, DepNode};
+use rustc_data_structures::sync::Lock;
+use rustc_data_structures::thin_vec::ThinVec;
+use rustc_errors::Diagnostic;
+use rustc_query_system::dep_graph::{DepContext, DepGraph, DepNode};
 use rustc_session::Session;
 use std::borrow::Cow;
 use std::fmt::Debug;
@@ -34,12 +37,25 @@ pub trait QueryContext: DepContext {
     /// Get string representation from DefPath.
     fn def_path_str(&self, def_id: DefId) -> String;
 
+    /// Access the DepGraph.
+    fn dep_graph(&self) -> &DepGraph<Self::DepKind>;
+
     /// Get the query information from the TLS context.
     fn read_query_job<R>(&self, op: impl FnOnce(Option<QueryJobId<Self::DepKind>>) -> R) -> R;
 
     fn try_collect_active_jobs(
         &self,
     ) -> Option<FxHashMap<QueryJobId<Self::DepKind>, QueryJobInfo<Self>>>;
+
+    /// Executes a job by changing the `ImplicitCtxt` to point to the
+    /// new query job while it executes. It returns the diagnostics
+    /// captured during execution and the actual result.
+    fn start_query<R>(
+        &self,
+        token: QueryJobId<Self::DepKind>,
+        diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
+        compute: impl FnOnce(Self) -> R,
+    ) -> R;
 }
 
 pub(crate) trait QueryAccessors<CTX: QueryContext>: QueryConfig<CTX> {
index 75420634a5a0e7a8638c4879770a6181e0695714..ae0ca080dac56f42111c9ca5212cce170734dd95 100644 (file)
@@ -7,7 +7,7 @@
 use crate::ty::query::config::{QueryContext, QueryDescription};
 use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId};
 use crate::ty::query::Query;
-use crate::ty::tls;
+use crate::ty::tls::{self, ImplicitCtxt};
 use crate::ty::{self, TyCtxt};
 
 #[cfg(not(parallel_compiler))]
@@ -17,7 +17,8 @@
 use rustc_data_structures::sync::{Lock, LockGuard};
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, FatalError, Handler, Level};
-use rustc_query_system::dep_graph::{DepKind, DepNode};
+use rustc_query_system::dep_graph::{DepContext, DepGraph, DepKind, DepNode};
+use rustc_query_system::HashStableContextProvider;
 use rustc_session::Session;
 use rustc_span::def_id::DefId;
 use rustc_span::source_map::DUMMY_SP;
@@ -364,6 +365,10 @@ fn def_path_str(&self, def_id: DefId) -> String {
         TyCtxt::def_path_str(*self, def_id)
     }
 
+    fn dep_graph(&self) -> &DepGraph<Self::DepKind> {
+        &self.dep_graph
+    }
+
     fn read_query_job<R>(&self, op: impl FnOnce(Option<QueryJobId<Self::DepKind>>) -> R) -> R {
         tls::with_related_context(*self, move |icx| op(icx.query))
     }
@@ -373,29 +378,24 @@ fn try_collect_active_jobs(
     ) -> Option<FxHashMap<QueryJobId<Self::DepKind>, QueryJobInfo<Self>>> {
         self.queries.try_collect_active_jobs()
     }
-}
 
-impl<'tcx> TyCtxt<'tcx> {
     /// Executes a job by changing the `ImplicitCtxt` to point to the
     /// new query job while it executes. It returns the diagnostics
     /// captured during execution and the actual result.
     #[inline(always)]
-    fn start_query<F, R>(
-        self,
-        token: QueryJobId<crate::dep_graph::DepKind>,
+    fn start_query<R>(
+        &self,
+        token: QueryJobId<Self::DepKind>,
         diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
-        compute: F,
-    ) -> R
-    where
-        F: FnOnce(TyCtxt<'tcx>) -> R,
-    {
+        compute: impl FnOnce(Self) -> R,
+    ) -> R {
         // The `TyCtxt` stored in TLS has the same global interner lifetime
         // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
         // when accessing the `ImplicitCtxt`.
-        tls::with_related_context(self, move |current_icx| {
+        tls::with_related_context(*self, move |current_icx| {
             // Update the `ImplicitCtxt` to point to our new query job.
-            let new_icx = tls::ImplicitCtxt {
-                tcx: self,
+            let new_icx = ImplicitCtxt {
+                tcx: *self,
                 query: Some(token),
                 diagnostics,
                 layout_depth: current_icx.layout_depth,
@@ -403,10 +403,12 @@ fn start_query<F, R>(
             };
 
             // Use the `ImplicitCtxt` while we execute the query.
-            tls::enter_context(&new_icx, |_| compute(self))
+            tls::enter_context(&new_icx, |_| compute(*self))
         })
     }
+}
 
+impl<'tcx> TyCtxt<'tcx> {
     #[inline(never)]
     #[cold]
     pub(super) fn report_cycle(
@@ -552,74 +554,80 @@ pub(super) fn get_query<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
                 self.dep_graph.read_index(index);
                 value.clone()
             },
-            |key, lookup| self.try_execute_query::<Q>(span, key, lookup),
+            |key, lookup| try_execute_query::<Q, _, _>(self, span, key, lookup),
         )
     }
+}
 
     #[inline(always)]
-    fn try_execute_query<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
-        self,
+    fn try_execute_query<Q, CTX, K>(
+        tcx: CTX,
         span: Span,
         key: Q::Key,
         lookup: QueryLookup<
             '_,
-            TyCtxt<'tcx>,
+            CTX,
             Q::Key,
-            <Q::Cache as QueryCache<TyCtxt<'tcx>>>::Sharded,
+            <Q::Cache as QueryCache<CTX>>::Sharded,
         >,
-    ) -> Q::Value {
-        let job = match JobOwner::try_start::<Q, _>(self, span, &key, lookup) {
+    ) -> Q::Value
+    where
+        Q: QueryDescription<CTX>,
+        CTX: QueryContext<DepKind = K>,
+        CTX: HashStableContextProvider<<CTX as DepContext>::StableHashingContext>,
+        K: DepKind,
+    {
+        let job = match JobOwner::try_start::<Q, _>(tcx, span, &key, lookup) {
             TryGetJob::NotYetStarted(job) => job,
             TryGetJob::Cycle(result) => return result,
             #[cfg(parallel_compiler)]
             TryGetJob::JobCompleted((v, index)) => {
-                self.dep_graph.read_index(index);
+                tcx.dep_graph().read_index(index);
                 return v;
             }
         };
 
         // Fast path for when incr. comp. is off. `to_dep_node` is
         // expensive for some `DepKind`s.
-        if !self.dep_graph.is_fully_enabled() {
+        if !tcx.dep_graph().is_fully_enabled() {
             let null_dep_node = DepNode::new_no_params(DepKind::NULL);
-            return self.force_query_with_job::<Q>(key, job, null_dep_node).0;
+            return force_query_with_job::<Q, _, _>(tcx, key, job, null_dep_node).0;
         }
 
         if Q::ANON {
-            let prof_timer = self.prof.query_provider();
+            let prof_timer = tcx.profiler().query_provider();
 
             let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
-                self.start_query(job.id, diagnostics, |tcx| {
-                    tcx.dep_graph.with_anon_task(Q::DEP_KIND, || Q::compute(tcx, key))
+                tcx.start_query(job.id, diagnostics, |tcx| {
+                    tcx.dep_graph().with_anon_task(Q::DEP_KIND, || Q::compute(tcx, key))
                 })
             });
 
             prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
-            self.dep_graph.read_index(dep_node_index);
+            tcx.dep_graph().read_index(dep_node_index);
 
             if unlikely!(!diagnostics.is_empty()) {
-                self.queries
-                    .on_disk_cache
-                    .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
+                tcx.store_diagnostics_for_anon_node(dep_node_index, diagnostics);
             }
 
-            job.complete(self, &result, dep_node_index);
+            job.complete(tcx, &result, dep_node_index);
 
             return result;
         }
 
-        let dep_node = Q::to_dep_node(self, &key);
+        let dep_node = Q::to_dep_node(tcx, &key);
 
         if !Q::EVAL_ALWAYS {
             // The diagnostics for this query will be
             // promoted to the current session during
             // `try_mark_green()`, so we can ignore them here.
-            let loaded = self.start_query(job.id, None, |tcx| {
-                let marked = tcx.dep_graph.try_mark_green_and_read(tcx, &dep_node);
+            let loaded = tcx.start_query(job.id, None, |tcx| {
+                let marked = tcx.dep_graph().try_mark_green_and_read(tcx, &dep_node);
                 marked.map(|(prev_dep_node_index, dep_node_index)| {
                     (
-                        tcx.load_from_disk_and_cache_in_memory::<Q>(
+                        load_from_disk_and_cache_in_memory::<Q, _>(
+                            tcx,
                             key.clone(),
                             prev_dep_node_index,
                             dep_node_index,
@@ -630,32 +638,36 @@ fn try_execute_query<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
                 })
             });
             if let Some((result, dep_node_index)) = loaded {
-                job.complete(self, &result, dep_node_index);
+                job.complete(tcx, &result, dep_node_index);
                 return result;
             }
         }
 
-        let (result, dep_node_index) = self.force_query_with_job::<Q>(key, job, dep_node);
-        self.dep_graph.read_index(dep_node_index);
+        let (result, dep_node_index) = force_query_with_job::<Q, _, _>(tcx, key, job, dep_node);
+        tcx.dep_graph().read_index(dep_node_index);
         result
     }
 
-    fn load_from_disk_and_cache_in_memory<Q: QueryDescription<TyCtxt<'tcx>>>(
-        self,
+    fn load_from_disk_and_cache_in_memory<Q, CTX>(
+        tcx: CTX,
         key: Q::Key,
         prev_dep_node_index: SerializedDepNodeIndex,
         dep_node_index: DepNodeIndex,
-        dep_node: &DepNode<crate::dep_graph::DepKind>,
-    ) -> Q::Value {
+        dep_node: &DepNode<CTX::DepKind>,
+    ) -> Q::Value
+    where
+        CTX: QueryContext,
+        Q: QueryDescription<CTX>,
+    {
         // Note this function can be called concurrently from the same query
         // We must ensure that this is handled correctly.
 
-        debug_assert!(self.dep_graph.is_green(dep_node));
+        debug_assert!(tcx.dep_graph().is_green(dep_node));
 
         // First we try to load the result from the on-disk cache.
-        let result = if Q::cache_on_disk(self, key.clone(), None) {
-            let prof_timer = self.prof.incr_cache_loading();
-            let result = Q::try_load_from_disk(self, prev_dep_node_index);
+        let result = if Q::cache_on_disk(tcx, key.clone(), None) {
+            let prof_timer = tcx.profiler().incr_cache_loading();
+            let result = Q::try_load_from_disk(tcx, prev_dep_node_index);
             prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
             // We always expect to find a cached result for things that
@@ -676,10 +688,10 @@ fn load_from_disk_and_cache_in_memory<Q: QueryDescription<TyCtxt<'tcx>>>(
         } else {
             // We could not load a result from the on-disk cache, so
             // recompute.
-            let prof_timer = self.prof.query_provider();
+            let prof_timer = tcx.profiler().query_provider();
 
             // The dep-graph for this computation is already in-place.
-            let result = self.dep_graph.with_ignore(|| Q::compute(self, key));
+            let result = tcx.dep_graph().with_ignore(|| Q::compute(tcx, key));
 
             prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
@@ -688,8 +700,8 @@ fn load_from_disk_and_cache_in_memory<Q: QueryDescription<TyCtxt<'tcx>>>(
 
         // If `-Zincremental-verify-ich` is specified, re-hash results from
         // the cache and make sure that they have the expected fingerprint.
-        if unlikely!(self.sess.opts.debugging_opts.incremental_verify_ich) {
-            self.incremental_verify_ich::<Q>(&result, dep_node, dep_node_index);
+        if unlikely!(tcx.session().opts.debugging_opts.incremental_verify_ich) {
+            incremental_verify_ich::<Q, _>(tcx, &result, dep_node, dep_node_index);
         }
 
         result
@@ -697,46 +709,56 @@ fn load_from_disk_and_cache_in_memory<Q: QueryDescription<TyCtxt<'tcx>>>(
 
     #[inline(never)]
     #[cold]
-    fn incremental_verify_ich<Q: QueryDescription<TyCtxt<'tcx>>>(
-        self,
+    fn incremental_verify_ich<Q, CTX>(
+        tcx: CTX,
         result: &Q::Value,
-        dep_node: &DepNode<crate::dep_graph::DepKind>,
+        dep_node: &DepNode<CTX::DepKind>,
         dep_node_index: DepNodeIndex,
-    ) {
+    )
+    where
+        CTX: QueryContext,
+        Q: QueryDescription<CTX>,
+    {
         use rustc_data_structures::fingerprint::Fingerprint;
 
         assert!(
-            Some(self.dep_graph.fingerprint_of(dep_node_index))
-                == self.dep_graph.prev_fingerprint_of(dep_node),
+            Some(tcx.dep_graph().fingerprint_of(dep_node_index))
+                == tcx.dep_graph().prev_fingerprint_of(dep_node),
             "fingerprint for green query instance not loaded from cache: {:?}",
             dep_node,
         );
 
         debug!("BEGIN verify_ich({:?})", dep_node);
-        let mut hcx = self.create_stable_hashing_context();
+        let mut hcx = tcx.create_stable_hashing_context();
 
         let new_hash = Q::hash_result(&mut hcx, result).unwrap_or(Fingerprint::ZERO);
         debug!("END verify_ich({:?})", dep_node);
 
-        let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
+        let old_hash = tcx.dep_graph().fingerprint_of(dep_node_index);
 
         assert!(new_hash == old_hash, "found unstable fingerprints for {:?}", dep_node,);
     }
 
     #[inline(always)]
-    fn force_query_with_job<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
-        self,
+    fn force_query_with_job<Q, CTX, K>(
+        tcx: CTX,
         key: Q::Key,
-        job: JobOwner<'tcx, Self, Q::Cache>,
-        dep_node: DepNode<crate::dep_graph::DepKind>,
-    ) -> (Q::Value, DepNodeIndex) {
+        job: JobOwner<'tcx, CTX, Q::Cache>,
+        dep_node: DepNode<CTX::DepKind>,
+    ) -> (Q::Value, DepNodeIndex)
+    where
+        Q: QueryDescription<CTX>,
+        CTX: QueryContext<DepKind = K>,
+        CTX: HashStableContextProvider<<CTX as DepContext>::StableHashingContext>,
+        K: DepKind,
+    {
         // If the following assertion triggers, it can have two reasons:
         // 1. Something is wrong with DepNode creation, either here or
         //    in `DepGraph::try_mark_green()`.
         // 2. Two distinct query keys get mapped to the same `DepNode`
         //    (see for example #48923).
         assert!(
-            !self.dep_graph.dep_node_exists(&dep_node),
+            !tcx.dep_graph().dep_node_exists(&dep_node),
             "forcing query with already existing `DepNode`\n\
                  - query-key: {:?}\n\
                  - dep-node: {:?}",
@@ -744,12 +766,12 @@ fn force_query_with_job<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
             dep_node
         );
 
-        let prof_timer = self.prof.query_provider();
+        let prof_timer = tcx.profiler().query_provider();
 
         let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
-            self.start_query(job.id, diagnostics, |tcx| {
+            tcx.start_query(job.id, diagnostics, |tcx| {
                 if Q::EVAL_ALWAYS {
-                    tcx.dep_graph.with_eval_always_task(
+                    tcx.dep_graph().with_eval_always_task(
                         dep_node,
                         tcx,
                         key,
@@ -757,7 +779,7 @@ fn force_query_with_job<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
                         Q::hash_result,
                     )
                 } else {
-                    tcx.dep_graph.with_task(dep_node, tcx, key, Q::compute, Q::hash_result)
+                    tcx.dep_graph().with_task(dep_node, tcx, key, Q::compute, Q::hash_result)
                 }
             })
         });
@@ -766,15 +788,16 @@ fn force_query_with_job<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
 
         if unlikely!(!diagnostics.is_empty()) {
             if dep_node.kind != DepKind::NULL {
-                self.queries.on_disk_cache.store_diagnostics(dep_node_index, diagnostics);
+                tcx.store_diagnostics(dep_node_index, diagnostics);
             }
         }
 
-        job.complete(self, &result, dep_node_index);
+        job.complete(tcx, &result, dep_node_index);
 
         (result, dep_node_index)
     }
 
+impl<'tcx> TyCtxt<'tcx> {
     /// Ensure that either this query has all green inputs or been executed.
     /// Executing `query::ensure(D)` is considered a read of the dep-node `D`.
     ///
@@ -833,7 +856,7 @@ pub(super) fn force_query<Q: QueryDescription<TyCtxt<'tcx>> + 'tcx>(
                     #[cfg(parallel_compiler)]
                     TryGetJob::JobCompleted(_) => return,
                 };
-                self.force_query_with_job::<Q>(key, job, dep_node);
+                force_query_with_job::<Q, _, _>(self, key, job, dep_node);
             },
         );
     }
index 888151782c7ddb6d97db9c068920d93d97936868..ca4377e783d91dd219134d0249907b0278cf07ac 100644 (file)
@@ -23,7 +23,7 @@
 use std::fmt;
 use std::hash::Hash;
 
-pub trait DepContext: Copy {
+pub trait DepContext: Copy + DepGraphSafe {
     type DepKind: self::DepKind;
     type StableHashingContext: crate::HashStableContext;
 
@@ -48,6 +48,9 @@ pub trait DepContext: Copy {
     /// Register diagnostics for the given node, for use in next session.
     fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec<Diagnostic>);
 
+    /// Register diagnostics for the given node, for use in next session.
+    fn store_diagnostics_for_anon_node(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec<Diagnostic>);
+
     /// Access the profiler.
     fn profiler(&self) -> &SelfProfilerRef;
 }