Skip to content

Commit d82ec95

Browse files
Rollup merge of #136957 - Zalathar:counters, r=oli-obk
coverage: Eliminate more counters by giving them to unreachable nodes When preparing a function's coverage counters and metadata during codegen, any part of the original coverage graph that was removed by MIR optimizations can be treated as having an execution count of zero. Somewhat counter-intuitively, if we give those unreachable nodes a _higher_ priority for receiving physical counters (instead of counter expressions), that ends up reducing the total number of physical counters needed. This works because if a node is unreachable, we don't actually create a physical counter for it. Instead that node gets a fixed zero counter, and any other node that would have relied on that physical counter in its counter expression can just ignore that term completely.
2 parents 82110ca + ab786d3 commit d82ec95

11 files changed

+237
-229
lines changed

compiler/rustc_mir_transform/src/coverage/counters.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,8 @@ pub(crate) fn transcribe_counters(
114114
let mut new_counters_for_sites = |sites: Vec<BasicCoverageBlock>| {
115115
sites.into_iter().map(|node| new.ensure_phys_counter(node)).collect::<Vec<_>>()
116116
};
117-
let mut pos = new_counters_for_sites(pos);
118-
let mut neg = new_counters_for_sites(neg);
119-
120-
// These sorts are also not strictly necessary; see above.
121-
pos.sort();
122-
neg.sort();
117+
let pos = new_counters_for_sites(pos);
118+
let neg = new_counters_for_sites(neg);
123119

124120
let pos_counter = new.make_sum(&pos).unwrap_or(CovTerm::Zero);
125121
let new_counter = new.make_subtracted_sum(pos_counter, &neg);

compiler/rustc_mir_transform/src/coverage/query.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,20 @@ fn coverage_ids_info<'tcx>(
123123
}
124124
}
125125

126-
// FIXME(Zalathar): It should be possible to sort `priority_list[1..]` by
127-
// `!bcbs_seen.contains(bcb)` to simplify the mappings even further, at the
128-
// expense of some churn in the tests. When doing so, also consider removing
129-
// the sorts in `transcribe_counters`.
130-
let node_counters = make_node_counters(&fn_cov_info.node_flow_data, &fn_cov_info.priority_list);
126+
// Clone the priority list so that we can re-sort it.
127+
let mut priority_list = fn_cov_info.priority_list.clone();
128+
// The first ID in the priority list represents the synthetic "sink" node,
129+
// and must remain first so that it _never_ gets a physical counter.
130+
debug_assert_eq!(priority_list[0], priority_list.iter().copied().max().unwrap());
131+
assert!(!bcbs_seen.contains(priority_list[0]));
132+
// Partition the priority list, so that unreachable nodes (removed by MIR opts)
133+
// are sorted later and therefore are _more_ likely to get a physical counter.
134+
// This is counter-intuitive, but it means that `transcribe_counters` can
135+
// easily skip those unused physical counters and replace them with zero.
136+
// (The original ordering remains in effect within both partitions.)
137+
priority_list[1..].sort_by_key(|&bcb| !bcbs_seen.contains(bcb));
138+
139+
let node_counters = make_node_counters(&fn_cov_info.node_flow_data, &priority_list);
131140
let coverage_counters = transcribe_counters(&node_counters, &bcb_needs_counter, &bcbs_seen);
132141

133142
let CoverageCounters {

tests/coverage/assert_not.cov-map

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
Function name: assert_not::main
2-
Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 09, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 0d, 01, 01, 00, 02]
2+
Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 12, 01, 02, 05, 00, 14, 01, 01, 05, 00, 14, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02]
33
Number of files: 1
44
- file 0 => global file 1
55
Number of expressions: 0
66
Number of file 0 mappings: 5
77
- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 18)
8-
- Code(Counter(1)) at (prev + 2, 5) to (start + 0, 20)
9-
- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 20)
10-
- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 22)
11-
- Code(Counter(3)) at (prev + 1, 1) to (start + 0, 2)
12-
Highest counter ID seen: c3
8+
- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 20)
9+
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 20)
10+
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
11+
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
12+
Highest counter ID seen: c0
1313

tests/coverage/async2.cov-map

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ Number of file 0 mappings: 1
88
Highest counter ID seen: c0
99

1010
Function name: async2::async_func::{closure#0}
11-
Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 17, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
11+
Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 17, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
1212
Number of files: 1
1313
- file 0 => global file 1
1414
Number of expressions: 0
1515
Number of file 0 mappings: 4
1616
- Code(Counter(0)) at (prev + 15, 23) to (start + 3, 9)
17-
- Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
17+
- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6)
1818
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
1919
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
20-
Highest counter ID seen: c1
20+
Highest counter ID seen: c0
2121

2222
Function name: async2::async_func_just_println
2323
Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 24]
@@ -47,14 +47,14 @@ Number of file 0 mappings: 1
4747
Highest counter ID seen: c0
4848

4949
Function name: async2::non_async_func
50-
Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
50+
Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
5151
Number of files: 1
5252
- file 0 => global file 1
5353
Number of expressions: 0
5454
Number of file 0 mappings: 4
5555
- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 9)
56-
- Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
56+
- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6)
5757
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
5858
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
59-
Highest counter ID seen: c1
59+
Highest counter ID seen: c0
6060

tests/coverage/bad_counter_ids.cov-map

+9-9
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@ Number of file 0 mappings: 3
2020
Highest counter ID seen: c0
2121

2222
Function name: bad_counter_ids::eq_good
23-
Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 1f, 05, 03, 01, 00, 02]
23+
Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 1f, 01, 03, 01, 00, 02]
2424
Number of files: 1
2525
- file 0 => global file 1
2626
Number of expressions: 0
2727
Number of file 0 mappings: 2
2828
- Code(Counter(0)) at (prev + 16, 1) to (start + 2, 31)
29-
- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2)
30-
Highest counter ID seen: c1
29+
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
30+
Highest counter ID seen: c0
3131

3232
Function name: bad_counter_ids::eq_good_message
33-
Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 05, 01, 01, 00, 02]
33+
Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02]
3434
Number of files: 1
3535
- file 0 => global file 1
3636
Number of expressions: 0
3737
Number of file 0 mappings: 3
3838
- Code(Counter(0)) at (prev + 21, 1) to (start + 2, 15)
3939
- Code(Zero) at (prev + 2, 32) to (start + 0, 43)
40-
- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
41-
Highest counter ID seen: c1
40+
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
41+
Highest counter ID seen: c0
4242

4343
Function name: bad_counter_ids::ne_bad
4444
Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 1f, 00, 03, 01, 00, 02]
@@ -51,15 +51,15 @@ Number of file 0 mappings: 2
5151
Highest counter ID seen: c0
5252

5353
Function name: bad_counter_ids::ne_bad_message
54-
Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 05, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
54+
Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
5555
Number of files: 1
5656
- file 0 => global file 1
5757
Number of expressions: 0
5858
Number of file 0 mappings: 3
5959
- Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15)
60-
- Code(Counter(1)) at (prev + 2, 32) to (start + 0, 43)
60+
- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43)
6161
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
62-
Highest counter ID seen: c1
62+
Highest counter ID seen: c0
6363

6464
Function name: bad_counter_ids::ne_good
6565
Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 1f, 01, 03, 01, 00, 02]

0 commit comments

Comments
 (0)