Skip to content

Commit f432e15

Browse files
committed
coverage: Remove the loop-based heuristic for choosing expression edges
This heuristic makes sense on paper, but currently isn't worth the extra complexity, especially when trying to refactor counter creation in other directions.
1 parent d7d271a commit f432e15

18 files changed

+416
-510
lines changed

compiler/rustc_mir_transform/src/coverage/counters.rs

Lines changed: 7 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl<'a> MakeBcbCounters<'a> {
299299
while let Some(bcb) = traversal.next() {
300300
let _span = debug_span!("traversal", ?bcb).entered();
301301
if self.bcb_needs_counter.contains(bcb) {
302-
self.make_node_counter_and_out_edge_counters(&traversal, bcb);
302+
self.make_node_counter_and_out_edge_counters(bcb);
303303
}
304304
}
305305

@@ -312,12 +312,8 @@ impl<'a> MakeBcbCounters<'a> {
312312

313313
/// Make sure the given node has a node counter, and then make sure each of
314314
/// its out-edges has an edge counter (if appropriate).
315-
#[instrument(level = "debug", skip(self, traversal))]
316-
fn make_node_counter_and_out_edge_counters(
317-
&mut self,
318-
traversal: &TraverseCoverageGraphWithLoops<'_>,
319-
from_bcb: BasicCoverageBlock,
320-
) {
315+
#[instrument(level = "debug", skip(self))]
316+
fn make_node_counter_and_out_edge_counters(&mut self, from_bcb: BasicCoverageBlock) {
321317
// First, ensure that this node has a counter of some kind.
322318
// We might also use that counter to compute one of the out-edge counters.
323319
let node_counter = self.get_or_make_node_counter(from_bcb);
@@ -340,8 +336,7 @@ impl<'a> MakeBcbCounters<'a> {
340336

341337
// If there are out-edges without counters, choose one to be given an expression
342338
// (computed from this node and the other out-edges) instead of a physical counter.
343-
let Some(expression_to_bcb) =
344-
self.choose_out_edge_for_expression(traversal, &candidate_successors)
339+
let Some(expression_to_bcb) = self.choose_out_edge_for_expression(&candidate_successors)
345340
else {
346341
return;
347342
};
@@ -455,60 +450,16 @@ impl<'a> MakeBcbCounters<'a> {
455450
/// choose one to be given a counter expression instead of a physical counter.
456451
fn choose_out_edge_for_expression(
457452
&self,
458-
traversal: &TraverseCoverageGraphWithLoops<'_>,
459453
candidate_successors: &[BasicCoverageBlock],
460454
) -> Option<BasicCoverageBlock> {
461-
// Try to find a candidate that leads back to the top of a loop,
462-
// because reloop edges tend to be executed more times than loop-exit edges.
463-
if let Some(reloop_target) = self.find_good_reloop_edge(traversal, &candidate_successors) {
464-
debug!("Selecting reloop target {reloop_target:?} to get an expression");
465-
return Some(reloop_target);
466-
}
467-
468-
// We couldn't identify a "good" edge, so just choose an arbitrary one.
455+
// For now, just choose an arbitrary edge.
456+
// FIXME(Zalathar): This was greatly simplified to make other refactoring
457+
// easier, but eventually it might be good to make this smarter again.
469458
let arbitrary_target = candidate_successors.first().copied()?;
470459
debug!(?arbitrary_target, "selecting arbitrary out-edge to get an expression");
471460
Some(arbitrary_target)
472461
}
473462

474-
/// Given a set of candidate out-edges (represented by their successor node),
475-
/// tries to find one that leads back to the top of a loop.
476-
///
477-
/// Reloop edges are good candidates for counter expressions, because they
478-
/// will tend to be executed more times than a loop-exit edge, so it's nice
479-
/// for them to be able to avoid a physical counter increment.
480-
fn find_good_reloop_edge(
481-
&self,
482-
traversal: &TraverseCoverageGraphWithLoops<'_>,
483-
candidate_successors: &[BasicCoverageBlock],
484-
) -> Option<BasicCoverageBlock> {
485-
// If there are no candidates, avoid iterating over the loop stack.
486-
if candidate_successors.is_empty() {
487-
return None;
488-
}
489-
490-
// Consider each loop on the current traversal context stack, top-down.
491-
for reloop_bcbs in traversal.reloop_bcbs_per_loop() {
492-
// Try to find a candidate edge that doesn't exit this loop.
493-
for &target_bcb in candidate_successors {
494-
// An edge is a reloop edge if its target dominates any BCB that has
495-
// an edge back to the loop header. (Otherwise it's an exit edge.)
496-
let is_reloop_edge = reloop_bcbs.iter().any(|&reloop_bcb| {
497-
self.basic_coverage_blocks.dominates(target_bcb, reloop_bcb)
498-
});
499-
if is_reloop_edge {
500-
// We found a good out-edge to be given an expression.
501-
return Some(target_bcb);
502-
}
503-
}
504-
505-
// All of the candidate edges exit this loop, so keep looking
506-
// for a good reloop edge for one of the outer loops.
507-
}
508-
509-
None
510-
}
511-
512463
#[inline]
513464
fn edge_has_no_counter(
514465
&self,

compiler/rustc_mir_transform/src/coverage/graph.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -438,16 +438,6 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
438438
Self { basic_coverage_blocks, backedges, context_stack, visited }
439439
}
440440

441-
/// For each loop on the loop context stack (top-down), yields a list of BCBs
442-
/// within that loop that have an outgoing edge back to the loop header.
443-
pub(crate) fn reloop_bcbs_per_loop(&self) -> impl Iterator<Item = &[BasicCoverageBlock]> {
444-
self.context_stack
445-
.iter()
446-
.rev()
447-
.filter_map(|context| context.loop_header)
448-
.map(|header_bcb| self.backedges[header_bcb].as_slice())
449-
}
450-
451441
pub(crate) fn next(&mut self) -> Option<BasicCoverageBlock> {
452442
debug!(
453443
"TraverseCoverageGraphWithLoops::next - context_stack: {:?}",

tests/coverage/abort.cov-map

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,33 @@
11
Function name: abort::main
2-
Raw bytes (89): 0x[01, 01, 0a, 01, 27, 05, 09, 03, 0d, 22, 11, 03, 0d, 03, 0d, 22, 15, 03, 0d, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 0a, 00, 0b, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 31, 00, 32, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
2+
Raw bytes (81): 0x[01, 01, 06, 01, 13, 05, 09, 0d, 11, 0d, 15, 05, 09, 03, 0d, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 0d, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0a, 02, 0a, 00, 0b, 0d, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 0e, 00, 31, 00, 32, 0d, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 13, 01, 09, 00, 17, 16, 02, 05, 01, 02]
33
Number of files: 1
44
- file 0 => global file 1
5-
Number of expressions: 10
6-
- expression 0 operands: lhs = Counter(0), rhs = Expression(9, Add)
5+
Number of expressions: 6
6+
- expression 0 operands: lhs = Counter(0), rhs = Expression(4, Add)
77
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
8-
- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
9-
- expression 3 operands: lhs = Expression(8, Sub), rhs = Counter(4)
10-
- expression 4 operands: lhs = Expression(0, Add), rhs = Counter(3)
8+
- expression 2 operands: lhs = Counter(3), rhs = Counter(4)
9+
- expression 3 operands: lhs = Counter(3), rhs = Counter(5)
10+
- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
1111
- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(3)
12-
- expression 6 operands: lhs = Expression(8, Sub), rhs = Counter(5)
13-
- expression 7 operands: lhs = Expression(0, Add), rhs = Counter(3)
14-
- expression 8 operands: lhs = Expression(0, Add), rhs = Counter(3)
15-
- expression 9 operands: lhs = Counter(1), rhs = Counter(2)
1612
Number of file 0 mappings: 13
1713
- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
1814
- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
1915
= (c0 + (c1 + c2))
20-
- Code(Expression(8, Sub)) at (prev + 1, 12) to (start + 0, 25)
21-
= ((c0 + (c1 + c2)) - c3)
16+
- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 25)
2217
- Code(Counter(4)) at (prev + 0, 26) to (start + 2, 10)
23-
- Code(Expression(3, Sub)) at (prev + 2, 10) to (start + 0, 11)
24-
= (((c0 + (c1 + c2)) - c3) - c4)
25-
- Code(Expression(8, Sub)) at (prev + 2, 12) to (start + 0, 25)
26-
= ((c0 + (c1 + c2)) - c3)
18+
- Code(Expression(2, Sub)) at (prev + 2, 10) to (start + 0, 11)
19+
= (c3 - c4)
20+
- Code(Counter(3)) at (prev + 2, 12) to (start + 0, 25)
2721
- Code(Counter(5)) at (prev + 0, 26) to (start + 0, 49)
28-
- Code(Expression(6, Sub)) at (prev + 0, 49) to (start + 0, 50)
29-
= (((c0 + (c1 + c2)) - c3) - c5)
30-
- Code(Expression(8, Sub)) at (prev + 4, 12) to (start + 0, 25)
31-
= ((c0 + (c1 + c2)) - c3)
22+
- Code(Expression(3, Sub)) at (prev + 0, 49) to (start + 0, 50)
23+
= (c3 - c5)
24+
- Code(Counter(3)) at (prev + 4, 12) to (start + 0, 25)
3225
- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 49)
3326
- Code(Counter(2)) at (prev + 0, 49) to (start + 0, 50)
34-
- Code(Expression(9, Add)) at (prev + 1, 9) to (start + 0, 23)
27+
- Code(Expression(4, Add)) at (prev + 1, 9) to (start + 0, 23)
3528
= (c1 + c2)
36-
- Code(Counter(3)) at (prev + 2, 5) to (start + 1, 2)
29+
- Code(Expression(5, Sub)) at (prev + 2, 5) to (start + 1, 2)
30+
= ((c0 + (c1 + c2)) - c3)
3731
Max counter seen: c5
3832

3933
Function name: abort::might_abort

tests/coverage/assert.cov-map

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
Function name: assert::main
2-
Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 0a, 00, 0b, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
2+
Raw bytes (63): 0x[01, 01, 07, 01, 13, 05, 17, 09, 0d, 11, 05, 05, 17, 09, 0d, 03, 11, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 11, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 0e, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 0a, 00, 0b, 13, 01, 09, 00, 17, 1a, 02, 05, 01, 02]
33
Number of files: 1
44
- file 0 => global file 1
5-
Number of expressions: 8
6-
- expression 0 operands: lhs = Counter(0), rhs = Expression(6, Add)
7-
- expression 1 operands: lhs = Counter(1), rhs = Expression(7, Add)
5+
Number of expressions: 7
6+
- expression 0 operands: lhs = Counter(0), rhs = Expression(4, Add)
7+
- expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
88
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
9-
- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4)
10-
- expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(1)
11-
- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(4)
12-
- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add)
13-
- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
9+
- expression 3 operands: lhs = Counter(4), rhs = Counter(1)
10+
- expression 4 operands: lhs = Counter(1), rhs = Expression(5, Add)
11+
- expression 5 operands: lhs = Counter(2), rhs = Counter(3)
12+
- expression 6 operands: lhs = Expression(0, Add), rhs = Counter(4)
1413
Number of file 0 mappings: 9
1514
- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 27)
1615
- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
1716
= (c0 + (c1 + (c2 + c3)))
18-
- Code(Expression(5, Sub)) at (prev + 1, 12) to (start + 0, 26)
19-
= ((c0 + (c1 + (c2 + c3))) - c4)
17+
- Code(Counter(4)) at (prev + 1, 12) to (start + 0, 26)
2018
- Code(Counter(1)) at (prev + 0, 27) to (start + 2, 10)
21-
- Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32)
22-
= (((c0 + (c1 + (c2 + c3))) - c4) - c1)
19+
- Code(Expression(3, Sub)) at (prev + 2, 19) to (start + 0, 32)
20+
= (c4 - c1)
2321
- Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10)
2422
- Code(Counter(3)) at (prev + 2, 10) to (start + 0, 11)
25-
- Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23)
23+
- Code(Expression(4, Add)) at (prev + 1, 9) to (start + 0, 23)
2624
= (c1 + (c2 + c3))
27-
- Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
25+
- Code(Expression(6, Sub)) at (prev + 2, 5) to (start + 1, 2)
26+
= ((c0 + (c1 + (c2 + c3))) - c4)
2827
Max counter seen: c4
2928

3029
Function name: assert::might_fail_assert

tests/coverage/assert.coverage

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
LL| 1|fn main() -> Result<(), u8> {
1111
LL| 1| let mut countdown = 10;
1212
LL| 11| while countdown > 0 {
13-
LL| 11| if countdown == 1 {
13+
LL| 10| if countdown == 1 {
1414
LL| 1| might_fail_assert(3);
15-
LL| 10| } else if countdown < 5 {
15+
LL| 9| } else if countdown < 5 {
1616
LL| 3| might_fail_assert(2);
1717
LL| 6| }
1818
LL| 10| countdown -= 1;
1919
LL| | }
20-
LL| 0| Ok(())
21-
LL| 0|}
20+
LL| 1| Ok(())
21+
LL| 1|}
2222
LL| |
2323
LL| |// Notes:
2424
LL| |// 1. Compare this program and its coverage results to those of the very similar test

tests/coverage/branch/no-mir-spans.cov-map

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Number of file 0 mappings: 2
2323
Max counter seen: c2
2424

2525
Function name: no_mir_spans::while_op_and
26-
Raw bytes (25): 0x[01, 01, 01, 09, 0d, 03, 01, 22, 01, 00, 13, 20, 09, 05, 05, 0b, 00, 10, 20, 02, 0d, 00, 14, 00, 19]
26+
Raw bytes (25): 0x[01, 01, 01, 09, 0d, 03, 01, 22, 01, 00, 13, 20, 09, 05, 05, 0b, 00, 10, 20, 0d, 02, 00, 14, 00, 19]
2727
Number of files: 1
2828
- file 0 => global file 1
2929
Number of expressions: 1
@@ -33,9 +33,9 @@ Number of file 0 mappings: 3
3333
- Branch { true: Counter(2), false: Counter(1) } at (prev + 5, 11) to (start + 0, 16)
3434
true = c2
3535
false = c1
36-
- Branch { true: Expression(0, Sub), false: Counter(3) } at (prev + 0, 20) to (start + 0, 25)
37-
true = (c2 - c3)
38-
false = c3
36+
- Branch { true: Counter(3), false: Expression(0, Sub) } at (prev + 0, 20) to (start + 0, 25)
37+
true = c3
38+
false = (c2 - c3)
3939
Max counter seen: c3
4040

4141
Function name: no_mir_spans::while_op_or

tests/coverage/branch/while.cov-map

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,29 @@ Number of file 0 mappings: 6
3535
Max counter seen: c2
3636

3737
Function name: while::while_op_and
38-
Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 11, 0d, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 11, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 0f, 04, 01, 00, 02]
38+
Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 11, 0e, 03, 0d, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0d, 0e, 00, 0b, 00, 10, 0d, 00, 14, 00, 19, 20, 09, 11, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 0b, 04, 01, 00, 02]
3939
Number of files: 1
4040
- file 0 => global file 1
4141
Number of expressions: 4
4242
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
4343
- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(3)
44-
- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
45-
- expression 3 operands: lhs = Counter(4), rhs = Counter(3)
44+
- expression 2 operands: lhs = Counter(4), rhs = Expression(3, Sub)
45+
- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(3)
4646
Number of file 0 mappings: 8
4747
- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16)
4848
- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18)
4949
- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16)
5050
= (c1 + c2)
51-
- Branch { true: Expression(2, Sub), false: Counter(3) } at (prev + 0, 11) to (start + 0, 16)
52-
true = ((c1 + c2) - c3)
53-
false = c3
54-
- Code(Expression(2, Sub)) at (prev + 0, 20) to (start + 0, 25)
55-
= ((c1 + c2) - c3)
51+
- Branch { true: Counter(3), false: Expression(3, Sub) } at (prev + 0, 11) to (start + 0, 16)
52+
true = c3
53+
false = ((c1 + c2) - c3)
54+
- Code(Counter(3)) at (prev + 0, 20) to (start + 0, 25)
5655
- Branch { true: Counter(2), false: Counter(4) } at (prev + 0, 20) to (start + 0, 25)
5756
true = c2
5857
false = c4
5958
- Code(Counter(2)) at (prev + 0, 26) to (start + 3, 6)
60-
- Code(Expression(3, Add)) at (prev + 4, 1) to (start + 0, 2)
61-
= (c4 + c3)
59+
- Code(Expression(2, Add)) at (prev + 4, 1) to (start + 0, 2)
60+
= (c4 + ((c1 + c2) - c3))
6261
Max counter seen: c4
6362

6463
Function name: while::while_op_or

0 commit comments

Comments
 (0)