1 use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
3 /// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L95)
4 #[derive(Copy, Clone, Debug)]
8 CounterValueReference = 1,
12 /// A reference to an instance of an abstract "counter" that will yield a value in a coverage
13 /// report. Note that `id` has different interpretations, depending on the `kind`:
14 /// * For `CounterKind::Zero`, `id` is assumed to be `0`
15 /// * For `CounterKind::CounterValueReference`, `id` matches the `counter_id` of the injected
16 /// instrumentation counter (the `index` argument to the LLVM intrinsic
17 /// `instrprof.increment()`)
18 /// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of
19 /// counter expressions.
20 /// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L102-L103)
21 /// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
22 #[derive(Copy, Clone, Debug)]
25 // Important: The layout (order and types of fields) must match its C++ counterpart.
26 pub kind: CounterKind,
31 /// Constructs a new `Counter` of kind `Zero`. For this `CounterKind`, the
33 pub fn zero() -> Self {
34 Self { kind: CounterKind::Zero, id: 0 }
37 /// Constructs a new `Counter` of kind `CounterValueReference`, and converts
38 /// the given 1-based counter_id to the required 0-based equivalent for
39 /// the `Counter` encoding.
40 pub fn counter_value_reference(counter_id: CounterValueReference) -> Self {
41 Self { kind: CounterKind::CounterValueReference, id: counter_id.zero_based_index() }
44 /// Constructs a new `Counter` of kind `Expression`.
45 pub fn expression(mapped_expression_index: MappedExpressionIndex) -> Self {
46 Self { kind: CounterKind::Expression, id: mapped_expression_index.into() }
49 /// Returns true if the `Counter` kind is `Zero`.
50 pub fn is_zero(&self) -> bool {
51 matches!(self.kind, CounterKind::Zero)
54 /// An explicitly-named function to get the ID value, making it more obvious
55 /// that the stored value is now 0-based.
56 pub fn zero_based_id(&self) -> u32 {
57 debug_assert!(!self.is_zero(), "`id` is undefined for CounterKind::Zero");
62 /// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L150)
63 #[derive(Copy, Clone, Debug)]
70 /// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L152)
71 /// Important: The Rust struct layout (order and types of fields) must match its C++
73 #[derive(Copy, Clone, Debug)]
75 pub struct CounterExpression {
81 impl CounterExpression {
82 pub fn new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self {
83 Self { kind, lhs, rhs }