Skip to content

Commit fbab055

Browse files
committed
coverage: Give the instrumentor its own counter type, separate from MIR
This splits off `BcbCounter` from MIR's `CoverageKind`, allowing the two types to evolve in different directions as necessary.
1 parent 629437e commit fbab055

File tree

5 files changed

+129
-85
lines changed

5 files changed

+129
-85
lines changed

compiler/rustc_middle/src/mir/coverage.rs

-15
Original file line numberDiff line numberDiff line change
@@ -96,21 +96,6 @@ pub enum CoverageKind {
9696
Unreachable,
9797
}
9898

99-
impl CoverageKind {
100-
pub fn as_operand(&self) -> Operand {
101-
use CoverageKind::*;
102-
match *self {
103-
Counter { id, .. } => Operand::Counter(id),
104-
Expression { id, .. } => Operand::Expression(id),
105-
Unreachable => bug!("Unreachable coverage cannot be part of an expression"),
106-
}
107-
}
108-
109-
pub fn is_expression(&self) -> bool {
110-
matches!(self, Self::Expression { .. })
111-
}
112-
}
113-
11499
impl Debug for CoverageKind {
115100
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
116101
use CoverageKind::*;

compiler/rustc_mir_transform/src/coverage/counters.rs

+61-19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,48 @@ use rustc_index::bit_set::BitSet;
1414
use rustc_index::IndexVec;
1515
use rustc_middle::mir::coverage::*;
1616

17+
use std::fmt::{self, Debug};
18+
19+
/// The coverage counter or counter expression associated with a particular
20+
/// BCB node or BCB edge.
21+
#[derive(Clone)]
22+
pub(super) enum BcbCounter {
23+
Counter { function_source_hash: u64, id: CounterId },
24+
Expression { id: ExpressionId, lhs: Operand, op: Op, rhs: Operand },
25+
}
26+
27+
impl BcbCounter {
28+
fn is_expression(&self) -> bool {
29+
matches!(self, Self::Expression { .. })
30+
}
31+
32+
pub(super) fn as_operand(&self) -> Operand {
33+
match *self {
34+
BcbCounter::Counter { id, .. } => Operand::Counter(id),
35+
BcbCounter::Expression { id, .. } => Operand::Expression(id),
36+
}
37+
}
38+
}
39+
40+
impl Debug for BcbCounter {
41+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
42+
match self {
43+
Self::Counter { id, .. } => write!(fmt, "Counter({:?})", id.index()),
44+
Self::Expression { id, lhs, op, rhs } => write!(
45+
fmt,
46+
"Expression({:?}) = {:?} {} {:?}",
47+
id.index(),
48+
lhs,
49+
match op {
50+
Op::Add => "+",
51+
Op::Subtract => "-",
52+
},
53+
rhs,
54+
),
55+
}
56+
}
57+
}
58+
1759
/// Generates and stores coverage counter and coverage expression information
1860
/// associated with nodes/edges in the BCB graph.
1961
pub(super) struct CoverageCounters {
@@ -22,18 +64,18 @@ pub(super) struct CoverageCounters {
2264
next_expression_id: ExpressionId,
2365

2466
/// Coverage counters/expressions that are associated with individual BCBs.
25-
bcb_counters: IndexVec<BasicCoverageBlock, Option<CoverageKind>>,
67+
bcb_counters: IndexVec<BasicCoverageBlock, Option<BcbCounter>>,
2668
/// Coverage counters/expressions that are associated with the control-flow
2769
/// edge between two BCBs.
28-
bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), CoverageKind>,
70+
bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>,
2971
/// Tracks which BCBs have a counter associated with some incoming edge.
3072
/// Only used by debug assertions, to verify that BCBs with incoming edge
3173
/// counters do not have their own physical counters (expressions are allowed).
3274
bcb_has_incoming_edge_counters: BitSet<BasicCoverageBlock>,
3375
/// Expression nodes that are not directly associated with any particular
3476
/// BCB/edge, but are needed as operands to more complex expressions.
35-
/// These are always `CoverageKind::Expression`.
36-
pub(super) intermediate_expressions: Vec<CoverageKind>,
77+
/// These are always [`BcbCounter::Expression`].
78+
pub(super) intermediate_expressions: Vec<BcbCounter>,
3779

3880
pub debug_counters: DebugCounters,
3981
}
@@ -57,12 +99,12 @@ impl CoverageCounters {
5799
}
58100

59101
/// Activate the `DebugCounters` data structures, to provide additional debug formatting
60-
/// features when formatting `CoverageKind` (counter) values.
102+
/// features when formatting [`BcbCounter`] (counter) values.
61103
pub fn enable_debug(&mut self) {
62104
self.debug_counters.enable();
63105
}
64106

65-
/// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
107+
/// Makes [`BcbCounter`] `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
66108
/// indirectly associated with `CoverageSpans`, and accumulates additional `Expression`s
67109
/// representing intermediate values.
68110
pub fn make_bcb_counters(
@@ -73,11 +115,11 @@ impl CoverageCounters {
73115
MakeBcbCounters::new(self, basic_coverage_blocks).make_bcb_counters(coverage_spans)
74116
}
75117

76-
fn make_counter<F>(&mut self, debug_block_label_fn: F) -> CoverageKind
118+
fn make_counter<F>(&mut self, debug_block_label_fn: F) -> BcbCounter
77119
where
78120
F: Fn() -> Option<String>,
79121
{
80-
let counter = CoverageKind::Counter {
122+
let counter = BcbCounter::Counter {
81123
function_source_hash: self.function_source_hash,
82124
id: self.next_counter(),
83125
};
@@ -93,19 +135,19 @@ impl CoverageCounters {
93135
op: Op,
94136
rhs: Operand,
95137
debug_block_label_fn: F,
96-
) -> CoverageKind
138+
) -> BcbCounter
97139
where
98140
F: Fn() -> Option<String>,
99141
{
100142
let id = self.next_expression();
101-
let expression = CoverageKind::Expression { id, lhs, op, rhs };
143+
let expression = BcbCounter::Expression { id, lhs, op, rhs };
102144
if self.debug_counters.is_enabled() {
103145
self.debug_counters.add_counter(&expression, (debug_block_label_fn)());
104146
}
105147
expression
106148
}
107149

108-
pub fn make_identity_counter(&mut self, counter_operand: Operand) -> CoverageKind {
150+
pub fn make_identity_counter(&mut self, counter_operand: Operand) -> BcbCounter {
109151
let some_debug_block_label = if self.debug_counters.is_enabled() {
110152
self.debug_counters.some_block_label(counter_operand).cloned()
111153
} else {
@@ -134,7 +176,7 @@ impl CoverageCounters {
134176
fn set_bcb_counter(
135177
&mut self,
136178
bcb: BasicCoverageBlock,
137-
counter_kind: CoverageKind,
179+
counter_kind: BcbCounter,
138180
) -> Result<Operand, Error> {
139181
debug_assert!(
140182
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
@@ -158,7 +200,7 @@ impl CoverageCounters {
158200
&mut self,
159201
from_bcb: BasicCoverageBlock,
160202
to_bcb: BasicCoverageBlock,
161-
counter_kind: CoverageKind,
203+
counter_kind: BcbCounter,
162204
) -> Result<Operand, Error> {
163205
if level_enabled!(tracing::Level::DEBUG) {
164206
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
@@ -183,25 +225,25 @@ impl CoverageCounters {
183225
}
184226
}
185227

186-
pub(super) fn bcb_counter(&self, bcb: BasicCoverageBlock) -> Option<&CoverageKind> {
228+
pub(super) fn bcb_counter(&self, bcb: BasicCoverageBlock) -> Option<&BcbCounter> {
187229
self.bcb_counters[bcb].as_ref()
188230
}
189231

190-
pub(super) fn take_bcb_counter(&mut self, bcb: BasicCoverageBlock) -> Option<CoverageKind> {
232+
pub(super) fn take_bcb_counter(&mut self, bcb: BasicCoverageBlock) -> Option<BcbCounter> {
191233
self.bcb_counters[bcb].take()
192234
}
193235

194236
pub(super) fn drain_bcb_counters(
195237
&mut self,
196-
) -> impl Iterator<Item = (BasicCoverageBlock, CoverageKind)> + '_ {
238+
) -> impl Iterator<Item = (BasicCoverageBlock, BcbCounter)> + '_ {
197239
self.bcb_counters
198240
.iter_enumerated_mut()
199241
.filter_map(|(bcb, counter)| Some((bcb, counter.take()?)))
200242
}
201243

202244
pub(super) fn drain_bcb_edge_counters(
203245
&mut self,
204-
) -> impl Iterator<Item = ((BasicCoverageBlock, BasicCoverageBlock), CoverageKind)> + '_ {
246+
) -> impl Iterator<Item = ((BasicCoverageBlock, BasicCoverageBlock), BcbCounter)> + '_ {
205247
self.bcb_edge_counters.drain()
206248
}
207249
}
@@ -653,7 +695,7 @@ impl<'a> MakeBcbCounters<'a> {
653695
self.branch_counter(branch).is_none()
654696
}
655697

656-
fn branch_counter(&self, branch: &BcbBranch) -> Option<&CoverageKind> {
698+
fn branch_counter(&self, branch: &BcbBranch) -> Option<&BcbCounter> {
657699
let to_bcb = branch.target_bcb;
658700
if let Some(from_bcb) = branch.edge_from_bcb {
659701
self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb))
@@ -675,7 +717,7 @@ impl<'a> MakeBcbCounters<'a> {
675717
}
676718

677719
#[inline]
678-
fn format_counter(&self, counter_kind: &CoverageKind) -> String {
720+
fn format_counter(&self, counter_kind: &BcbCounter) -> String {
679721
self.coverage_counters.debug_counters.format_counter(counter_kind)
680722
}
681723
}

0 commit comments

Comments
 (0)