@@ -127,10 +127,10 @@ impl CoverageGraph {
127
127
let mut bcbs = IndexVec :: < BasicCoverageBlock , _ > :: with_capacity ( num_basic_blocks) ;
128
128
let mut bb_to_bcb = IndexVec :: from_elem_n ( None , num_basic_blocks) ;
129
129
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 > | {
131
131
// Take the accumulated list of blocks, leaving the vector empty
132
132
// to be used by subsequent BCBs.
133
- let basic_blocks = std:: mem:: take ( basic_blocks ) ;
133
+ let basic_blocks = std:: mem:: take ( current_chain ) ;
134
134
135
135
let bcb = bcbs. next_index ( ) ;
136
136
for & bb in basic_blocks. iter ( ) {
@@ -141,7 +141,7 @@ impl CoverageGraph {
141
141
bcb_filtered_successors ( mir_body[ bb] . terminator ( ) ) . is_out_summable ( )
142
142
} ) ;
143
143
let bcb_data = BasicCoverageBlockData { basic_blocks, is_out_summable } ;
144
- debug ! ( "adding bcb{ }: {:?}" , bcb . index ( ) , bcb_data ) ;
144
+ debug ! ( "adding {bcb:? }: {bcb_data :?}" ) ;
145
145
bcbs. push ( bcb_data) ;
146
146
} ;
147
147
@@ -153,36 +153,31 @@ impl CoverageGraph {
153
153
// `catch_unwind()` handlers.
154
154
155
155
// 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 ! [ ] ;
157
157
158
158
let filtered_successors = |bb| bcb_filtered_successors ( mir_body[ bb] . terminator ( ) ) ;
159
159
for bb in short_circuit_preorder ( mir_body, filtered_successors)
160
160
. filter ( |& bb| mir_body[ bb] . terminator ( ) . kind != TerminatorKind :: Unreachable )
161
161
{
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
+ }
178
173
}
179
174
180
- basic_blocks . push ( bb) ;
175
+ current_chain . push ( bb) ;
181
176
}
182
177
183
- if !basic_blocks . is_empty ( ) {
178
+ if !current_chain . is_empty ( ) {
184
179
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 ) ;
186
181
}
187
182
188
183
( bcbs, bb_to_bcb)
@@ -399,7 +394,9 @@ struct CoverageSuccessors<'a> {
399
394
}
400
395
401
396
impl 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 {
403
400
// If a terminator is out-summable and has exactly one out-edge, then
404
401
// it is eligible to be chained into its successor block.
405
402
self . is_out_summable ( ) && self . targets . len ( ) == 1
0 commit comments