]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/mir/coverage.rs
New upstream version 1.59.0+dfsg1
[rustc.git] / compiler / rustc_middle / src / mir / coverage.rs
CommitLineData
29967ef6
XL
1//! Metadata from source code coverage analysis and instrumentation.
2
3use rustc_macros::HashStable;
4use rustc_span::Symbol;
5
6use std::cmp::Ord;
7use std::fmt::{self, Debug, Formatter};
8
9rustc_index::newtype_index! {
10 /// An ExpressionOperandId value is assigned directly from either a
11 /// CounterValueReference.as_u32() (which ascend from 1) or an ExpressionOperandId.as_u32()
12 /// (which _*descend*_ from u32::MAX). Id value `0` (zero) represents a virtual counter with a
13 /// constant value of `0`.
14 pub struct ExpressionOperandId {
15 derive [HashStable]
16 DEBUG_FORMAT = "ExpressionOperandId({})",
17 MAX = 0xFFFF_FFFF,
18 }
19}
20
21impl ExpressionOperandId {
22 /// An expression operand for a "zero counter", as described in the following references:
23 ///
a2a8927a
XL
24 /// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter>
25 /// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#tag>
26 /// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter-expressions>
29967ef6
XL
27 ///
28 /// This operand can be used to count two or more separate code regions with a single counter,
29 /// if they run sequentially with no branches, by injecting the `Counter` in a `BasicBlock` for
30 /// one of the code regions, and inserting `CounterExpression`s ("add ZERO to the counter") in
31 /// the coverage map for the other code regions.
32 pub const ZERO: Self = Self::from_u32(0);
33}
34
35rustc_index::newtype_index! {
36 pub struct CounterValueReference {
37 derive [HashStable]
38 DEBUG_FORMAT = "CounterValueReference({})",
39 MAX = 0xFFFF_FFFF,
40 }
41}
42
43impl CounterValueReference {
cdc7bbd5 44 /// Counters start at 1 to reserve 0 for ExpressionOperandId::ZERO.
29967ef6 45 pub const START: Self = Self::from_u32(1);
cdc7bbd5
XL
46
47 /// Returns explicitly-requested zero-based version of the counter id, used
48 /// during codegen. LLVM expects zero-based indexes.
49 pub fn zero_based_index(&self) -> u32 {
50 let one_based_index = self.as_u32();
51 debug_assert!(one_based_index > 0);
52 one_based_index - 1
53 }
29967ef6
XL
54}
55
56rustc_index::newtype_index! {
57 /// InjectedExpressionId.as_u32() converts to ExpressionOperandId.as_u32()
58 ///
59 /// Values descend from u32::MAX.
60 pub struct InjectedExpressionId {
61 derive [HashStable]
62 DEBUG_FORMAT = "InjectedExpressionId({})",
63 MAX = 0xFFFF_FFFF,
64 }
65}
66
67rustc_index::newtype_index! {
68 /// InjectedExpressionIndex.as_u32() translates to u32::MAX - ExpressionOperandId.as_u32()
69 ///
70 /// Values ascend from 0.
71 pub struct InjectedExpressionIndex {
72 derive [HashStable]
73 DEBUG_FORMAT = "InjectedExpressionIndex({})",
74 MAX = 0xFFFF_FFFF,
75 }
76}
77
78rustc_index::newtype_index! {
79 /// MappedExpressionIndex values ascend from zero, and are recalculated indexes based on their
80 /// array position in the LLVM coverage map "Expressions" array, which is assembled during the
81 /// "mapgen" process. They cannot be computed algorithmically, from the other `newtype_index`s.
82 pub struct MappedExpressionIndex {
83 derive [HashStable]
84 DEBUG_FORMAT = "MappedExpressionIndex({})",
85 MAX = 0xFFFF_FFFF,
86 }
87}
88
89impl From<CounterValueReference> for ExpressionOperandId {
90 #[inline]
91 fn from(v: CounterValueReference) -> ExpressionOperandId {
92 ExpressionOperandId::from(v.as_u32())
93 }
94}
95
96impl From<InjectedExpressionId> for ExpressionOperandId {
97 #[inline]
98 fn from(v: InjectedExpressionId) -> ExpressionOperandId {
99 ExpressionOperandId::from(v.as_u32())
100 }
101}
102
6a06907d 103#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
29967ef6
XL
104pub enum CoverageKind {
105 Counter {
106 function_source_hash: u64,
107 id: CounterValueReference,
108 },
109 Expression {
110 id: InjectedExpressionId,
111 lhs: ExpressionOperandId,
112 op: Op,
113 rhs: ExpressionOperandId,
114 },
115 Unreachable,
116}
117
118impl CoverageKind {
119 pub fn as_operand_id(&self) -> ExpressionOperandId {
120 use CoverageKind::*;
121 match *self {
122 Counter { id, .. } => ExpressionOperandId::from(id),
123 Expression { id, .. } => ExpressionOperandId::from(id),
124 Unreachable => bug!("Unreachable coverage cannot be part of an expression"),
125 }
126 }
127
29967ef6 128 pub fn is_expression(&self) -> bool {
5869c6ff 129 matches!(self, Self::Expression { .. })
29967ef6 130 }
29967ef6
XL
131}
132
133impl Debug for CoverageKind {
134 fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
135 use CoverageKind::*;
136 match self {
137 Counter { id, .. } => write!(fmt, "Counter({:?})", id.index()),
138 Expression { id, lhs, op, rhs } => write!(
139 fmt,
140 "Expression({:?}) = {} {} {}",
141 id.index(),
142 lhs.index(),
143 if *op == Op::Add { "+" } else { "-" },
144 rhs.index(),
145 ),
146 Unreachable => write!(fmt, "Unreachable"),
147 }
148 }
149}
150
6a06907d
XL
151#[derive(
152 Clone,
153 TyEncodable,
154 TyDecodable,
155 Hash,
156 HashStable,
157 TypeFoldable,
158 PartialEq,
159 Eq,
160 PartialOrd,
161 Ord
162)]
29967ef6
XL
163pub struct CodeRegion {
164 pub file_name: Symbol,
165 pub start_line: u32,
166 pub start_col: u32,
167 pub end_line: u32,
168 pub end_col: u32,
169}
170
171impl Debug for CodeRegion {
172 fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
173 write!(
174 fmt,
175 "{}:{}:{} - {}:{}",
176 self.file_name, self.start_line, self.start_col, self.end_line, self.end_col
177 )
178 }
179}
180
6a06907d 181#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
29967ef6
XL
182pub enum Op {
183 Subtract,
184 Add,
185}
cdc7bbd5
XL
186
187impl Op {
188 pub fn is_add(&self) -> bool {
189 matches!(self, Self::Add)
190 }
191
192 pub fn is_subtract(&self) -> bool {
193 matches!(self, Self::Subtract)
194 }
195}