@@ -127,10 +127,10 @@ impl CoverageGraph {
127127 let mut bcbs = IndexVec :: < BasicCoverageBlock , _ > :: with_capacity ( num_basic_blocks) ;
128128 let mut bb_to_bcb = IndexVec :: from_elem_n ( None , num_basic_blocks) ;
129129
130- let mut add_basic_coverage_block = |basic_blocks : & mut Vec < BasicBlock > | {
130+ let mut flush_chain_into_new_bcb = |current_chain : & mut Vec < BasicBlock > | {
131131 // Take the accumulated list of blocks, leaving the vector empty
132132 // to be used by subsequent BCBs.
133- let basic_blocks = std:: mem:: take ( basic_blocks ) ;
133+ let basic_blocks = std:: mem:: take ( current_chain ) ;
134134
135135 let bcb = bcbs. next_index ( ) ;
136136 for & bb in basic_blocks. iter ( ) {
@@ -141,7 +141,7 @@ impl CoverageGraph {
141141 bcb_filtered_successors ( mir_body[ bb] . terminator ( ) ) . is_out_summable ( )
142142 } ) ;
143143 let bcb_data = BasicCoverageBlockData { basic_blocks, is_out_summable } ;
144- debug ! ( "adding bcb{ }: {:?}" , bcb . index ( ) , bcb_data ) ;
144+ debug ! ( "adding {bcb:? }: {bcb_data :?}" ) ;
145145 bcbs. push ( bcb_data) ;
146146 } ;
147147
@@ -153,36 +153,31 @@ impl CoverageGraph {
153153 // `catch_unwind()` handlers.
154154
155155 // Accumulates a chain of blocks that will be combined into one BCB.
156- let mut basic_blocks = Vec :: new ( ) ;
156+ let mut current_chain = Vec :: new ( ) ;
157157
158158 let filtered_successors = |bb| bcb_filtered_successors ( mir_body[ bb] . terminator ( ) ) ;
159159 for bb in short_circuit_preorder ( mir_body, filtered_successors)
160160 . filter ( |& bb| mir_body[ bb] . terminator ( ) . kind != TerminatorKind :: Unreachable )
161161 {
162- // If the previous block can't be chained into `bb`, flush the accumulated
163- // blocks into a new BCB, then start building the next chain.
164- if let Some ( & prev) = basic_blocks. last ( )
165- && ( !filtered_successors ( prev) . is_chainable ( ) || {
166- // If `bb` has multiple predecessor blocks, or `prev` isn't
167- // one of its predecessors, we can't chain and must flush.
168- let predecessors = & mir_body. basic_blocks . predecessors ( ) [ bb] ;
169- predecessors. len ( ) > 1 || !predecessors. contains ( & prev)
170- } )
171- {
172- debug ! (
173- terminator_kind = ?mir_body[ prev] . terminator( ) . kind,
174- predecessors = ?& mir_body. basic_blocks. predecessors( ) [ bb] ,
175- "can't chain from {prev:?} to {bb:?}"
176- ) ;
177- add_basic_coverage_block ( & mut basic_blocks) ;
162+ if let Some ( & prev) = current_chain. last ( ) {
163+ // Adding a block to a non-empty chain is allowed if the
164+ // previous block permits chaining, and the current block has
165+ // `prev` as its sole predecessor.
166+ let can_chain = filtered_successors ( prev) . is_out_chainable ( )
167+ && mir_body. basic_blocks . predecessors ( ) [ bb] . as_slice ( ) == & [ prev] ;
168+ if !can_chain {
169+ // The current block can't be added to the existing chain, so
170+ // flush that chain into a new BCB, and start a new chain.
171+ flush_chain_into_new_bcb ( & mut current_chain) ;
172+ }
178173 }
179174
180- basic_blocks . push ( bb) ;
175+ current_chain . push ( bb) ;
181176 }
182177
183- if !basic_blocks . is_empty ( ) {
178+ if !current_chain . is_empty ( ) {
184179 debug ! ( "flushing accumulated blocks into one last BCB" ) ;
185- add_basic_coverage_block ( & mut basic_blocks ) ;
180+ flush_chain_into_new_bcb ( & mut current_chain ) ;
186181 }
187182
188183 ( bcbs, bb_to_bcb)
@@ -399,7 +394,9 @@ struct CoverageSuccessors<'a> {
399394}
400395
401396impl CoverageSuccessors < ' _ > {
402- fn is_chainable ( & self ) -> bool {
397+ /// If `false`, this terminator cannot be chained into another block when
398+ /// building the coverage graph.
399+ fn is_out_chainable ( & self ) -> bool {
403400 // If a terminator is out-summable and has exactly one out-edge, then
404401 // it is eligible to be chained into its successor block.
405402 self . is_out_summable ( ) && self . targets . len ( ) == 1
0 commit comments