1
Fork 0

Rollup merge of #130263 - Zalathar:sums, r=compiler-errors

coverage: Simplify creation of sum counters

A small and self-contained improvement, extracted from some larger changes that I'm still working on.

Ultimately I want to avoid creating these sum counter-expressions in some cases (in favour of just adding physical counters directly to the nodes we care about), so a good incremental move towards that is splitting the “gather edge counters” step out from the ”build a sum of those counters” step.

Creating an extra intermediate vector should have negligible cost (and coverage isn't exercised by the benchmark suite anyway). The removed logging is redundant with the `#[instrument(..)]` logging we already have on the underlying method calls.
This commit is contained in:
Matthias Krüger 2024-09-12 19:03:42 +02:00 committed by GitHub
commit 7cae463bda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -155,12 +155,14 @@ impl CoverageCounters {
BcbCounter::Expression { id } BcbCounter::Expression { id }
} }
/// Variant of `make_expression` that makes `lhs` optional and assumes [`Op::Add`]. /// Creates a counter that is the sum of the given counters.
/// ///
/// This is useful when using [`Iterator::fold`] to build an arbitrary-length sum. /// Returns `None` if the given list of counters was empty.
fn make_sum_expression(&mut self, lhs: Option<BcbCounter>, rhs: BcbCounter) -> BcbCounter { fn make_sum(&mut self, counters: &[BcbCounter]) -> Option<BcbCounter> {
let Some(lhs) = lhs else { return rhs }; counters
self.make_expression(lhs, Op::Add, rhs) .iter()
.copied()
.reduce(|accum, counter| self.make_expression(accum, Op::Add, counter))
} }
pub(super) fn num_counters(&self) -> usize { pub(super) fn num_counters(&self) -> usize {
@ -315,20 +317,17 @@ impl<'a> MakeBcbCounters<'a> {
// For each out-edge other than the one that was chosen to get an expression, // For each out-edge other than the one that was chosen to get an expression,
// ensure that it has a counter (existing counter/expression or a new counter), // ensure that it has a counter (existing counter/expression or a new counter),
// and accumulate the corresponding counters into a single sum expression. // and accumulate the corresponding counters into a single sum expression.
let sum_of_all_other_out_edges: BcbCounter = { let other_out_edge_counters = successors
let _span = debug_span!("sum_of_all_other_out_edges", ?expression_to_bcb).entered();
successors
.iter() .iter()
.copied() .copied()
// Skip the chosen edge, since we'll calculate its count from this sum. // Skip the chosen edge, since we'll calculate its count from this sum.
.filter(|&to_bcb| to_bcb != expression_to_bcb) .filter(|&to_bcb| to_bcb != expression_to_bcb)
.fold(None, |accum, to_bcb| { .map(|to_bcb| self.get_or_make_edge_counter(from_bcb, to_bcb))
let _span = debug_span!("to_bcb", ?accum, ?to_bcb).entered(); .collect::<Vec<_>>();
let edge_counter = self.get_or_make_edge_counter(from_bcb, to_bcb); let sum_of_all_other_out_edges: BcbCounter = self
Some(self.coverage_counters.make_sum_expression(accum, edge_counter)) .coverage_counters
}) .make_sum(&other_out_edge_counters)
.expect("there must be at least one other out-edge") .expect("there must be at least one other out-edge");
};
// Now create an expression for the chosen edge, by taking the counter // Now create an expression for the chosen edge, by taking the counter
// for its source node and subtracting the sum of its sibling out-edges. // for its source node and subtracting the sum of its sibling out-edges.
@ -375,20 +374,15 @@ impl<'a> MakeBcbCounters<'a> {
// A BCB with multiple incoming edges can compute its count by ensuring that counters // A BCB with multiple incoming edges can compute its count by ensuring that counters
// exist for each of those edges, and then adding them up to get a total count. // exist for each of those edges, and then adding them up to get a total count.
let sum_of_in_edges: BcbCounter = { let in_edge_counters = self.basic_coverage_blocks.predecessors[bcb]
let _span = debug_span!("sum_of_in_edges", ?bcb).entered();
// We avoid calling `self.bcb_predecessors` here so that we can
// call methods on `&mut self` inside the fold.
self.basic_coverage_blocks.predecessors[bcb]
.iter() .iter()
.copied() .copied()
.fold(None, |accum, from_bcb| { .map(|from_bcb| self.get_or_make_edge_counter(from_bcb, bcb))
let _span = debug_span!("from_bcb", ?accum, ?from_bcb).entered(); .collect::<Vec<_>>();
let edge_counter = self.get_or_make_edge_counter(from_bcb, bcb); let sum_of_in_edges: BcbCounter = self
Some(self.coverage_counters.make_sum_expression(accum, edge_counter)) .coverage_counters
}) .make_sum(&in_edge_counters)
.expect("there must be at least one in-edge") .expect("there must be at least one in-edge");
};
debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}"); debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}");
self.coverage_counters.set_bcb_counter(bcb, sum_of_in_edges) self.coverage_counters.set_bcb_counter(bcb, sum_of_in_edges)