]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
Merge commit '4f3ab69ea0a0908260944443c739426cc384ae1a' into clippyup
[rust.git] / compiler / rustc_codegen_ssa / src / coverageinfo / ffi.rs
1 use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
2
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)]
5 #[repr(C)]
6 pub enum CounterKind {
7     Zero = 0,
8     CounterValueReference = 1,
9     Expression = 2,
10 }
11
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)]
23 #[repr(C)]
24 pub struct Counter {
25     // Important: The layout (order and types of fields) must match its C++ counterpart.
26     pub kind: CounterKind,
27     id: u32,
28 }
29
30 impl Counter {
31     /// Constructs a new `Counter` of kind `Zero`. For this `CounterKind`, the
32     /// `id` is not used.
33     pub fn zero() -> Self {
34         Self { kind: CounterKind::Zero, id: 0 }
35     }
36
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() }
42     }
43
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() }
47     }
48
49     /// Returns true if the `Counter` kind is `Zero`.
50     pub fn is_zero(&self) -> bool {
51         matches!(self.kind, CounterKind::Zero)
52     }
53
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");
58         self.id
59     }
60 }
61
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)]
64 #[repr(C)]
65 pub enum ExprKind {
66     Subtract = 0,
67     Add = 1,
68 }
69
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++
72 /// counterpart.
73 #[derive(Copy, Clone, Debug)]
74 #[repr(C)]
75 pub struct CounterExpression {
76     pub kind: ExprKind,
77     pub lhs: Counter,
78     pub rhs: Counter,
79 }
80
81 impl CounterExpression {
82     pub fn new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self {
83         Self { kind, lhs, rhs }
84     }
85 }