Skip to content

Commit ba54046

Browse files
committed
coverage: Simplify logic for chaining multiple blocks into one BCB
We only need to take action when the next block cannot be added to the current chain, but the logic is much simpler if we express it in terms of when the block _can_ be added.
1 parent 8834b5a commit ba54046

File tree

1 file changed

+21
-24
lines changed
  • compiler/rustc_mir_transform/src/coverage

1 file changed

+21
-24
lines changed

compiler/rustc_mir_transform/src/coverage/graph.rs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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![];
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

401396
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 {
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

Comments
 (0)