Skip to content

Commit 248b9fc

Browse files
committed
coverage: Unbox and simplify bcb_filtered_successors
This function already has access to the MIR body, so instead of taking a reference to a terminator, it's simpler and easier to pass in a basic block index. There is no need to box the returned iterator if we instead add appropriate lifetime captures, and make `short_circuit_preorder` generic over the type of iterator it expects. We can also greatly simplify the function's implementation by observing that the only difference between its two cases is whether we take all of a BB's successors, or just the first one.
1 parent 344594f commit 248b9fc

File tree

2 files changed

+26
-32
lines changed

2 files changed

+26
-32
lines changed

compiler/rustc_mir_transform/src/coverage/graph.rs

Lines changed: 25 additions & 31 deletions
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, Terminator, TerminatorKind};
6+
use rustc_middle::mir::{self, BasicBlock, TerminatorKind};
77

88
use std::cmp::Ordering;
99
use std::ops::{Index, IndexMut};
@@ -37,9 +37,8 @@ impl CoverageGraph {
3737
}
3838
let bcb_data = &bcbs[bcb];
3939
let mut bcb_successors = Vec::new();
40-
for successor in
41-
bcb_filtered_successors(&mir_body, &bcb_data.terminator(mir_body).kind)
42-
.filter_map(|successor_bb| bb_to_bcb[successor_bb])
40+
for successor in bcb_filtered_successors(&mir_body, bcb_data.last_bb())
41+
.filter_map(|successor_bb| bb_to_bcb[successor_bb])
4342
{
4443
if !seen[successor] {
4544
seen[successor] = true;
@@ -316,11 +315,6 @@ impl BasicCoverageBlockData {
316315
pub fn last_bb(&self) -> BasicBlock {
317316
*self.basic_blocks.last().unwrap()
318317
}
319-
320-
#[inline(always)]
321-
pub fn terminator<'a, 'tcx>(&self, mir_body: &'a mir::Body<'tcx>) -> &'a Terminator<'tcx> {
322-
&mir_body[self.last_bb()].terminator()
323-
}
324318
}
325319

326320
/// Represents a successor from a branching BasicCoverageBlock (such as the arms of a `SwitchInt`)
@@ -362,26 +356,28 @@ impl std::fmt::Debug for BcbBranch {
362356
}
363357
}
364358

365-
// Returns the `Terminator`s non-unwind successors.
359+
// Returns the subset of a block's successors that are relevant to the coverage
360+
// graph, i.e. those that do not represent unwinds or unreachable branches.
366361
// FIXME(#78544): MIR InstrumentCoverage: Improve coverage of `#[should_panic]` tests and
367362
// `catch_unwind()` handlers.
368363
fn bcb_filtered_successors<'a, 'tcx>(
369364
body: &'a mir::Body<'tcx>,
370-
term_kind: &'a TerminatorKind<'tcx>,
371-
) -> Box<dyn Iterator<Item = BasicBlock> + 'a> {
372-
Box::new(
373-
match &term_kind {
374-
// SwitchInt successors are never unwind, and all of them should be traversed.
375-
TerminatorKind::SwitchInt { ref targets, .. } => {
376-
None.into_iter().chain(targets.all_targets().into_iter().copied())
377-
}
378-
// For all other kinds, return only the first successor, if any, and ignore unwinds.
379-
// NOTE: `chain(&[])` is required to coerce the `option::iter` (from
380-
// `next().into_iter()`) into the `mir::Successors` aliased type.
381-
_ => term_kind.successors().next().into_iter().chain((&[]).into_iter().copied()),
382-
}
383-
.filter(move |&successor| body[successor].terminator().kind != TerminatorKind::Unreachable),
384-
)
365+
bb: BasicBlock,
366+
) -> impl Iterator<Item = BasicBlock> + Captures<'a> + Captures<'tcx> {
367+
let terminator = body[bb].terminator();
368+
369+
let take_n_successors = match terminator.kind {
370+
// SwitchInt successors are never unwinds, so all of them should be traversed.
371+
TerminatorKind::SwitchInt { .. } => usize::MAX,
372+
// For all other kinds, return only the first successor (if any), ignoring any
373+
// unwind successors.
374+
_ => 1,
375+
};
376+
377+
terminator
378+
.successors()
379+
.take(take_n_successors)
380+
.filter(move |&successor| body[successor].terminator().kind != TerminatorKind::Unreachable)
385381
}
386382

387383
/// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the
@@ -553,15 +549,13 @@ pub(super) fn find_loop_backedges(
553549
backedges
554550
}
555551

556-
fn short_circuit_preorder<'a, 'tcx, F>(
552+
fn short_circuit_preorder<'a, 'tcx, F, Iter>(
557553
body: &'a mir::Body<'tcx>,
558554
filtered_successors: F,
559555
) -> impl Iterator<Item = BasicBlock> + Captures<'a> + Captures<'tcx>
560556
where
561-
F: Fn(
562-
&'a mir::Body<'tcx>,
563-
&'a TerminatorKind<'tcx>,
564-
) -> Box<dyn Iterator<Item = BasicBlock> + 'a>,
557+
F: Fn(&'a mir::Body<'tcx>, BasicBlock) -> Iter,
558+
Iter: Iterator<Item = BasicBlock>,
565559
{
566560
let mut visited = BitSet::new_empty(body.basic_blocks.len());
567561
let mut worklist = vec![mir::START_BLOCK];
@@ -572,7 +566,7 @@ where
572566
continue;
573567
}
574568

575-
worklist.extend(filtered_successors(body, &body[bb].terminator().kind));
569+
worklist.extend(filtered_successors(body, bb));
576570

577571
return Some(bb);
578572
}

compiler/rustc_mir_transform/src/coverage/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ fn print_coverage_graphviz(
241241
" {:?} [label=\"{:?}: {}\"];\n{}",
242242
bcb,
243243
bcb,
244-
bcb_data.terminator(mir_body).kind.name(),
244+
mir_body[bcb_data.last_bb()].terminator().kind.name(),
245245
basic_coverage_blocks
246246
.successors(bcb)
247247
.map(|successor| { format!(" {:?} -> {:?};", bcb, successor) })

0 commit comments

Comments
 (0)