From 276a32994e30aeca2cd7f5039009e9cd7b6f2e00 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 30 Oct 2023 20:54:19 +1100 Subject: [PATCH] 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. --- .../rustc_mir_transform/src/coverage/counters.rs | 9 +-------- .../rustc_mir_transform/src/coverage/graph.rs | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index ca7feb942fe..b5fba797dc4 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -341,7 +341,7 @@ impl<'a> MakeBcbCounters<'a> { // 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 // 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) { let counter_kind = self.coverage_counters.make_counter(); if one_path_to_target { @@ -510,11 +510,4 @@ impl<'a> MakeBcbCounters<'a> { 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 - } } diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 0d807db404c..b3a69e9fa82 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -199,6 +199,20 @@ impl CoverageGraph { pub fn cmp_in_dominator_order(&self, a: BasicCoverageBlock, b: BasicCoverageBlock) -> Ordering { 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 for CoverageGraph { @@ -335,7 +349,7 @@ impl BcbBranch { to_bcb: BasicCoverageBlock, basic_coverage_blocks: &CoverageGraph, ) -> 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) } else { None