coverage: Avoid referring to "coverage spans" in counter creation
The counter-creation code needs to know which BCB nodes require counters, but isn't interested in why, so treat that as an opaque detail.
This commit is contained in:
parent
26b2b8d162
commit
96d545a33b
@ -74,12 +74,11 @@ pub(super) struct CoverageCounters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CoverageCounters {
|
impl CoverageCounters {
|
||||||
/// Makes [`BcbCounter`] `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
|
/// Ensures that each BCB node needing a counter has one, by creating physical
|
||||||
/// indirectly associated with coverage spans, and accumulates additional `Expression`s
|
/// counters or counter expressions for nodes and edges as required.
|
||||||
/// representing intermediate values.
|
|
||||||
pub(super) fn make_bcb_counters(
|
pub(super) fn make_bcb_counters(
|
||||||
basic_coverage_blocks: &CoverageGraph,
|
basic_coverage_blocks: &CoverageGraph,
|
||||||
bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool,
|
bcb_needs_counter: impl Fn(BasicCoverageBlock) -> bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let num_bcbs = basic_coverage_blocks.num_nodes();
|
let num_bcbs = basic_coverage_blocks.num_nodes();
|
||||||
|
|
||||||
@ -91,8 +90,7 @@ impl CoverageCounters {
|
|||||||
expressions_memo: FxHashMap::default(),
|
expressions_memo: FxHashMap::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
MakeBcbCounters::new(&mut this, basic_coverage_blocks)
|
MakeBcbCounters::new(&mut this, basic_coverage_blocks).make_bcb_counters(bcb_needs_counter);
|
||||||
.make_bcb_counters(bcb_has_coverage_spans);
|
|
||||||
|
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
@ -241,10 +239,7 @@ impl CoverageCounters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traverse the `CoverageGraph` and add either a `Counter` or `Expression` to every BCB, to be
|
/// Helper struct that allows counter creation to inspect the BCB graph.
|
||||||
/// injected with coverage spans. `Expressions` have no runtime overhead, so if a viable expression
|
|
||||||
/// (adding or subtracting two other counters or expressions) can compute the same result as an
|
|
||||||
/// embedded counter, an `Expression` should be used.
|
|
||||||
struct MakeBcbCounters<'a> {
|
struct MakeBcbCounters<'a> {
|
||||||
coverage_counters: &'a mut CoverageCounters,
|
coverage_counters: &'a mut CoverageCounters,
|
||||||
basic_coverage_blocks: &'a CoverageGraph,
|
basic_coverage_blocks: &'a CoverageGraph,
|
||||||
@ -264,30 +259,21 @@ impl<'a> MakeBcbCounters<'a> {
|
|||||||
/// One way to predict which branch executes the least is by considering loops. A loop is exited
|
/// One way to predict which branch executes the least is by considering loops. A loop is exited
|
||||||
/// at a branch, so the branch that jumps to a `BasicCoverageBlock` outside the loop is almost
|
/// at a branch, so the branch that jumps to a `BasicCoverageBlock` outside the loop is almost
|
||||||
/// always executed less than the branch that does not exit the loop.
|
/// always executed less than the branch that does not exit the loop.
|
||||||
fn make_bcb_counters(&mut self, bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool) {
|
fn make_bcb_counters(&mut self, bcb_needs_counter: impl Fn(BasicCoverageBlock) -> bool) {
|
||||||
debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
|
debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
|
||||||
|
|
||||||
// Walk the `CoverageGraph`. For each `BasicCoverageBlock` node with an associated
|
// Traverse the coverage graph, ensuring that every node that needs a
|
||||||
// coverage span, add a counter. If the `BasicCoverageBlock` branches, add a counter or
|
// coverage counter has one.
|
||||||
// expression to each branch `BasicCoverageBlock` (if the branch BCB has only one incoming
|
|
||||||
// edge) or edge from the branching BCB to the branch BCB (if the branch BCB has multiple
|
|
||||||
// incoming edges).
|
|
||||||
//
|
//
|
||||||
// The `TraverseCoverageGraphWithLoops` traversal ensures that, when a loop is encountered,
|
// The traversal tries to ensure that, when a loop is encountered, all
|
||||||
// all `BasicCoverageBlock` nodes in the loop are visited before visiting any node outside
|
// nodes within the loop are visited before visiting any nodes outside
|
||||||
// the loop. The `traversal` state includes a `context_stack`, providing a way to know if
|
// the loop. It also keeps track of which loop(s) the traversal is
|
||||||
// the current BCB is in one or more nested loops or not.
|
// currently inside.
|
||||||
let mut traversal = TraverseCoverageGraphWithLoops::new(self.basic_coverage_blocks);
|
let mut traversal = TraverseCoverageGraphWithLoops::new(self.basic_coverage_blocks);
|
||||||
while let Some(bcb) = traversal.next() {
|
while let Some(bcb) = traversal.next() {
|
||||||
if bcb_has_coverage_spans(bcb) {
|
let _span = debug_span!("traversal", ?bcb).entered();
|
||||||
debug!("{:?} has at least one coverage span. Get or make its counter", bcb);
|
if bcb_needs_counter(bcb) {
|
||||||
self.make_node_and_branch_counters(&traversal, bcb);
|
self.make_node_and_branch_counters(&traversal, bcb);
|
||||||
} else {
|
|
||||||
debug!(
|
|
||||||
"{:?} does not have any coverage spans. A counter will only be added if \
|
|
||||||
and when a covered BCB has an expression dependency.",
|
|
||||||
bcb,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +284,7 @@ impl<'a> MakeBcbCounters<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(self, traversal))]
|
||||||
fn make_node_and_branch_counters(
|
fn make_node_and_branch_counters(
|
||||||
&mut self,
|
&mut self,
|
||||||
traversal: &TraverseCoverageGraphWithLoops<'_>,
|
traversal: &TraverseCoverageGraphWithLoops<'_>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user