Skip to content

Commit d29a59d

Browse files
committed
coverage: Store the instrumentor's expressions in a separate list
This will make it easier to store the entire expression list in `FunctionCoverageData`.
1 parent 3135471 commit d29a59d

File tree

4 files changed

+49
-37
lines changed

4 files changed

+49
-37
lines changed

compiler/rustc_middle/src/mir/coverage.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ impl Op {
135135
}
136136
}
137137

138+
#[derive(Clone, Debug)]
139+
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
140+
pub struct Expression {
141+
pub lhs: CovTerm,
142+
pub op: Op,
143+
pub rhs: CovTerm,
144+
}
145+
138146
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
139147
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
140148
pub struct Mapping {

compiler/rustc_mir_transform/src/coverage/counters.rs

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::fmt::{self, Debug};
2121
#[derive(Clone)]
2222
pub(super) enum BcbCounter {
2323
Counter { id: CounterId },
24-
Expression { id: ExpressionId, lhs: CovTerm, op: Op, rhs: CovTerm },
24+
Expression { id: ExpressionId },
2525
}
2626

2727
impl BcbCounter {
@@ -41,17 +41,7 @@ impl Debug for BcbCounter {
4141
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
4242
match self {
4343
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-
),
44+
Self::Expression { id } => write!(fmt, "Expression({:?}", id.index()),
5545
}
5646
}
5747
}
@@ -60,7 +50,6 @@ impl Debug for BcbCounter {
6050
/// associated with nodes/edges in the BCB graph.
6151
pub(super) struct CoverageCounters {
6252
next_counter_id: CounterId,
63-
next_expression_id: ExpressionId,
6453

6554
/// Coverage counters/expressions that are associated with individual BCBs.
6655
bcb_counters: IndexVec<BasicCoverageBlock, Option<BcbCounter>>,
@@ -75,6 +64,7 @@ pub(super) struct CoverageCounters {
7564
/// BCB/edge, but are needed as operands to more complex expressions.
7665
/// These are always [`BcbCounter::Expression`].
7766
pub(super) intermediate_expressions: Vec<BcbCounter>,
67+
pub(crate) expressions: IndexVec<ExpressionId, Expression>,
7868

7969
pub debug_counters: DebugCounters,
8070
}
@@ -85,12 +75,11 @@ impl CoverageCounters {
8575

8676
Self {
8777
next_counter_id: CounterId::START,
88-
next_expression_id: ExpressionId::START,
89-
9078
bcb_counters: IndexVec::from_elem_n(None, num_bcbs),
9179
bcb_edge_counters: FxHashMap::default(),
9280
bcb_has_incoming_edge_counters: BitSet::new_empty(num_bcbs),
9381
intermediate_expressions: Vec::new(),
82+
expressions: IndexVec::new(),
9483

9584
debug_counters: DebugCounters::new(),
9685
}
@@ -134,12 +123,12 @@ impl CoverageCounters {
134123
where
135124
F: Fn() -> Option<String>,
136125
{
137-
let id = self.next_expression();
138-
let expression = BcbCounter::Expression { id, lhs, op, rhs };
126+
let id = self.expressions.push(Expression { lhs, op, rhs });
139127
if self.debug_counters.is_enabled() {
140-
self.debug_counters.add_counter(&expression, (debug_block_label_fn)());
128+
let expression = self.expressions[id].clone();
129+
self.debug_counters.add_expression(id, expression, (debug_block_label_fn)());
141130
}
142-
expression
131+
BcbCounter::Expression { id }
143132
}
144133

145134
/// Counter IDs start from one and go up.
@@ -149,20 +138,12 @@ impl CoverageCounters {
149138
next
150139
}
151140

152-
/// Expression IDs start from 0 and go up.
153-
/// (Counter IDs and Expression IDs are distinguished by the `Operand` enum.)
154-
fn next_expression(&mut self) -> ExpressionId {
155-
let next = self.next_expression_id;
156-
self.next_expression_id = self.next_expression_id + 1;
157-
next
158-
}
159-
160141
pub(crate) fn num_counters(&self) -> usize {
161142
self.next_counter_id.as_usize()
162143
}
163144

164145
pub(crate) fn num_expressions(&self) -> usize {
165-
self.next_expression_id.as_usize()
146+
self.expressions.len()
166147
}
167148

168149
fn set_bcb_counter(

compiler/rustc_mir_transform/src/coverage/debug.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ use rustc_middle::mir::generic_graphviz::GraphvizWriter;
118118
use rustc_middle::mir::spanview::{self, SpanViewable};
119119

120120
use rustc_data_structures::fx::FxHashMap;
121+
use rustc_index::IndexVec;
121122
use rustc_middle::mir::coverage::*;
122123
use rustc_middle::mir::{self, BasicBlock};
123124
use rustc_middle::ty::TyCtxt;
@@ -259,12 +260,13 @@ impl Default for ExpressionFormat {
259260
/// `DebugCounters` supports a recursive rendering of `Expression` counters, so they can be
260261
/// presented as nested expressions such as `(bcb3 - (bcb0 + bcb1))`.
261262
pub(super) struct DebugCounters {
263+
expressions: IndexVec<ExpressionId, Expression>,
262264
some_counters: Option<FxHashMap<CovTerm, DebugCounter>>,
263265
}
264266

265267
impl DebugCounters {
266268
pub fn new() -> Self {
267-
Self { some_counters: None }
269+
Self { expressions: IndexVec::new(), some_counters: None }
268270
}
269271

270272
pub fn enable(&mut self) {
@@ -285,6 +287,17 @@ impl DebugCounters {
285287
}
286288
}
287289

290+
pub fn add_expression(
291+
&mut self,
292+
id: ExpressionId,
293+
expression: Expression,
294+
some_block_label: Option<String>,
295+
) {
296+
assert_eq!(id, self.expressions.next_index());
297+
self.expressions.push(expression);
298+
self.add_counter(&BcbCounter::Expression { id }, some_block_label);
299+
}
300+
288301
pub fn format_counter(&self, counter_kind: &BcbCounter) -> String {
289302
match *counter_kind {
290303
BcbCounter::Counter { .. } => {
@@ -298,8 +311,9 @@ impl DebugCounters {
298311

299312
fn format_counter_kind(&self, counter_kind: &BcbCounter) -> String {
300313
let counter_format = &debug_options().counter_format;
301-
if let BcbCounter::Expression { id, lhs, op, rhs } = *counter_kind {
314+
if let BcbCounter::Expression { id } = *counter_kind {
302315
if counter_format.operation {
316+
let Expression { lhs, op, rhs } = self.expressions[id];
303317
return format!(
304318
"{}{} {} {}",
305319
if counter_format.id || self.some_counters.is_none() {
@@ -500,9 +514,14 @@ impl UsedExpressions {
500514
self.some_used_expression_operands.is_some()
501515
}
502516

503-
pub fn add_expression_operands(&mut self, expression: &BcbCounter) {
517+
pub fn add_expression_operands(
518+
&mut self,
519+
expression: &BcbCounter,
520+
coverage_counters: &CoverageCounters,
521+
) {
504522
if let Some(used_expression_operands) = self.some_used_expression_operands.as_mut() {
505-
if let BcbCounter::Expression { id, lhs, rhs, .. } = *expression {
523+
if let BcbCounter::Expression { id } = *expression {
524+
let Expression { lhs, op: _, rhs } = coverage_counters.expressions[id];
506525
used_expression_operands.entry(lhs).or_insert_with(Vec::new).push(id);
507526
used_expression_operands.entry(rhs).or_insert_with(Vec::new).push(id);
508527
}
@@ -556,6 +575,7 @@ impl UsedExpressions {
556575
BasicCoverageBlock,
557576
BcbCounter,
558577
)],
578+
coverage_counters: &CoverageCounters,
559579
) {
560580
if self.is_enabled() {
561581
let mut not_validated = bcb_counters_without_direct_coverage_spans
@@ -568,7 +588,7 @@ impl UsedExpressions {
568588
validating_count = to_validate.len();
569589
for counter_kind in to_validate {
570590
if self.expression_is_used(counter_kind) {
571-
self.add_expression_operands(counter_kind);
591+
self.add_expression_operands(counter_kind, coverage_counters);
572592
} else {
573593
not_validated.push(counter_kind);
574594
}

compiler/rustc_mir_transform/src/coverage/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
213213
// BCB) to the `debug_used_expressions` map.
214214
if debug_used_expressions.is_enabled() {
215215
for intermediate_expression in &self.coverage_counters.intermediate_expressions {
216-
debug_used_expressions.add_expression_operands(intermediate_expression);
216+
debug_used_expressions
217+
.add_expression_operands(intermediate_expression, &self.coverage_counters);
217218
}
218219
}
219220

@@ -311,7 +312,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
311312
let counter_kind = self.coverage_counters.take_bcb_counter(bcb).unwrap_or_else(|| {
312313
bug!("Every BasicCoverageBlock should have a Counter or Expression");
313314
});
314-
debug_used_expressions.add_expression_operands(&counter_kind);
315+
debug_used_expressions.add_expression_operands(&counter_kind, &self.coverage_counters);
315316
graphviz_data.add_bcb_coverage_spans_with_counter(bcb, bcb_spans, &counter_kind);
316317

317318
let term = counter_kind.as_term();
@@ -359,7 +360,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
359360
// If debug is enabled, validate that every BCB or edge counter not directly associated
360361
// with a coverage span is at least indirectly associated (it is a dependency of a BCB
361362
// counter that _is_ associated with a coverage span).
362-
debug_used_expressions.validate(&bcb_counters_without_direct_coverage_spans);
363+
debug_used_expressions
364+
.validate(&bcb_counters_without_direct_coverage_spans, &self.coverage_counters);
363365

364366
for (edge_from_bcb, target_bcb, counter_kind) in bcb_counters_without_direct_coverage_spans
365367
{
@@ -440,7 +442,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
440442
fn make_mir_coverage_kind(&self, counter_kind: &BcbCounter) -> CoverageKind {
441443
match *counter_kind {
442444
BcbCounter::Counter { id } => CoverageKind::Counter { id },
443-
BcbCounter::Expression { id, lhs, op, rhs } => {
445+
BcbCounter::Expression { id } => {
446+
let Expression { lhs, op, rhs } = self.coverage_counters.expressions[id];
444447
CoverageKind::Expression { id, lhs, op, rhs }
445448
}
446449
}

0 commit comments

Comments
 (0)