Skip to content

Commit 6d1c396

Browse files
committed
coverage: Determine a block's successors from just the terminator
Filtering out unreachable successors is only needed by the main graph traversal loop, so we can move the filtering step into that loop instead, eliminating the need to pass the MIR body into `bcb_filtered_successors`.
1 parent 3deb9bb commit 6d1c396

File tree

1 file changed

+11
-14
lines changed
  • compiler/rustc_mir_transform/src/coverage

1 file changed

+11
-14
lines changed

compiler/rustc_mir_transform/src/coverage/graph.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_data_structures::graph::dominators::{self, Dominators};
33
use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes, WithStartNode};
44
use rustc_index::bit_set::BitSet;
55
use rustc_index::{IndexSlice, IndexVec};
6-
use rustc_middle::mir::{self, BasicBlock, TerminatorKind};
6+
use rustc_middle::mir::{self, BasicBlock, Terminator, TerminatorKind};
77

88
use std::cmp::Ordering;
99
use std::collections::VecDeque;
@@ -38,7 +38,7 @@ impl CoverageGraph {
3838
}
3939
let bcb_data = &bcbs[bcb];
4040
let mut bcb_successors = Vec::new();
41-
for successor in bcb_filtered_successors(mir_body, bcb_data.last_bb())
41+
for successor in bcb_filtered_successors(mir_body[bcb_data.last_bb()].terminator())
4242
.filter_map(|successor_bb| bb_to_bcb[successor_bb])
4343
{
4444
if !seen[successor] {
@@ -91,7 +91,10 @@ impl CoverageGraph {
9191
// `catch_unwind()` handlers.
9292

9393
let mut basic_blocks = Vec::new();
94-
for bb in short_circuit_preorder(mir_body, bcb_filtered_successors) {
94+
let filtered_successors = |bb| bcb_filtered_successors(mir_body[bb].terminator());
95+
for bb in short_circuit_preorder(mir_body, filtered_successors)
96+
.filter(|&bb| mir_body[bb].terminator().kind != TerminatorKind::Unreachable)
97+
{
9598
if let Some(last) = basic_blocks.last() {
9699
let predecessors = &mir_body.basic_blocks.predecessors()[bb];
97100
if predecessors.len() > 1 || !predecessors.contains(last) {
@@ -347,15 +350,12 @@ impl BasicCoverageBlockData {
347350
}
348351

349352
// Returns the subset of a block's successors that are relevant to the coverage
350-
// graph, i.e. those that do not represent unwinds or unreachable branches.
353+
// graph, i.e. those that do not represent unwinds or false edges.
351354
// FIXME(#78544): MIR InstrumentCoverage: Improve coverage of `#[should_panic]` tests and
352355
// `catch_unwind()` handlers.
353356
fn bcb_filtered_successors<'a, 'tcx>(
354-
body: &'a mir::Body<'tcx>,
355-
bb: BasicBlock,
357+
terminator: &'a Terminator<'tcx>,
356358
) -> impl Iterator<Item = BasicBlock> + Captures<'a> + Captures<'tcx> {
357-
let terminator = body[bb].terminator();
358-
359359
let take_n_successors = match terminator.kind {
360360
// SwitchInt successors are never unwinds, so all of them should be traversed.
361361
TerminatorKind::SwitchInt { .. } => usize::MAX,
@@ -364,10 +364,7 @@ fn bcb_filtered_successors<'a, 'tcx>(
364364
_ => 1,
365365
};
366366

367-
terminator
368-
.successors()
369-
.take(take_n_successors)
370-
.filter(move |&successor| body[successor].terminator().kind != TerminatorKind::Unreachable)
367+
terminator.successors().take(take_n_successors)
371368
}
372369

373370
/// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the
@@ -544,7 +541,7 @@ fn short_circuit_preorder<'a, 'tcx, F, Iter>(
544541
filtered_successors: F,
545542
) -> impl Iterator<Item = BasicBlock> + Captures<'a> + Captures<'tcx>
546543
where
547-
F: Fn(&'a mir::Body<'tcx>, BasicBlock) -> Iter,
544+
F: Fn(BasicBlock) -> Iter,
548545
Iter: Iterator<Item = BasicBlock>,
549546
{
550547
let mut visited = BitSet::new_empty(body.basic_blocks.len());
@@ -556,7 +553,7 @@ where
556553
continue;
557554
}
558555

559-
worklist.extend(filtered_successors(body, bb));
556+
worklist.extend(filtered_successors(bb));
560557

561558
return Some(bb);
562559
}

0 commit comments

Comments
 (0)