Skip to content

Commit 1a014d4

Browse files
committed
Replace ExpressionOperandId with enum Operand
Because the three kinds of operand are now distinguished explicitly, we no longer need fiddly code to disambiguate counter IDs and expression IDs based on the total number of counters/expressions in a function. This does increase the size of operands from 4 bytes to 8 bytes, but that shouldn't be a big deal since they are mostly stored inside boxed structures, and the current coverage code is not particularly size-optimized anyway.
1 parent 5a808d4 commit 1a014d4

File tree

11 files changed

+96
-147
lines changed

11 files changed

+96
-147
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs

+19-24
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ pub use super::ffi::*;
33
use rustc_index::{IndexSlice, IndexVec};
44
use rustc_middle::bug;
55
use rustc_middle::mir::coverage::{
6-
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId,
7-
InjectedExpressionIndex, MappedExpressionIndex, Op,
6+
CodeRegion, CounterValueReference, InjectedExpressionId, InjectedExpressionIndex,
7+
MappedExpressionIndex, Op, Operand,
88
};
99
use rustc_middle::ty::Instance;
1010
use rustc_middle::ty::TyCtxt;
1111

1212
#[derive(Clone, Debug, PartialEq)]
1313
pub struct Expression {
14-
lhs: ExpressionOperandId,
14+
lhs: Operand,
1515
op: Op,
16-
rhs: ExpressionOperandId,
16+
rhs: Operand,
1717
region: Option<CodeRegion>,
1818
}
1919

@@ -105,16 +105,16 @@ impl<'tcx> FunctionCoverage<'tcx> {
105105
pub fn add_counter_expression(
106106
&mut self,
107107
expression_id: InjectedExpressionId,
108-
lhs: ExpressionOperandId,
108+
lhs: Operand,
109109
op: Op,
110-
rhs: ExpressionOperandId,
110+
rhs: Operand,
111111
region: Option<CodeRegion>,
112112
) {
113113
debug!(
114114
"add_counter_expression({:?}, lhs={:?}, op={:?}, rhs={:?} at {:?}",
115115
expression_id, lhs, op, rhs, region
116116
);
117-
let expression_index = self.expression_index(u32::from(expression_id));
117+
let expression_index = self.expression_index(expression_id);
118118
debug_assert!(
119119
expression_index.as_usize() < self.expressions.len(),
120120
"expression_index {} is out of range for expressions.len() = {}
@@ -186,10 +186,7 @@ impl<'tcx> FunctionCoverage<'tcx> {
186186

187187
// This closure converts any `Expression` operand (`lhs` or `rhs` of the `Op::Add` or
188188
// `Op::Subtract` operation) into its native `llvm::coverage::Counter::CounterKind` type
189-
// and value. Operand ID value `0` maps to `CounterKind::Zero`; values in the known range
190-
// of injected LLVM counters map to `CounterKind::CounterValueReference` (and the value
191-
// matches the injected counter index); and any other value is converted into a
192-
// `CounterKind::Expression` with the expression's `new_index`.
189+
// and value.
193190
//
194191
// Expressions will be returned from this function in a sequential vector (array) of
195192
// `CounterExpression`, so the expression IDs must be mapped from their original,
@@ -206,26 +203,23 @@ impl<'tcx> FunctionCoverage<'tcx> {
206203
// `expression_index`s lower than the referencing `Expression`. Therefore, it is
207204
// reasonable to look up the new index of an expression operand while the `new_indexes`
208205
// vector is only complete up to the current `ExpressionIndex`.
209-
let id_to_counter = |new_indexes: &IndexSlice<
210-
InjectedExpressionIndex,
211-
Option<MappedExpressionIndex>,
212-
>,
213-
id: ExpressionOperandId| {
214-
if id == ExpressionOperandId::ZERO {
215-
Some(Counter::zero())
216-
} else if id.index() < self.counters.len() {
206+
type NewIndexes = IndexSlice<InjectedExpressionIndex, Option<MappedExpressionIndex>>;
207+
let id_to_counter = |new_indexes: &NewIndexes, operand: Operand| match operand {
208+
Operand::Zero => Some(Counter::zero()),
209+
Operand::Counter(id) => {
217210
debug_assert!(
218211
id.index() > 0,
219-
"ExpressionOperandId indexes for counters are 1-based, but this id={}",
212+
"Operand::Counter indexes for counters are 1-based, but this id={}",
220213
id.index()
221214
);
222215
// Note: Some codegen-injected Counters may be only referenced by `Expression`s,
223216
// and may not have their own `CodeRegion`s,
224217
let index = CounterValueReference::from(id.index());
225218
// Note, the conversion to LLVM `Counter` adjusts the index to be zero-based.
226219
Some(Counter::counter_value_reference(index))
227-
} else {
228-
let index = self.expression_index(u32::from(id));
220+
}
221+
Operand::Expression(id) => {
222+
let index = self.expression_index(id);
229223
self.expressions
230224
.get(index)
231225
.expect("expression id is out of range")
@@ -341,8 +335,9 @@ impl<'tcx> FunctionCoverage<'tcx> {
341335
self.unreachable_regions.iter().map(|region| (Counter::zero(), region))
342336
}
343337

344-
fn expression_index(&self, id_descending_from_max: u32) -> InjectedExpressionIndex {
345-
debug_assert!(id_descending_from_max >= self.counters.len() as u32);
338+
fn expression_index(&self, id: InjectedExpressionId) -> InjectedExpressionIndex {
339+
debug_assert!(id.as_usize() >= self.counters.len());
340+
let id_descending_from_max = id.as_u32();
346341
InjectedExpressionIndex::from(u32::MAX - id_descending_from_max)
347342
}
348343
}

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_hir::def_id::DefId;
1717
use rustc_llvm::RustString;
1818
use rustc_middle::bug;
1919
use rustc_middle::mir::coverage::{
20-
CodeRegion, CounterValueReference, CoverageKind, ExpressionOperandId, InjectedExpressionId, Op,
20+
CodeRegion, CounterValueReference, CoverageKind, InjectedExpressionId, Op, Operand,
2121
};
2222
use rustc_middle::mir::Coverage;
2323
use rustc_middle::ty;
@@ -203,9 +203,9 @@ impl<'tcx> Builder<'_, '_, 'tcx> {
203203
&mut self,
204204
instance: Instance<'tcx>,
205205
id: InjectedExpressionId,
206-
lhs: ExpressionOperandId,
206+
lhs: Operand,
207207
op: Op,
208-
rhs: ExpressionOperandId,
208+
rhs: Operand,
209209
region: Option<CodeRegion>,
210210
) -> bool {
211211
if let Some(coverage_context) = self.coverage_context() {

compiler/rustc_middle/src/mir/coverage.rs

+26-48
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,6 @@ use rustc_span::Symbol;
55

66
use std::fmt::{self, Debug, Formatter};
77

8-
rustc_index::newtype_index! {
9-
/// An ExpressionOperandId value is assigned directly from either a
10-
/// CounterValueReference.as_u32() (which ascend from 1) or an ExpressionOperandId.as_u32()
11-
/// (which _*descend*_ from u32::MAX). Id value `0` (zero) represents a virtual counter with a
12-
/// constant value of `0`.
13-
#[derive(HashStable)]
14-
#[max = 0xFFFF_FFFF]
15-
#[debug_format = "ExpressionOperandId({})"]
16-
pub struct ExpressionOperandId {
17-
}
18-
}
19-
20-
impl ExpressionOperandId {
21-
/// An expression operand for a "zero counter", as described in the following references:
22-
///
23-
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter>
24-
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#tag>
25-
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter-expressions>
26-
///
27-
/// This operand can be used to count two or more separate code regions with a single counter,
28-
/// if they run sequentially with no branches, by injecting the `Counter` in a `BasicBlock` for
29-
/// one of the code regions, and inserting `CounterExpression`s ("add ZERO to the counter") in
30-
/// the coverage map for the other code regions.
31-
pub const ZERO: Self = Self::from_u32(0);
32-
}
33-
348
rustc_index::newtype_index! {
359
#[derive(HashStable)]
3610
#[max = 0xFFFF_FFFF]
@@ -39,7 +13,7 @@ rustc_index::newtype_index! {
3913
}
4014

4115
impl CounterValueReference {
42-
/// Counters start at 1 to reserve 0 for ExpressionOperandId::ZERO.
16+
/// Counters start at 1 for historical reasons.
4317
pub const START: Self = Self::from_u32(1);
4418

4519
/// Returns explicitly-requested zero-based version of the counter id, used
@@ -52,8 +26,6 @@ impl CounterValueReference {
5226
}
5327

5428
rustc_index::newtype_index! {
55-
/// InjectedExpressionId.as_u32() converts to ExpressionOperandId.as_u32()
56-
///
5729
/// Values descend from u32::MAX.
5830
#[derive(HashStable)]
5931
#[max = 0xFFFF_FFFF]
@@ -62,8 +34,6 @@ rustc_index::newtype_index! {
6234
}
6335

6436
rustc_index::newtype_index! {
65-
/// InjectedExpressionIndex.as_u32() translates to u32::MAX - ExpressionOperandId.as_u32()
66-
///
6737
/// Values ascend from 0.
6838
#[derive(HashStable)]
6939
#[max = 0xFFFF_FFFF]
@@ -81,17 +51,25 @@ rustc_index::newtype_index! {
8151
pub struct MappedExpressionIndex {}
8252
}
8353

84-
impl From<CounterValueReference> for ExpressionOperandId {
85-
#[inline]
86-
fn from(v: CounterValueReference) -> ExpressionOperandId {
87-
ExpressionOperandId::from(v.as_u32())
88-
}
54+
/// Operand of a coverage-counter expression.
55+
///
56+
/// Operands can be a constant zero value, an actual coverage counter, or another
57+
/// expression. Counter/expression operands are referred to by ID.
58+
#[derive(Copy, Clone, PartialEq, Eq)]
59+
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
60+
pub enum Operand {
61+
Zero,
62+
Counter(CounterValueReference),
63+
Expression(InjectedExpressionId),
8964
}
9065

91-
impl From<InjectedExpressionId> for ExpressionOperandId {
92-
#[inline]
93-
fn from(v: InjectedExpressionId) -> ExpressionOperandId {
94-
ExpressionOperandId::from(v.as_u32())
66+
impl Debug for Operand {
67+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
68+
match self {
69+
Self::Zero => write!(f, "Zero"),
70+
Self::Counter(id) => f.debug_tuple("Counter").field(&id.as_u32()).finish(),
71+
Self::Expression(id) => f.debug_tuple("Expression").field(&id.as_u32()).finish(),
72+
}
9573
}
9674
}
9775

@@ -107,19 +85,19 @@ pub enum CoverageKind {
10785
/// ID of this coverage-counter expression within its enclosing function.
10886
/// Other expressions in the same function can refer to it as an operand.
10987
id: InjectedExpressionId,
110-
lhs: ExpressionOperandId,
88+
lhs: Operand,
11189
op: Op,
112-
rhs: ExpressionOperandId,
90+
rhs: Operand,
11391
},
11492
Unreachable,
11593
}
11694

11795
impl CoverageKind {
118-
pub fn as_operand_id(&self) -> ExpressionOperandId {
96+
pub fn as_operand(&self) -> Operand {
11997
use CoverageKind::*;
12098
match *self {
121-
Counter { id, .. } => ExpressionOperandId::from(id),
122-
Expression { id, .. } => ExpressionOperandId::from(id),
99+
Counter { id, .. } => Operand::Counter(id),
100+
Expression { id, .. } => Operand::Expression(id),
123101
Unreachable => bug!("Unreachable coverage cannot be part of an expression"),
124102
}
125103
}
@@ -136,14 +114,14 @@ impl Debug for CoverageKind {
136114
Counter { id, .. } => write!(fmt, "Counter({:?})", id.index()),
137115
Expression { id, lhs, op, rhs } => write!(
138116
fmt,
139-
"Expression({:?}) = {} {} {}",
117+
"Expression({:?}) = {:?} {} {:?}",
140118
id.index(),
141-
lhs.index(),
119+
lhs,
142120
match op {
143121
Op::Add => "+",
144122
Op::Subtract => "-",
145123
},
146-
rhs.index(),
124+
rhs,
147125
),
148126
Unreachable => write!(fmt, "Unreachable"),
149127
}

compiler/rustc_middle/src/ty/structural_impls.rs

-1
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,6 @@ TrivialTypeTraversalAndLiftImpls! {
470470
::rustc_hir::Unsafety,
471471
::rustc_target::asm::InlineAsmRegOrRegClass,
472472
::rustc_target::spec::abi::Abi,
473-
crate::mir::coverage::ExpressionOperandId,
474473
crate::mir::coverage::CounterValueReference,
475474
crate::mir::coverage::InjectedExpressionId,
476475
crate::mir::coverage::InjectedExpressionIndex,

compiler/rustc_mir_transform/src/coverage/counters.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ impl CoverageCounters {
6565

6666
fn make_expression<F>(
6767
&mut self,
68-
lhs: ExpressionOperandId,
68+
lhs: Operand,
6969
op: Op,
70-
rhs: ExpressionOperandId,
70+
rhs: Operand,
7171
debug_block_label_fn: F,
7272
) -> CoverageKind
7373
where
@@ -81,13 +81,13 @@ impl CoverageCounters {
8181
expression
8282
}
8383

84-
pub fn make_identity_counter(&mut self, counter_operand: ExpressionOperandId) -> CoverageKind {
84+
pub fn make_identity_counter(&mut self, counter_operand: Operand) -> CoverageKind {
8585
let some_debug_block_label = if self.debug_counters.is_enabled() {
8686
self.debug_counters.some_block_label(counter_operand).cloned()
8787
} else {
8888
None
8989
};
90-
self.make_expression(counter_operand, Op::Add, ExpressionOperandId::ZERO, || {
90+
self.make_expression(counter_operand, Op::Add, Operand::Zero, || {
9191
some_debug_block_label.clone()
9292
})
9393
}
@@ -199,7 +199,7 @@ impl<'a> BcbCounters<'a> {
199199
&mut self,
200200
traversal: &mut TraverseCoverageGraphWithLoops,
201201
branching_bcb: BasicCoverageBlock,
202-
branching_counter_operand: ExpressionOperandId,
202+
branching_counter_operand: Operand,
203203
collect_intermediate_expressions: &mut Vec<CoverageKind>,
204204
) -> Result<(), Error> {
205205
let branches = self.bcb_branches(branching_bcb);
@@ -261,7 +261,7 @@ impl<'a> BcbCounters<'a> {
261261
" [new intermediate expression: {}]",
262262
self.format_counter(&intermediate_expression)
263263
);
264-
let intermediate_expression_operand = intermediate_expression.as_operand_id();
264+
let intermediate_expression_operand = intermediate_expression.as_operand();
265265
collect_intermediate_expressions.push(intermediate_expression);
266266
some_sumup_counter_operand.replace(intermediate_expression_operand);
267267
}
@@ -298,7 +298,7 @@ impl<'a> BcbCounters<'a> {
298298
&mut self,
299299
bcb: BasicCoverageBlock,
300300
collect_intermediate_expressions: &mut Vec<CoverageKind>,
301-
) -> Result<ExpressionOperandId, Error> {
301+
) -> Result<Operand, Error> {
302302
self.recursive_get_or_make_counter_operand(bcb, collect_intermediate_expressions, 1)
303303
}
304304

@@ -307,7 +307,7 @@ impl<'a> BcbCounters<'a> {
307307
bcb: BasicCoverageBlock,
308308
collect_intermediate_expressions: &mut Vec<CoverageKind>,
309309
debug_indent_level: usize,
310-
) -> Result<ExpressionOperandId, Error> {
310+
) -> Result<Operand, Error> {
311311
// If the BCB already has a counter, return it.
312312
if let Some(counter_kind) = self.basic_coverage_blocks[bcb].counter() {
313313
debug!(
@@ -316,7 +316,7 @@ impl<'a> BcbCounters<'a> {
316316
bcb,
317317
self.format_counter(counter_kind),
318318
);
319-
return Ok(counter_kind.as_operand_id());
319+
return Ok(counter_kind.as_operand());
320320
}
321321

322322
// A BCB with only one incoming edge gets a simple `Counter` (via `make_counter()`).
@@ -383,7 +383,7 @@ impl<'a> BcbCounters<'a> {
383383
NESTED_INDENT.repeat(debug_indent_level),
384384
self.format_counter(&intermediate_expression)
385385
);
386-
let intermediate_expression_operand = intermediate_expression.as_operand_id();
386+
let intermediate_expression_operand = intermediate_expression.as_operand();
387387
collect_intermediate_expressions.push(intermediate_expression);
388388
some_sumup_edge_counter_operand.replace(intermediate_expression_operand);
389389
}
@@ -408,7 +408,7 @@ impl<'a> BcbCounters<'a> {
408408
from_bcb: BasicCoverageBlock,
409409
to_bcb: BasicCoverageBlock,
410410
collect_intermediate_expressions: &mut Vec<CoverageKind>,
411-
) -> Result<ExpressionOperandId, Error> {
411+
) -> Result<Operand, Error> {
412412
self.recursive_get_or_make_edge_counter_operand(
413413
from_bcb,
414414
to_bcb,
@@ -423,7 +423,7 @@ impl<'a> BcbCounters<'a> {
423423
to_bcb: BasicCoverageBlock,
424424
collect_intermediate_expressions: &mut Vec<CoverageKind>,
425425
debug_indent_level: usize,
426-
) -> Result<ExpressionOperandId, Error> {
426+
) -> Result<Operand, Error> {
427427
// If the source BCB has only one successor (assumed to be the given target), an edge
428428
// counter is unnecessary. Just get or make a counter for the source BCB.
429429
let successors = self.bcb_successors(from_bcb).iter();
@@ -444,7 +444,7 @@ impl<'a> BcbCounters<'a> {
444444
to_bcb,
445445
self.format_counter(counter_kind)
446446
);
447-
return Ok(counter_kind.as_operand_id());
447+
return Ok(counter_kind.as_operand());
448448
}
449449

450450
// Make a new counter to count this edge.

0 commit comments

Comments
 (0)