@@ -6,7 +6,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
66use rustc_data_structures:: sync:: { DynSend , DynSync } ;
77use rustc_data_structures:: { outline, sharded, sync} ;
88use rustc_errors:: FatalError ;
9- use rustc_middle:: dep_graph:: { DepGraphData , DepNodeKey , SerializedDepNodeIndex } ;
9+ use rustc_middle:: dep_graph:: DepNodeKey ;
1010use rustc_middle:: query:: {
1111 ActiveKeyStatus , CycleError , EnsureMode , QueryCache , QueryJob , QueryJobId , QueryKey ,
1212 QueryLatch , QueryMode , QueryState , QueryVTable ,
@@ -380,7 +380,6 @@ fn check_feedable_consistency<'tcx, C: QueryCache>(
380380 }
381381}
382382
383- // Fast path for when incr. comp. is off.
384383#[ inline( always) ]
385384fn execute_job_non_incr < ' tcx , C : QueryCache > (
386385 query : & ' tcx QueryVTable < ' tcx , C > ,
@@ -391,12 +390,13 @@ fn execute_job_non_incr<'tcx, C: QueryCache>(
391390 debug_assert ! ( !tcx. dep_graph. is_fully_enabled( ) ) ;
392391
393392 let prof_timer = tcx. prof . query_provider ( ) ;
394- // Call the query provider.
395393 let value = start_query ( job_id, query. depth_limit , || ( query. invoke_provider_fn ) ( tcx, key) ) ;
396394 let dep_node_index = tcx. dep_graph . next_virtual_depnode_index ( ) ;
397395 prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
398396
399397 // Sanity: Fingerprint the key and the result to assert they don't contain anything unhashable.
398+ // (There is no corresponding sanity check in `execute_job_incr` because it fingerprints the
399+ // key and result as part of its normal operation.)
400400 if cfg ! ( debug_assertions) {
401401 let _ = key. to_fingerprint ( tcx) ;
402402 if let Some ( hash_value_fn) = query. hash_value_fn {
@@ -420,116 +420,80 @@ fn execute_job_incr<'tcx, C: QueryCache>(
420420 let dep_graph_data =
421421 tcx. dep_graph . data ( ) . expect ( "should always be present in incremental mode" ) ;
422422
423- if !query. eval_always {
424- // The diagnostics for this query will be promoted to the current session during
425- // `try_mark_green()`, so we can ignore them here.
426- if let Some ( ret) = start_query ( job_id, false , || try {
427- let ( prev_index, dep_node_index) = dep_graph_data. try_mark_green ( tcx, & dep_node) ?;
428- let value = load_from_disk_or_invoke_provider_green (
429- tcx,
430- dep_graph_data,
431- query,
432- key,
433- & dep_node,
434- prev_index,
435- dep_node_index,
436- ) ;
437- ( value, dep_node_index)
438- } ) {
439- return ret;
440- }
441- }
442-
443- let prof_timer = tcx. prof . query_provider ( ) ;
444-
445- let ( result, dep_node_index) = start_query ( job_id, query. depth_limit , || {
446- // Call the query provider.
447- dep_graph_data. with_task (
448- dep_node,
449- tcx,
450- ( query, key) ,
451- |tcx, ( query, key) | ( query. invoke_provider_fn ) ( tcx, key) ,
452- query. hash_value_fn ,
453- )
454- } ) ;
423+ if !query. eval_always
424+ && let Some ( ( prev_index, dep_node_index) ) = dep_graph_data. try_mark_green ( tcx, & dep_node)
425+ {
426+ // Note this function can be called concurrently from the same query. We must ensure that
427+ // this is handled correctly.
428+
429+ // First try to load the result from the on-disk cache. Some things are never cached on
430+ // disk.
431+ let try_value = if ( query. will_cache_on_disk_for_key_fn ) ( tcx, key) {
432+ let prof_timer = tcx. prof . incr_cache_loading ( ) ;
433+ let value = ( query. try_load_from_disk_fn ) ( tcx, prev_index) ;
434+ prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
435+ value
436+ } else {
437+ None
438+ } ;
455439
456- prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
440+ let ( value, verify) = match try_value {
441+ Some ( value) => {
442+ if std:: intrinsics:: unlikely ( tcx. sess . opts . unstable_opts . query_dep_graph ) {
443+ dep_graph_data. mark_debug_loaded_from_disk ( dep_node)
444+ }
457445
458- ( result, dep_node_index)
459- }
446+ let prev_fingerprint = dep_graph_data. prev_value_fingerprint_of ( prev_index) ;
447+ // If `-Zincremental-verify-ich` is specified, re-hash every result from the cache
448+ // to make sure is has the expected fingerprint. Otherwise, re-hash a fraction to
449+ // give some coverage at low cost.
450+ let verify = prev_fingerprint. split ( ) . 1 . as_u64 ( ) . is_multiple_of ( 32 )
451+ || tcx. sess . opts . unstable_opts . incremental_verify_ich ;
460452
461- /// Given that the dep node for this query+key is green, obtain a value for it
462- /// by loading one from disk if possible, or by invoking its query provider if
463- /// necessary.
464- #[ inline( always) ]
465- fn load_from_disk_or_invoke_provider_green < ' tcx , C : QueryCache > (
466- tcx : TyCtxt < ' tcx > ,
467- dep_graph_data : & DepGraphData ,
468- query : & ' tcx QueryVTable < ' tcx , C > ,
469- key : C :: Key ,
470- dep_node : & DepNode ,
471- prev_index : SerializedDepNodeIndex ,
472- dep_node_index : DepNodeIndex ,
473- ) -> C :: Value {
474- // Note this function can be called concurrently from the same query
475- // We must ensure that this is handled correctly.
476-
477- debug_assert ! ( dep_graph_data. is_index_green( prev_index) ) ;
478-
479- // First try to load the result from the on-disk cache. Some things are never cached on disk.
480- let value;
481- let verify;
482- match ( query. try_load_from_disk_fn ) ( tcx, key, prev_index, dep_node_index) {
483- Some ( loaded_value) => {
484- if std:: intrinsics:: unlikely ( tcx. sess . opts . unstable_opts . query_dep_graph ) {
485- dep_graph_data. mark_debug_loaded_from_disk ( * dep_node)
453+ ( value, verify)
486454 }
455+ None => {
456+ // We could not load a result from the on-disk cache, so recompute. The dep-graph
457+ // for this computation is already in-place, so we can just call the query
458+ // provider.
459+ let prof_timer = tcx. prof . query_provider ( ) ;
460+ let value = start_query ( job_id, query. depth_limit , || {
461+ tcx. dep_graph . with_ignore ( || ( query. invoke_provider_fn ) ( tcx, key) )
462+ } ) ;
463+ prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
464+
465+ ( value, true )
466+ }
467+ } ;
487468
488- value = loaded_value;
489-
490- let prev_fingerprint = dep_graph_data. prev_value_fingerprint_of ( prev_index) ;
491- // If `-Zincremental-verify-ich` is specified, re-hash results from
492- // the cache and make sure that they have the expected fingerprint.
469+ if verify {
470+ // Verify that re-running the query produced a result with the expected hash. This
471+ // catches bugs in query implementations, turning them into ICEs. For example, a query
472+ // might sort its result by `DefId`. Because `DefId`s are not stable across compilation
473+ // sessions, the result could get up getting sorted in a different order when the query
474+ // is re-run, even though all of the inputs (e.g. `DefPathHash` values) were green.
493475 //
494- // If not, we still seek to verify a subset of fingerprints loaded
495- // from disk. Re-hashing results is fairly expensive, so we can't
496- // currently afford to verify every hash. This subset should still
497- // give us some coverage of potential bugs.
498- verify = prev_fingerprint. split ( ) . 1 . as_u64 ( ) . is_multiple_of ( 32 )
499- || tcx. sess . opts . unstable_opts . incremental_verify_ich ;
500- }
501- None => {
502- // We could not load a result from the on-disk cache, so recompute. The dep-graph for
503- // this computation is already in-place, so we can just call the query provider.
504- let prof_timer = tcx. prof . query_provider ( ) ;
505- value = tcx. dep_graph . with_ignore ( || ( query. invoke_provider_fn ) ( tcx, key) ) ;
506- prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
507-
508- verify = true ;
476+ // See issue #82920 for an example of a miscompilation that would get turned into an
477+ // ICE by this check.
478+ incremental_verify_ich ( tcx, dep_graph_data, query, & value, prev_index) ;
509479 }
510- } ;
511480
512- if verify {
513- // Verify that re-running the query produced a result with the expected hash.
514- // This catches bugs in query implementations, turning them into ICEs.
515- // For example, a query might sort its result by `DefId` - since `DefId`s are
516- // not stable across compilation sessions, the result could get up getting sorted
517- // in a different order when the query is re-run, even though all of the inputs
518- // (e.g. `DefPathHash` values) were green.
519- //
520- // See issue #82920 for an example of a miscompilation that would get turned into
521- // an ICE by this check
522- incremental_verify_ich (
523- tcx,
524- dep_graph_data,
525- & value,
526- prev_index,
527- query. hash_value_fn ,
528- query. format_value ,
529- ) ;
481+ ( value, dep_node_index)
482+ } else {
483+ let prof_timer = tcx. prof . query_provider ( ) ;
484+ let ( value, dep_node_index) = start_query ( job_id, query. depth_limit , || {
485+ dep_graph_data. with_task (
486+ dep_node,
487+ tcx,
488+ ( query, key) ,
489+ |tcx, ( query, key) | ( query. invoke_provider_fn ) ( tcx, key) ,
490+ query. hash_value_fn ,
491+ )
492+ } ) ;
493+ prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
494+
495+ ( value, dep_node_index)
530496 }
531-
532- value
533497}
534498
535499/// Checks whether a `tcx.ensure_ok()` or `tcx.ensure_done()` query call can
0 commit comments