@@ -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
@@ -151,37 +151,31 @@ impl CoverageGraph {
151151 // together, they will be adjacent in the traversal order.
152152
153153 // Accumulates a chain of blocks that will be combined into one BCB.
154- let mut basic_blocks = Vec :: new ( ) ;
154+ let mut current_chain = vec ! [ ] ;
155155
156- let filtered_successors = |bb| bcb_filtered_successors ( mir_body[ bb] . terminator ( ) ) ;
157156 let subgraph = CoverageRelevantSubgraph :: new ( & mir_body. basic_blocks ) ;
158157 for bb in graph:: depth_first_search ( subgraph, mir:: START_BLOCK )
159158 . filter ( |& bb| mir_body[ bb] . terminator ( ) . kind != TerminatorKind :: Unreachable )
160159 {
161- // If the previous block can't be chained into `bb`, flush the accumulated
162- // blocks into a new BCB, then start building the next chain.
163- if let Some ( & prev) = basic_blocks. last ( )
164- && ( !filtered_successors ( prev) . is_chainable ( ) || {
165- // If `bb` has multiple predecessor blocks, or `prev` isn't
166- // one of its predecessors, we can't chain and must flush.
167- let predecessors = & mir_body. basic_blocks . predecessors ( ) [ bb] ;
168- predecessors. len ( ) > 1 || !predecessors. contains ( & prev)
169- } )
170- {
171- debug ! (
172- terminator_kind = ?mir_body[ prev] . terminator( ) . kind,
173- predecessors = ?& mir_body. basic_blocks. predecessors( ) [ bb] ,
174- "can't chain from {prev:?} to {bb:?}"
175- ) ;
176- add_basic_coverage_block ( & mut basic_blocks) ;
160+ if let Some ( & prev) = current_chain. last ( ) {
161+ // Adding a block to a non-empty chain is allowed if the
162+ // previous block permits chaining, and the current block has
163+ // `prev` as its sole predecessor.
164+ let can_chain = subgraph. coverage_successors ( prev) . is_out_chainable ( )
165+ && mir_body. basic_blocks . predecessors ( ) [ bb] . as_slice ( ) == & [ prev] ;
166+ if !can_chain {
167+ // The current block can't be added to the existing chain, so
168+ // flush that chain into a new BCB, and start a new chain.
169+ flush_chain_into_new_bcb ( & mut current_chain) ;
170+ }
177171 }
178172
179- basic_blocks . push ( bb) ;
173+ current_chain . push ( bb) ;
180174 }
181175
182- if !basic_blocks . is_empty ( ) {
176+ if !current_chain . is_empty ( ) {
183177 debug ! ( "flushing accumulated blocks into one last BCB" ) ;
184- add_basic_coverage_block ( & mut basic_blocks ) ;
178+ flush_chain_into_new_bcb ( & mut current_chain ) ;
185179 }
186180
187181 ( bcbs, bb_to_bcb)
@@ -398,7 +392,9 @@ struct CoverageSuccessors<'a> {
398392}
399393
400394impl CoverageSuccessors < ' _ > {
401- fn is_chainable ( & self ) -> bool {
395+ /// If `false`, this terminator cannot be chained into another block when
396+ /// building the coverage graph.
397+ fn is_out_chainable ( & self ) -> bool {
402398 // If a terminator is out-summable and has exactly one out-edge, then
403399 // it is eligible to be chained into its successor block.
404400 self . is_out_summable ( ) && self . targets . len ( ) == 1
0 commit comments