coverage: Extract CoverageGraph::bcb_has_multiple_in_edges
This was previously a helper method in `MakeBcbCounters`, but putting it in the graph lets us call it from `BcbBranch`, and gives us a more fine-grained borrow.
This commit is contained in:
parent
a1e2c10b1f
commit
276a32994e
@ -341,7 +341,7 @@ fn get_or_make_counter_operand(&mut self, bcb: BasicCoverageBlock) -> BcbCounter
|
|||||||
// A BCB with only one incoming edge gets a simple `Counter` (via `make_counter()`).
|
// A BCB with only one incoming edge gets a simple `Counter` (via `make_counter()`).
|
||||||
// Also, a BCB that loops back to itself gets a simple `Counter`. This may indicate the
|
// Also, a BCB that loops back to itself gets a simple `Counter`. This may indicate the
|
||||||
// program results in a tight infinite loop, but it should still compile.
|
// program results in a tight infinite loop, but it should still compile.
|
||||||
let one_path_to_target = self.bcb_has_one_path_to_target(bcb);
|
let one_path_to_target = !self.basic_coverage_blocks.bcb_has_multiple_in_edges(bcb);
|
||||||
if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) {
|
if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) {
|
||||||
let counter_kind = self.coverage_counters.make_counter();
|
let counter_kind = self.coverage_counters.make_counter();
|
||||||
if one_path_to_target {
|
if one_path_to_target {
|
||||||
@ -510,11 +510,4 @@ fn branch_counter(&self, branch: &BcbBranch) -> Option<&BcbCounter> {
|
|||||||
self.coverage_counters.bcb_counters[to_bcb].as_ref()
|
self.coverage_counters.bcb_counters[to_bcb].as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the BasicCoverageBlock has zero or one incoming edge. (If zero, it should be
|
|
||||||
/// the entry point for the function.)
|
|
||||||
#[inline]
|
|
||||||
fn bcb_has_one_path_to_target(&self, bcb: BasicCoverageBlock) -> bool {
|
|
||||||
self.bcb_predecessors(bcb).len() <= 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -199,6 +199,20 @@ pub fn dominates(&self, dom: BasicCoverageBlock, node: BasicCoverageBlock) -> bo
|
|||||||
pub fn cmp_in_dominator_order(&self, a: BasicCoverageBlock, b: BasicCoverageBlock) -> Ordering {
|
pub fn cmp_in_dominator_order(&self, a: BasicCoverageBlock, b: BasicCoverageBlock) -> Ordering {
|
||||||
self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
|
self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the given node has 2 or more in-edges, i.e. 2 or more
|
||||||
|
/// predecessors.
|
||||||
|
///
|
||||||
|
/// This property is interesting to code that assigns counters to nodes and
|
||||||
|
/// edges, because if a node _doesn't_ have multiple in-edges, then there's
|
||||||
|
/// no benefit in having a separate counter for its in-edge, because it
|
||||||
|
/// would have the same value as the node's own counter.
|
||||||
|
///
|
||||||
|
/// FIXME: That assumption might not be true for [`TerminatorKind::Yield`]?
|
||||||
|
#[inline(always)]
|
||||||
|
pub(super) fn bcb_has_multiple_in_edges(&self, bcb: BasicCoverageBlock) -> bool {
|
||||||
|
self.predecessors[bcb].len() > 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<BasicCoverageBlock> for CoverageGraph {
|
impl Index<BasicCoverageBlock> for CoverageGraph {
|
||||||
@ -335,7 +349,7 @@ pub fn from_to(
|
|||||||
to_bcb: BasicCoverageBlock,
|
to_bcb: BasicCoverageBlock,
|
||||||
basic_coverage_blocks: &CoverageGraph,
|
basic_coverage_blocks: &CoverageGraph,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let edge_from_bcb = if basic_coverage_blocks.predecessors[to_bcb].len() > 1 {
|
let edge_from_bcb = if basic_coverage_blocks.bcb_has_multiple_in_edges(from_bcb) {
|
||||||
Some(from_bcb)
|
Some(from_bcb)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
Loading…
Reference in New Issue
Block a user