@@ -12,12 +12,12 @@ use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame};
1212
1313use rustc_data_structures:: fingerprint:: Fingerprint ;
1414use rustc_data_structures:: fx:: { FxHashMap , FxHasher } ;
15+ #[ cfg( parallel_compiler) ]
16+ use rustc_data_structures:: profiling:: TimingGuard ;
1517use rustc_data_structures:: sharded:: { get_shard_index_by_hash, Sharded } ;
1618use rustc_data_structures:: sync:: { Lock , LockGuard } ;
1719use rustc_data_structures:: thin_vec:: ThinVec ;
18- #[ cfg( not( parallel_compiler) ) ]
19- use rustc_errors:: DiagnosticBuilder ;
20- use rustc_errors:: { Diagnostic , FatalError } ;
20+ use rustc_errors:: { Diagnostic , DiagnosticBuilder , FatalError } ;
2121use rustc_span:: { Span , DUMMY_SP } ;
2222use std:: cell:: Cell ;
2323use std:: collections:: hash_map:: Entry ;
@@ -147,24 +147,21 @@ impl<D, K> Default for QueryState<D, K> {
147147
148148/// A type representing the responsibility to execute the job in the `job` field.
149149/// This will poison the relevant query if dropped.
150- struct JobOwner < ' tcx , D , C >
150+ struct JobOwner < ' tcx , D , K >
151151where
152152 D : Copy + Clone + Eq + Hash ,
153- C : QueryCache ,
153+ K : Eq + Hash + Clone ,
154154{
155- state : & ' tcx QueryState < D , C :: Key > ,
156- cache : & ' tcx QueryCacheStore < C > ,
157- key : C :: Key ,
155+ state : & ' tcx QueryState < D , K > ,
156+ key : K ,
158157 id : QueryJobId < D > ,
159158}
160159
161160#[ cold]
162161#[ inline( never) ]
163- #[ cfg( not( parallel_compiler) ) ]
164162fn mk_cycle < CTX , V , R > (
165163 tcx : CTX ,
166- root : QueryJobId < CTX :: DepKind > ,
167- span : Span ,
164+ error : CycleError ,
168165 handle_cycle_error : fn ( CTX , DiagnosticBuilder < ' _ > ) -> V ,
169166 cache : & dyn crate :: query:: QueryStorage < Value = V , Stored = R > ,
170167) -> R
@@ -173,20 +170,15 @@ where
173170 V : std:: fmt:: Debug ,
174171 R : Clone ,
175172{
176- let error: CycleError = root. find_cycle_in_stack (
177- tcx. try_collect_active_jobs ( ) . unwrap ( ) ,
178- & tcx. current_query_job ( ) ,
179- span,
180- ) ;
181173 let error = report_cycle ( tcx. dep_context ( ) . sess ( ) , error) ;
182174 let value = handle_cycle_error ( tcx, error) ;
183175 cache. store_nocache ( value)
184176}
185177
186- impl < ' tcx , D , C > JobOwner < ' tcx , D , C >
178+ impl < ' tcx , D , K > JobOwner < ' tcx , D , K >
187179where
188180 D : Copy + Clone + Eq + Hash ,
189- C : QueryCache ,
181+ K : Eq + Hash + Clone ,
190182{
191183 /// Either gets a `JobOwner` corresponding the query, allowing us to
192184 /// start executing the query, or returns with the result of the query.
@@ -198,14 +190,13 @@ where
198190 /// for some compile-time benchmarks.
199191 #[ inline( always) ]
200192 fn try_start < ' b , CTX > (
201- tcx : CTX ,
202- state : & ' b QueryState < CTX :: DepKind , C :: Key > ,
203- cache : & ' b QueryCacheStore < C > ,
193+ tcx : & ' b CTX ,
194+ state : & ' b QueryState < CTX :: DepKind , K > ,
204195 span : Span ,
205- key : C :: Key ,
196+ key : K ,
206197 lookup : QueryLookup ,
207- query : & QueryVtable < CTX , C :: Key , C :: Value > ,
208- ) -> TryGetJob < ' b , CTX :: DepKind , C >
198+ dep_kind : CTX :: DepKind ,
199+ ) -> TryGetJob < ' b , CTX :: DepKind , K >
209200 where
210201 CTX : QueryContext ,
211202 {
@@ -226,26 +217,24 @@ where
226217 let key = entry. key ( ) . clone ( ) ;
227218 entry. insert ( QueryResult :: Started ( job) ) ;
228219
229- let global_id = QueryJobId :: new ( id, shard, query . dep_kind ) ;
230- let owner = JobOwner { state, cache , id : global_id, key } ;
220+ let global_id = QueryJobId :: new ( id, shard, dep_kind) ;
221+ let owner = JobOwner { state, id : global_id, key } ;
231222 return TryGetJob :: NotYetStarted ( owner) ;
232223 }
233224 Entry :: Occupied ( mut entry) => {
234225 match entry. get_mut ( ) {
235226 #[ cfg( not( parallel_compiler) ) ]
236227 QueryResult :: Started ( job) => {
237- let id = QueryJobId :: new ( job. id , shard, query . dep_kind ) ;
228+ let id = QueryJobId :: new ( job. id , shard, dep_kind) ;
238229
239230 drop ( state_lock) ;
240231
241232 // If we are single-threaded we know that we have cycle error,
242233 // so we just return the error.
243- return TryGetJob :: Cycle ( mk_cycle (
244- tcx,
245- id ,
234+ return TryGetJob :: Cycle ( id . find_cycle_in_stack (
235+ tcx. try_collect_active_jobs ( ) . unwrap ( ) ,
236+ & tcx . current_query_job ( ) ,
246237 span,
247- query. handle_cycle_error ,
248- & cache. cache ,
249238 ) ) ;
250239 }
251240 #[ cfg( parallel_compiler) ]
@@ -257,38 +246,17 @@ where
257246
258247 // Get the latch out
259248 let latch = job. latch ( ) ;
260- let key = entry. key ( ) . clone ( ) ;
261249
262250 drop ( state_lock) ;
263251
264252 // With parallel queries we might just have to wait on some other
265253 // thread.
266254 let result = latch. wait_on ( tcx. current_query_job ( ) , span) ;
267255
268- if let Err ( cycle) = result {
269- let cycle = report_cycle ( tcx. dep_context ( ) . sess ( ) , cycle) ;
270- let value = ( query. handle_cycle_error ) ( tcx, cycle) ;
271- let value = cache. cache . store_nocache ( value) ;
272- return TryGetJob :: Cycle ( value) ;
256+ match result {
257+ Ok ( ( ) ) => TryGetJob :: JobCompleted ( query_blocked_prof_timer) ,
258+ Err ( cycle) => TryGetJob :: Cycle ( cycle) ,
273259 }
274-
275- let cached = cache
276- . cache
277- . lookup ( cache, & key, |value, index| {
278- if unlikely ! ( tcx. dep_context( ) . profiler( ) . enabled( ) ) {
279- tcx. dep_context ( ) . profiler ( ) . query_cache_hit ( index. into ( ) ) ;
280- }
281- #[ cfg( debug_assertions) ]
282- {
283- cache. cache_hits . fetch_add ( 1 , Ordering :: Relaxed ) ;
284- }
285- ( value. clone ( ) , index)
286- } )
287- . unwrap_or_else ( |_| panic ! ( "value must be in cache after waiting" ) ) ;
288-
289- query_blocked_prof_timer. finish_with_query_invocation_id ( cached. 1 . into ( ) ) ;
290-
291- return TryGetJob :: JobCompleted ( cached) ;
292260 }
293261 QueryResult :: Poisoned => FatalError . raise ( ) ,
294262 }
@@ -298,11 +266,18 @@ where
298266
299267 /// Completes the query by updating the query cache with the `result`,
300268 /// signals the waiter and forgets the JobOwner, so it won't poison the query
301- fn complete ( self , result : C :: Value , dep_node_index : DepNodeIndex ) -> C :: Stored {
269+ fn complete < C > (
270+ self ,
271+ cache : & QueryCacheStore < C > ,
272+ result : C :: Value ,
273+ dep_node_index : DepNodeIndex ,
274+ ) -> C :: Stored
275+ where
276+ C : QueryCache < Key = K > ,
277+ {
302278 // We can move out of `self` here because we `mem::forget` it below
303279 let key = unsafe { ptr:: read ( & self . key ) } ;
304280 let state = self . state ;
305- let cache = self . cache ;
306281
307282 // Forget ourself so our destructor won't poison the query
308283 mem:: forget ( self ) ;
@@ -338,10 +313,10 @@ where
338313 ( result, diagnostics. into_inner ( ) )
339314}
340315
341- impl < ' tcx , D , C > Drop for JobOwner < ' tcx , D , C >
316+ impl < ' tcx , D , K > Drop for JobOwner < ' tcx , D , K >
342317where
343318 D : Copy + Clone + Eq + Hash ,
344- C : QueryCache ,
319+ K : Eq + Hash + Clone ,
345320{
346321 #[ inline( never) ]
347322 #[ cold]
@@ -372,22 +347,22 @@ pub(crate) struct CycleError {
372347}
373348
374349/// The result of `try_start`.
375- enum TryGetJob < ' tcx , D , C >
350+ enum TryGetJob < ' tcx , D , K >
376351where
377352 D : Copy + Clone + Eq + Hash ,
378- C : QueryCache ,
353+ K : Eq + Hash + Clone ,
379354{
380355 /// The query is not yet started. Contains a guard to the cache eventually used to start it.
381- NotYetStarted ( JobOwner < ' tcx , D , C > ) ,
356+ NotYetStarted ( JobOwner < ' tcx , D , K > ) ,
382357
383358 /// The query was already completed.
384359 /// Returns the result of the query and its dep-node index
385360 /// if it succeeded or a cycle error if it failed.
386361 #[ cfg( parallel_compiler) ]
387- JobCompleted ( ( C :: Stored , DepNodeIndex ) ) ,
362+ JobCompleted ( TimingGuard < ' tcx > ) ,
388363
389364 /// Trying to execute the query resulted in a cycle.
390- Cycle ( C :: Stored ) ,
365+ Cycle ( CycleError ) ,
391366}
392367
393368/// Checks if the query is already computed and in the cache.
@@ -436,19 +411,35 @@ where
436411 C :: Key : Clone + DepNodeParams < CTX :: DepContext > ,
437412 CTX : QueryContext ,
438413{
439- let job = match JobOwner :: < ' _ , CTX :: DepKind , C > :: try_start (
440- tcx,
414+ let job = match JobOwner :: < ' _ , CTX :: DepKind , C :: Key > :: try_start (
415+ & tcx,
441416 state,
442- cache,
443417 span,
444418 key. clone ( ) ,
445419 lookup,
446- query,
420+ query. dep_kind ,
447421 ) {
448422 TryGetJob :: NotYetStarted ( job) => job,
449- TryGetJob :: Cycle ( result) => return ( result, None ) ,
423+ TryGetJob :: Cycle ( error) => {
424+ let result = mk_cycle ( tcx, error, query. handle_cycle_error , & cache. cache ) ;
425+ return ( result, None ) ;
426+ }
450427 #[ cfg( parallel_compiler) ]
451- TryGetJob :: JobCompleted ( ( v, index) ) => {
428+ TryGetJob :: JobCompleted ( query_blocked_prof_timer) => {
429+ let ( v, index) = cache
430+ . cache
431+ . lookup ( cache, & key, |value, index| ( value. clone ( ) , index) )
432+ . unwrap_or_else ( |_| panic ! ( "value must be in cache after waiting" ) ) ;
433+
434+ if unlikely ! ( tcx. dep_context( ) . profiler( ) . enabled( ) ) {
435+ tcx. dep_context ( ) . profiler ( ) . query_cache_hit ( index. into ( ) ) ;
436+ }
437+ #[ cfg( debug_assertions) ]
438+ {
439+ cache. cache_hits . fetch_add ( 1 , Ordering :: Relaxed ) ;
440+ }
441+ query_blocked_prof_timer. finish_with_query_invocation_id ( index. into ( ) ) ;
442+
452443 return ( v, Some ( index) ) ;
453444 }
454445 } ;
@@ -461,7 +452,7 @@ where
461452 let result = tcx. start_query ( job. id , None , || compute ( * tcx. dep_context ( ) , key) ) ;
462453 let dep_node_index = dep_graph. next_virtual_depnode_index ( ) ;
463454 prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
464- let result = job. complete ( result, dep_node_index) ;
455+ let result = job. complete ( cache , result, dep_node_index) ;
465456 return ( result, None ) ;
466457 }
467458
@@ -504,7 +495,7 @@ where
504495 force_query_with_job ( tcx, key, job. id , dep_node, query, compute)
505496 }
506497 } ;
507- let result = job. complete ( result, dep_node_index) ;
498+ let result = job. complete ( cache , result, dep_node_index) ;
508499 ( result, Some ( dep_node_index) )
509500}
510501
0 commit comments