@@ -450,7 +450,7 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
450450 worklist : VecDeque :: new ( ) ,
451451 } ) ;
452452 }
453- self . extend_worklist ( bcb) ;
453+ self . add_successors_to_worklists ( bcb) ;
454454 return Some ( bcb) ;
455455 } else {
456456 // Strip contexts with empty worklists from the top of the stack
@@ -461,10 +461,10 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
461461 None
462462 }
463463
464- pub fn extend_worklist ( & mut self , bcb : BasicCoverageBlock ) {
465- let Self { basic_coverage_blocks, .. } = * self ;
466- let successors = & basic_coverage_blocks. successors [ bcb] ;
464+ pub fn add_successors_to_worklists ( & mut self , bcb : BasicCoverageBlock ) {
465+ let successors = & self . basic_coverage_blocks . successors [ bcb] ;
467466 debug ! ( "{:?} has {} successors:" , bcb, successors. len( ) ) ;
467+
468468 for & successor in successors {
469469 if successor == bcb {
470470 debug ! (
@@ -473,43 +473,44 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
473473 bcb
474474 ) ;
475475 // Don't re-add this successor to the worklist. We are already processing it.
476+ // FIXME: This claims to skip just the self-successor, but it actually skips
477+ // all other successors as well. Does that matter?
476478 break ;
477479 }
478- for context in self . context_stack . iter_mut ( ) . rev ( ) {
479- // Add successors of the current BCB to the appropriate context. Successors that
480- // stay within a loop are added to the BCBs context worklist. Successors that
481- // exit the loop (they are not dominated by the loop header) must be reachable
482- // from other BCBs outside the loop, and they will be added to a different
483- // worklist.
484- //
485- // Branching blocks (with more than one successor) must be processed before
486- // blocks with only one successor, to prevent unnecessarily complicating
487- // `Expression`s by creating a Counter in a `BasicCoverageBlock` that the
488- // branching block would have given an `Expression` (or vice versa).
489- let ( some_successor_to_add, _) =
490- if let Some ( loop_header) = context. loop_header {
491- if basic_coverage_blocks. dominates ( loop_header, successor) {
492- ( Some ( successor) , Some ( loop_header) )
493- } else {
494- ( None , None )
495- }
496- } else {
497- ( Some ( successor) , None )
498- } ;
499-
500- // FIXME: The code below had debug messages claiming to add items to a
501- // particular end of the worklist, but was confused about which end was
502- // which. The existing behaviour has been preserved for now, but it's
503- // unclear what the intended behaviour was.
504-
505- if let Some ( successor_to_add) = some_successor_to_add {
506- if basic_coverage_blocks. successors [ successor_to_add] . len ( ) > 1 {
507- context. worklist . push_back ( successor_to_add) ;
508- } else {
509- context. worklist . push_front ( successor_to_add) ;
480+
481+ // Add successors of the current BCB to the appropriate context. Successors that
482+ // stay within a loop are added to the BCBs context worklist. Successors that
483+ // exit the loop (they are not dominated by the loop header) must be reachable
484+ // from other BCBs outside the loop, and they will be added to a different
485+ // worklist.
486+ //
487+ // Branching blocks (with more than one successor) must be processed before
488+ // blocks with only one successor, to prevent unnecessarily complicating
489+ // `Expression`s by creating a Counter in a `BasicCoverageBlock` that the
490+ // branching block would have given an `Expression` (or vice versa).
491+
492+ let context = self
493+ . context_stack
494+ . iter_mut ( )
495+ . rev ( )
496+ . find ( |context| match context. loop_header {
497+ Some ( loop_header) => {
498+ self . basic_coverage_blocks . dominates ( loop_header, successor)
510499 }
511- break ;
512- }
500+ None => true ,
501+ } )
502+ . unwrap_or_else ( || bug ! ( "should always fall back to the root non-loop context" ) ) ;
503+ debug ! ( "adding to worklist for {:?}" , context. loop_header) ;
504+
505+ // FIXME: The code below had debug messages claiming to add items to a
506+ // particular end of the worklist, but was confused about which end was
507+ // which. The existing behaviour has been preserved for now, but it's
508+ // unclear what the intended behaviour was.
509+
510+ if self . basic_coverage_blocks . successors [ successor] . len ( ) > 1 {
511+ context. worklist . push_back ( successor) ;
512+ } else {
513+ context. worklist . push_front ( successor) ;
513514 }
514515 }
515516 }
0 commit comments