From f12bdf2e45ffc963de34e9c497e1598e65493cd7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 17:32:07 +0100 Subject: [PATCH] Monomorphise try_start. --- src/librustc/ty/query/config.rs | 6 ++++ src/librustc/ty/query/plumbing.rs | 50 +++++++++++++++++-------------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 0954a61b9d546..2caba7226a2d8 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -36,6 +36,7 @@ pub(crate) struct QueryVtable<'tcx, K, V> { pub compute: fn(TyCtxt<'tcx>, K) -> V, pub hash_result: fn(&mut StableHashingContext<'_>, &V) -> Option, + pub handle_cycle_error: fn(TyCtxt<'tcx>, CycleError<'tcx>) -> V, pub cache_on_disk: fn(TyCtxt<'tcx>, K, Option<&V>) -> bool, pub try_load_from_disk: fn(TyCtxt<'tcx>, SerializedDepNodeIndex) -> Option, } @@ -53,6 +54,10 @@ impl<'tcx, K, V> QueryVtable<'tcx, K, V> { (self.hash_result)(hcx, value) } + pub(crate) fn handle_cycle_error(&self, tcx: TyCtxt<'tcx>, error: CycleError<'tcx>) -> V { + (self.handle_cycle_error)(tcx, error) + } + pub(crate) fn cache_on_disk(&self, tcx: TyCtxt<'tcx>, key: K, value: Option<&V>) -> bool { (self.cache_on_disk)(tcx, key, value) } @@ -106,6 +111,7 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { name: Self::NAME, compute: Self::COMPUTE_FN, hash_result: Self::hash_result, + handle_cycle_error: Self::handle_cycle_error, cache_on_disk: Self::cache_on_disk, try_load_from_disk: Self::try_load_from_disk, }; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index c829cc3748190..19010ad3006f9 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -175,15 +175,14 @@ where /// This function is inlined because that results in a noticeable speed-up /// for some compile-time benchmarks. #[inline(always)] - pub(super) fn try_start( + pub(super) fn try_start( tcx: TyCtxt<'tcx>, + state: &'tcx QueryState<'tcx, C>, span: Span, key: &C::Key, mut lookup: QueryLookup<'tcx, C::Key, C::Sharded>, - ) -> TryGetJob<'tcx, C> - where - Q: QueryDescription<'tcx, Key = C::Key, Value = C::Value, Cache = C>, - { + query: &QueryVtable<'tcx, C::Key, C::Value>, + ) -> TryGetJob<'tcx, C> { let lock = &mut *lookup.lock; let (latch, mut _query_blocked_prof_timer) = match lock.active.entry((*key).clone()) { @@ -200,7 +199,7 @@ where }; // Create the id of the job we're waiting for - let id = QueryJobId::new(job.id, lookup.shard, Q::DEP_KIND); + let id = QueryJobId::new(job.id, lookup.shard, query.dep_kind); (job.latch(id), _query_blocked_prof_timer) } @@ -215,14 +214,13 @@ where lock.jobs = id; let id = QueryShardJobId(NonZeroU32::new(id).unwrap()); - let global_id = QueryJobId::new(id, lookup.shard, Q::DEP_KIND); + let global_id = QueryJobId::new(id, lookup.shard, query.dep_kind); let job = tls::with_related_context(tcx, |icx| QueryJob::new(id, span, icx.query)); entry.insert(QueryResult::Started(job)); - let owner = - JobOwner { state: Q::query_state(tcx), id: global_id, key: (*key).clone() }; + let owner = JobOwner { state, id: global_id, key: (*key).clone() }; return TryGetJob::NotYetStarted(owner); } }; @@ -232,7 +230,7 @@ where // so we just return the error. #[cfg(not(parallel_compiler))] return TryGetJob::Cycle(cold_path(|| { - Q::handle_cycle_error(tcx, latch.find_cycle_in_stack(tcx, span)) + query.handle_cycle_error(tcx, latch.find_cycle_in_stack(tcx, span)) })); // With parallel queries we might just have to wait on some other @@ -242,11 +240,11 @@ where let result = latch.wait_on(tcx, span); if let Err(cycle) = result { - return TryGetJob::Cycle(Q::handle_cycle_error(tcx, cycle)); + return TryGetJob::Cycle(query.handle_cycle_error(tcx, cycle)); } let cached = tcx.try_get_cached( - Q::query_state(self), + state, (*key).clone(), |value, index| (value.clone(), index), |_, _| panic!("value must be in cache after waiting"), @@ -531,15 +529,16 @@ impl<'tcx> TyCtxt<'tcx> { key: Q::Key, lookup: QueryLookup<'tcx, Q::Key, ::Sharded>, ) -> Q::Value { - let job = match JobOwner::try_start::(self, 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); - return v; - } - }; + let job = + match JobOwner::try_start(self, Q::query_state(self), span, &key, lookup, &Q::VTABLE) { + TryGetJob::NotYetStarted(job) => job, + TryGetJob::Cycle(result) => return result, + #[cfg(parallel_compiler)] + TryGetJob::JobCompleted((v, index)) => { + self.dep_graph.read_index(index); + return v; + } + }; // Fast path for when incr. comp. is off. `to_dep_node` is // expensive for some `DepKind`s. @@ -826,7 +825,14 @@ impl<'tcx> TyCtxt<'tcx> { // Cache hit, do nothing }, |key, lookup| { - let job = match JobOwner::try_start::(self, span, &key, lookup) { + let job = match JobOwner::try_start( + self, + Q::query_state(self), + span, + &key, + lookup, + &Q::VTABLE, + ) { TryGetJob::NotYetStarted(job) => job, TryGetJob::Cycle(_) => return, #[cfg(parallel_compiler)]