@@ -261,9 +261,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
261261 tcx : TyCtxt < ' tcx > ,
262262 span : Span ,
263263 key : C :: Key ,
264- // If present, some previous step has already created a `DepNode` for this
265- // query+key, which we should reuse instead of creating a new one.
266- dep_node : Option < DepNode > ,
264+ dep_node : Option < DepNode > , // `None` for non-incremental, `Some` for incremental
267265) -> ( C :: Value , Option < DepNodeIndex > ) {
268266 let key_hash = sharded:: make_hash ( & key) ;
269267 let mut state_lock = query. state . active . lock_shard_by_hash ( key_hash) ;
@@ -300,7 +298,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
300298
301299 // Delegate to another function to actually execute the query job.
302300 let ( value, dep_node_index) = if INCR {
303- execute_job_incr ( query, tcx, key, dep_node, id)
301+ execute_job_incr ( query, tcx, key, dep_node. unwrap ( ) , id)
304302 } else {
305303 execute_job_non_incr ( query, tcx, key, id)
306304 } ;
@@ -416,27 +414,23 @@ fn execute_job_incr<'tcx, C: QueryCache>(
416414 query : & ' tcx QueryVTable < ' tcx , C > ,
417415 tcx : TyCtxt < ' tcx > ,
418416 key : C :: Key ,
419- mut dep_node_opt : Option < DepNode > ,
417+ dep_node : DepNode ,
420418 job_id : QueryJobId ,
421419) -> ( C :: Value , DepNodeIndex ) {
422420 let dep_graph_data =
423421 tcx. dep_graph . data ( ) . expect ( "should always be present in incremental mode" ) ;
424422
425423 if !query. eval_always {
426- // `to_dep_node` is expensive for some `DepKind`s.
427- let dep_node =
428- dep_node_opt. get_or_insert_with ( || DepNode :: construct ( tcx, query. dep_kind , & key) ) ;
429-
430424 // The diagnostics for this query will be promoted to the current session during
431425 // `try_mark_green()`, so we can ignore them here.
432426 if let Some ( ret) = start_query ( job_id, false , || try {
433- let ( prev_index, dep_node_index) = dep_graph_data. try_mark_green ( tcx, dep_node) ?;
427+ let ( prev_index, dep_node_index) = dep_graph_data. try_mark_green ( tcx, & dep_node) ?;
434428 let value = load_from_disk_or_invoke_provider_green (
435429 tcx,
436430 dep_graph_data,
437431 query,
438432 key,
439- dep_node,
433+ & dep_node,
440434 prev_index,
441435 dep_node_index,
442436 ) ;
@@ -449,10 +443,6 @@ fn execute_job_incr<'tcx, C: QueryCache>(
449443 let prof_timer = tcx. prof . query_provider ( ) ;
450444
451445 let ( result, dep_node_index) = start_query ( job_id, query. depth_limit , || {
452- // `to_dep_node` is expensive for some `DepKind`s.
453- let dep_node =
454- dep_node_opt. unwrap_or_else ( || DepNode :: construct ( tcx, query. dep_kind , & key) ) ;
455-
456446 // Call the query provider.
457447 dep_graph_data. with_task (
458448 dep_node,
@@ -542,67 +532,54 @@ fn load_from_disk_or_invoke_provider_green<'tcx, C: QueryCache>(
542532 value
543533}
544534
545- /// Return value struct for [`check_if_ensure_can_skip_execution`].
546- struct EnsureCanSkip {
547- /// If true, the current `tcx.ensure_ok()` or `tcx.ensure_done()` query
548- /// can return early without actually trying to execute.
549- skip_execution : bool ,
550- /// A dep node that was prepared while checking whether execution can be
551- /// skipped, to be reused by execution itself if _not_ skipped.
552- dep_node : Option < DepNode > ,
553- }
554-
555535/// Checks whether a `tcx.ensure_ok()` or `tcx.ensure_done()` query call can
556536/// return early without actually trying to execute.
557537///
558538/// This only makes sense during incremental compilation, because it relies
559539/// on having the dependency graph (and in some cases a disk-cached value)
560540/// from the previous incr-comp session.
561541#[ inline( never) ]
562- fn check_if_ensure_can_skip_execution < ' tcx , C : QueryCache > (
542+ fn ensure_can_skip_execution < ' tcx , C : QueryCache > (
563543 query : & ' tcx QueryVTable < ' tcx , C > ,
564544 tcx : TyCtxt < ' tcx > ,
565545 key : C :: Key ,
546+ dep_node : DepNode ,
566547 ensure_mode : EnsureMode ,
567- ) -> EnsureCanSkip {
548+ ) -> bool {
568549 // Queries with `eval_always` should never skip execution.
569550 if query. eval_always {
570- return EnsureCanSkip { skip_execution : false , dep_node : None } ;
551+ return false ;
571552 }
572553
573- let dep_node = DepNode :: construct ( tcx, query. dep_kind , & key) ;
574-
575- let serialized_dep_node_index = match tcx. dep_graph . try_mark_green ( tcx, & dep_node) {
554+ match tcx. dep_graph . try_mark_green ( tcx, & dep_node) {
576555 None => {
577556 // A None return from `try_mark_green` means that this is either
578557 // a new dep node or that the dep node has already been marked red.
579558 // Either way, we can't call `dep_graph.read()` as we don't have the
580559 // DepNodeIndex. We must invoke the query itself. The performance cost
581560 // this introduces should be negligible as we'll immediately hit the
582561 // in-memory cache, or another query down the line will.
583- return EnsureCanSkip { skip_execution : false , dep_node : Some ( dep_node ) } ;
562+ false
584563 }
585564 Some ( ( serialized_dep_node_index, dep_node_index) ) => {
586565 tcx. dep_graph . read_index ( dep_node_index) ;
587566 tcx. prof . query_cache_hit ( dep_node_index. into ( ) ) ;
588- serialized_dep_node_index
589- }
590- } ;
591-
592- match ensure_mode {
593- EnsureMode :: Ok => {
594- // In ensure-ok mode, we can skip execution for this key if the node
595- // is green. It must have succeeded in the previous session, and
596- // therefore would succeed in the current session if executed.
597- EnsureCanSkip { skip_execution : true , dep_node : None }
598- }
599- EnsureMode :: Done => {
600- // In ensure-done mode, we can only skip execution for this key if
601- // there's a disk-cached value available to load later if needed,
602- // which guarantees the query provider will never run for this key.
603- let is_loadable = ( query. will_cache_on_disk_for_key_fn ) ( tcx, key)
604- && loadable_from_disk ( tcx, serialized_dep_node_index) ;
605- EnsureCanSkip { skip_execution : is_loadable, dep_node : Some ( dep_node) }
567+ match ensure_mode {
568+ // In ensure-ok mode, we can skip execution for this key if the
569+ // node is green. It must have succeeded in the previous
570+ // session, and therefore would succeed in the current session
571+ // if executed.
572+ EnsureMode :: Ok => true ,
573+
574+ // In ensure-done mode, we can only skip execution for this key
575+ // if there's a disk-cached value available to load later if
576+ // needed, which guarantees the query provider will never run
577+ // for this key.
578+ EnsureMode :: Done => {
579+ ( query. will_cache_on_disk_for_key_fn ) ( tcx, key)
580+ && loadable_from_disk ( tcx, serialized_dep_node_index)
581+ }
582+ }
606583 }
607584 }
608585}
@@ -629,24 +606,18 @@ pub(super) fn execute_query_incr_inner<'tcx, C: QueryCache>(
629606 key : C :: Key ,
630607 mode : QueryMode ,
631608) -> Option < C :: Value > {
609+ let dep_node = DepNode :: construct ( tcx, query. dep_kind , & key) ;
610+
632611 // Check if query execution can be skipped, for `ensure_ok` or `ensure_done`.
633- // This might have the side-effect of creating a suitable DepNode, which
634- // we should reuse for execution instead of creating a new one.
635- let dep_node: Option < DepNode > = match mode {
636- QueryMode :: Ensure { ensure_mode } => {
637- let EnsureCanSkip { skip_execution, dep_node } =
638- check_if_ensure_can_skip_execution ( query, tcx, key, ensure_mode) ;
639- if skip_execution {
640- // Return early to skip execution.
641- return None ;
642- }
643- dep_node
644- }
645- QueryMode :: Get => None ,
646- } ;
612+ if let QueryMode :: Ensure { ensure_mode } = mode
613+ && ensure_can_skip_execution ( query, tcx, key, dep_node, ensure_mode)
614+ {
615+ return None ;
616+ }
647617
648- let ( result, dep_node_index) =
649- ensure_sufficient_stack ( || try_execute_query :: < C , true > ( query, tcx, span, key, dep_node) ) ;
618+ let ( result, dep_node_index) = ensure_sufficient_stack ( || {
619+ try_execute_query :: < C , true > ( query, tcx, span, key, Some ( dep_node) )
620+ } ) ;
650621 if let Some ( dep_node_index) = dep_node_index {
651622 tcx. dep_graph . read_index ( dep_node_index)
652623 }
0 commit comments