summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/mir/coverage.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/mir/coverage.rs')
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs129
1 files changed, 50 insertions, 79 deletions
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index db24dae11..1efb54bdb 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -6,69 +6,43 @@ use rustc_span::Symbol;
use std::fmt::{self, Debug, Formatter};
rustc_index::newtype_index! {
- /// An ExpressionOperandId value is assigned directly from either a
- /// CounterValueReference.as_u32() (which ascend from 1) or an ExpressionOperandId.as_u32()
- /// (which _*descend*_ from u32::MAX). Id value `0` (zero) represents a virtual counter with a
- /// constant value of `0`.
- #[derive(HashStable)]
- #[max = 0xFFFF_FFFF]
- #[debug_format = "ExpressionOperandId({})"]
- pub struct ExpressionOperandId {
- }
-}
-
-impl ExpressionOperandId {
- /// An expression operand for a "zero counter", as described in the following references:
- ///
- /// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter>
- /// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#tag>
- /// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter-expressions>
+ /// ID of a coverage counter. Values ascend from 0.
///
- /// This operand can be used to count two or more separate code regions with a single counter,
- /// if they run sequentially with no branches, by injecting the `Counter` in a `BasicBlock` for
- /// one of the code regions, and inserting `CounterExpression`s ("add ZERO to the counter") in
- /// the coverage map for the other code regions.
- pub const ZERO: Self = Self::from_u32(0);
-}
-
-rustc_index::newtype_index! {
+ /// Note that LLVM handles counter IDs as `uint32_t`, so there is no need
+ /// to use a larger representation on the Rust side.
#[derive(HashStable)]
#[max = 0xFFFF_FFFF]
- #[debug_format = "CounterValueReference({})"]
- pub struct CounterValueReference {}
+ #[debug_format = "CounterId({})"]
+ pub struct CounterId {}
}
-impl CounterValueReference {
- /// Counters start at 1 to reserve 0 for ExpressionOperandId::ZERO.
- pub const START: Self = Self::from_u32(1);
+impl CounterId {
+ pub const START: Self = Self::from_u32(0);
- /// Returns explicitly-requested zero-based version of the counter id, used
- /// during codegen. LLVM expects zero-based indexes.
- pub fn zero_based_index(self) -> u32 {
- let one_based_index = self.as_u32();
- debug_assert!(one_based_index > 0);
- one_based_index - 1
+ #[inline(always)]
+ pub fn next_id(self) -> Self {
+ Self::from_u32(self.as_u32() + 1)
}
}
rustc_index::newtype_index! {
- /// InjectedExpressionId.as_u32() converts to ExpressionOperandId.as_u32()
+ /// ID of a coverage-counter expression. Values ascend from 0.
///
- /// Values descend from u32::MAX.
+ /// Note that LLVM handles expression IDs as `uint32_t`, so there is no need
+ /// to use a larger representation on the Rust side.
#[derive(HashStable)]
#[max = 0xFFFF_FFFF]
- #[debug_format = "InjectedExpressionId({})"]
- pub struct InjectedExpressionId {}
+ #[debug_format = "ExpressionId({})"]
+ pub struct ExpressionId {}
}
-rustc_index::newtype_index! {
- /// InjectedExpressionIndex.as_u32() translates to u32::MAX - ExpressionOperandId.as_u32()
- ///
- /// Values ascend from 0.
- #[derive(HashStable)]
- #[max = 0xFFFF_FFFF]
- #[debug_format = "InjectedExpressionIndex({})"]
- pub struct InjectedExpressionIndex {}
+impl ExpressionId {
+ pub const START: Self = Self::from_u32(0);
+
+ #[inline(always)]
+ pub fn next_id(self) -> Self {
+ Self::from_u32(self.as_u32() + 1)
+ }
}
rustc_index::newtype_index! {
@@ -81,17 +55,25 @@ rustc_index::newtype_index! {
pub struct MappedExpressionIndex {}
}
-impl From<CounterValueReference> for ExpressionOperandId {
- #[inline]
- fn from(v: CounterValueReference) -> ExpressionOperandId {
- ExpressionOperandId::from(v.as_u32())
- }
+/// Operand of a coverage-counter expression.
+///
+/// Operands can be a constant zero value, an actual coverage counter, or another
+/// expression. Counter/expression operands are referred to by ID.
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
+pub enum Operand {
+ Zero,
+ Counter(CounterId),
+ Expression(ExpressionId),
}
-impl From<InjectedExpressionId> for ExpressionOperandId {
- #[inline]
- fn from(v: InjectedExpressionId) -> ExpressionOperandId {
- ExpressionOperandId::from(v.as_u32())
+impl Debug for Operand {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::Zero => write!(f, "Zero"),
+ Self::Counter(id) => f.debug_tuple("Counter").field(&id.as_u32()).finish(),
+ Self::Expression(id) => f.debug_tuple("Expression").field(&id.as_u32()).finish(),
+ }
}
}
@@ -99,32 +81,21 @@ impl From<InjectedExpressionId> for ExpressionOperandId {
pub enum CoverageKind {
Counter {
function_source_hash: u64,
- id: CounterValueReference,
+ /// ID of this counter within its enclosing function.
+ /// Expressions in the same function can refer to it as an operand.
+ id: CounterId,
},
Expression {
- id: InjectedExpressionId,
- lhs: ExpressionOperandId,
+ /// ID of this coverage-counter expression within its enclosing function.
+ /// Other expressions in the same function can refer to it as an operand.
+ id: ExpressionId,
+ lhs: Operand,
op: Op,
- rhs: ExpressionOperandId,
+ rhs: Operand,
},
Unreachable,
}
-impl CoverageKind {
- pub fn as_operand_id(&self) -> ExpressionOperandId {
- use CoverageKind::*;
- match *self {
- Counter { id, .. } => ExpressionOperandId::from(id),
- Expression { id, .. } => ExpressionOperandId::from(id),
- Unreachable => bug!("Unreachable coverage cannot be part of an expression"),
- }
- }
-
- pub fn is_expression(&self) -> bool {
- matches!(self, Self::Expression { .. })
- }
-}
-
impl Debug for CoverageKind {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
use CoverageKind::*;
@@ -132,14 +103,14 @@ impl Debug for CoverageKind {
Counter { id, .. } => write!(fmt, "Counter({:?})", id.index()),
Expression { id, lhs, op, rhs } => write!(
fmt,
- "Expression({:?}) = {} {} {}",
+ "Expression({:?}) = {:?} {} {:?}",
id.index(),
- lhs.index(),
+ lhs,
match op {
Op::Add => "+",
Op::Subtract => "-",
},
- rhs.index(),
+ rhs,
),
Unreachable => write!(fmt, "Unreachable"),
}