Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/machinst/valueregs.rs
Line
Count
Source (jump to first uncovered line)
1
//! Data structure for tracking the (possibly multiple) registers that hold one
2
//! SSA `Value`.
3
4
use regalloc2::{PReg, VReg};
5
6
use super::{RealReg, Reg, VirtualReg, Writable};
7
use std::fmt::Debug;
8
9
const VALUE_REGS_PARTS: usize = 2;
10
11
/// Location at which a `Value` is stored in register(s): the value is located
12
/// in one or more registers, depending on its width. A value may be stored in
13
/// more than one register if the machine has no registers wide enough
14
/// otherwise: for example, on a 32-bit architecture, we may store `I64` values
15
/// in two registers, and `I128` values in four.
16
///
17
/// By convention, the register parts are kept in machine-endian order here.
18
///
19
/// N.B.: we cap the capacity of this at four (when any 32-bit target is
20
/// enabled) or two (otherwise), and we use special in-band sentinal `Reg`
21
/// values (`Reg::invalid()`) to avoid the need to carry a separate length. This
22
/// allows the struct to be `Copy` (no heap or drop overhead) and be only 16 or
23
/// 8 bytes, which is important for compiler performance.
24
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25
pub struct ValueRegs<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> {
26
    parts: [R; VALUE_REGS_PARTS],
27
}
28
29
/// A type with an "invalid" sentinel value.
30
pub trait InvalidSentinel: Copy + Eq {
31
    /// The invalid sentinel value.
32
    fn invalid_sentinel() -> Self;
33
    /// Is this the invalid sentinel?
34
2.69M
    fn is_invalid_sentinel(self) -> bool {
35
2.69M
        self == Self::invalid_sentinel()
36
2.69M
    }
<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg> as cranelift_codegen::machinst::valueregs::InvalidSentinel>::is_invalid_sentinel
Line
Count
Source
34
36.3k
    fn is_invalid_sentinel(self) -> bool {
35
36.3k
        self == Self::invalid_sentinel()
36
36.3k
    }
Unexecuted instantiation: <cranelift_codegen::machinst::reg::VirtualReg as cranelift_codegen::machinst::valueregs::InvalidSentinel>::is_invalid_sentinel
<cranelift_codegen::machinst::reg::Reg as cranelift_codegen::machinst::valueregs::InvalidSentinel>::is_invalid_sentinel
Line
Count
Source
34
2.65M
    fn is_invalid_sentinel(self) -> bool {
35
2.65M
        self == Self::invalid_sentinel()
36
2.65M
    }
Unexecuted instantiation: <cranelift_codegen::machinst::reg::RealReg as cranelift_codegen::machinst::valueregs::InvalidSentinel>::is_invalid_sentinel
37
}
38
impl InvalidSentinel for Reg {
39
18.5M
    fn invalid_sentinel() -> Self {
40
18.5M
        Reg::from(VReg::invalid())
41
18.5M
    }
42
}
43
impl InvalidSentinel for VirtualReg {
44
0
    fn invalid_sentinel() -> Self {
45
0
        VirtualReg::from(VReg::invalid())
46
0
    }
47
}
48
impl InvalidSentinel for RealReg {
49
0
    fn invalid_sentinel() -> Self {
50
0
        RealReg::from(PReg::invalid())
51
0
    }
52
}
53
impl InvalidSentinel for Writable<Reg> {
54
4.74M
    fn invalid_sentinel() -> Self {
55
4.74M
        Writable::from_reg(Reg::invalid_sentinel())
56
4.74M
    }
57
}
58
59
impl<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> ValueRegs<R> {
60
    /// Create an invalid Value-in-Reg.
61
139k
    pub fn invalid() -> Self {
62
139k
        ValueRegs {
63
139k
            parts: [R::invalid_sentinel(); VALUE_REGS_PARTS],
64
139k
        }
65
139k
    }
66
67
    /// Is this Value-to-Reg mapping valid?
68
928k
    pub fn is_valid(self) -> bool {
69
928k
        !self.parts[0].is_invalid_sentinel()
70
928k
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::is_valid
Line
Count
Source
68
36.3k
    pub fn is_valid(self) -> bool {
69
36.3k
        !self.parts[0].is_invalid_sentinel()
70
36.3k
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Reg>>::is_valid
Line
Count
Source
68
892k
    pub fn is_valid(self) -> bool {
69
892k
        !self.parts[0].is_invalid_sentinel()
70
892k
    }
71
    /// Is this Value-to-Reg mapping invalid?
72
1.10M
    pub fn is_invalid(self) -> bool {
73
1.10M
        self.parts[0].is_invalid_sentinel()
74
1.10M
    }
75
76
    /// Return the single register used for this value, if any.
77
1.59M
    pub fn only_reg(self) -> Option<R> {
78
1.59M
        if self.len() == 1 {
79
1.59M
            Some(self.parts[0])
80
        } else {
81
0
            None
82
        }
83
1.59M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::only_reg
Line
Count
Source
77
748k
    pub fn only_reg(self) -> Option<R> {
78
748k
        if self.len() == 1 {
79
748k
            Some(self.parts[0])
80
        } else {
81
0
            None
82
        }
83
748k
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Reg>>::only_reg
Line
Count
Source
77
843k
    pub fn only_reg(self) -> Option<R> {
78
843k
        if self.len() == 1 {
79
843k
            Some(self.parts[0])
80
        } else {
81
0
            None
82
        }
83
843k
    }
84
85
    /// Return an iterator over the registers storing this value.
86
4.07M
    pub fn regs(&self) -> &[R] {
87
4.07M
        &self.parts[0..self.len()]
88
4.07M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::regs
Line
Count
Source
86
1.02M
    pub fn regs(&self) -> &[R] {
87
1.02M
        &self.parts[0..self.len()]
88
1.02M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Reg>>::regs
Line
Count
Source
86
3.05M
    pub fn regs(&self) -> &[R] {
87
3.05M
        &self.parts[0..self.len()]
88
3.05M
    }
89
}
90
91
impl<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> ValueRegs<R> {
92
    /// Create a Value-in-R location for a value stored in one register.
93
2.32M
    pub fn one(reg: R) -> Self {
94
2.32M
        ValueRegs {
95
2.32M
            parts: [reg, R::invalid_sentinel()],
96
2.32M
        }
97
2.32M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Reg>>::one
Line
Count
Source
93
2.27M
    pub fn one(reg: R) -> Self {
94
2.27M
        ValueRegs {
95
2.27M
            parts: [reg, R::invalid_sentinel()],
96
2.27M
        }
97
2.27M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::one
Line
Count
Source
93
49.6k
    pub fn one(reg: R) -> Self {
94
49.6k
        ValueRegs {
95
49.6k
            parts: [reg, R::invalid_sentinel()],
96
49.6k
        }
97
49.6k
    }
98
    /// Create a Value-in-R location for a value stored in two registers.
99
564
    pub fn two(r1: R, r2: R) -> Self {
100
564
        ValueRegs { parts: [r1, r2] }
101
564
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Reg>>::two
Line
Count
Source
99
564
    pub fn two(r1: R, r2: R) -> Self {
100
564
        ValueRegs { parts: [r1, r2] }
101
564
    }
Unexecuted instantiation: <cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::two
102
103
    /// Return the number of registers used.
104
6.58M
    pub fn len(self) -> usize {
105
6.58M
        // If rustc/LLVM is smart enough, this might even be vectorized...
106
6.58M
        (self.parts[0] != R::invalid_sentinel()) as usize
107
6.58M
            + (self.parts[1] != R::invalid_sentinel()) as usize
108
6.58M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::len
Line
Count
Source
104
2.33M
    pub fn len(self) -> usize {
105
2.33M
        // If rustc/LLVM is smart enough, this might even be vectorized...
106
2.33M
        (self.parts[0] != R::invalid_sentinel()) as usize
107
2.33M
            + (self.parts[1] != R::invalid_sentinel()) as usize
108
2.33M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Reg>>::len
Line
Count
Source
104
4.25M
    pub fn len(self) -> usize {
105
4.25M
        // If rustc/LLVM is smart enough, this might even be vectorized...
106
4.25M
        (self.parts[0] != R::invalid_sentinel()) as usize
107
4.25M
            + (self.parts[1] != R::invalid_sentinel()) as usize
108
4.25M
    }
109
110
    /// Map individual registers via a map function.
111
1.80M
    pub fn map<NewR, F>(self, f: F) -> ValueRegs<NewR>
112
1.80M
    where
113
1.80M
        NewR: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel,
114
1.80M
        F: Fn(R) -> NewR,
115
1.80M
    {
116
1.80M
        ValueRegs {
117
1.80M
            parts: [f(self.parts[0]), f(self.parts[1])],
118
1.80M
        }
119
1.80M
    }
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::map::<cranelift_codegen::machinst::reg::Reg, cranelift_codegen::machinst::valueregs::non_writable_value_regs::{closure#0}>
Line
Count
Source
111
86.4k
    pub fn map<NewR, F>(self, f: F) -> ValueRegs<NewR>
112
86.4k
    where
113
86.4k
        NewR: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel,
114
86.4k
        F: Fn(R) -> NewR,
115
86.4k
    {
116
86.4k
        ValueRegs {
117
86.4k
            parts: [f(self.parts[0]), f(self.parts[1])],
118
86.4k
        }
119
86.4k
    }
Unexecuted instantiation: <cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>>>::map::<cranelift_codegen::machinst::reg::Reg, <cranelift_codegen::machinst::isle::IsleContext<cranelift_codegen::isa::riscv64::lower::isle::generated_code::MInst, cranelift_codegen::settings::Flags, cranelift_codegen::isa::riscv64::settings::Flags, 6> as cranelift_codegen::isa::riscv64::lower::isle::generated_code::Context>::gen_moves::{closure#2}>
<cranelift_codegen::machinst::valueregs::ValueRegs<cranelift_codegen::machinst::reg::Reg>>::map::<cranelift_codegen::machinst::reg::Writable<cranelift_codegen::machinst::reg::Reg>, cranelift_codegen::machinst::valueregs::writable_value_regs::{closure#0}>
Line
Count
Source
111
1.72M
    pub fn map<NewR, F>(self, f: F) -> ValueRegs<NewR>
112
1.72M
    where
113
1.72M
        NewR: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel,
114
1.72M
        F: Fn(R) -> NewR,
115
1.72M
    {
116
1.72M
        ValueRegs {
117
1.72M
            parts: [f(self.parts[0]), f(self.parts[1])],
118
1.72M
        }
119
1.72M
    }
120
}
121
122
/// Create a writable ValueRegs.
123
#[allow(dead_code)]
124
1.72M
pub(crate) fn writable_value_regs(regs: ValueRegs<Reg>) -> ValueRegs<Writable<Reg>> {
125
3.44M
    regs.map(|r| Writable::from_reg(r))
126
1.72M
}
127
128
/// Strip a writable ValueRegs down to a readonly ValueRegs.
129
#[allow(dead_code)]
130
86.4k
pub(crate) fn non_writable_value_regs(regs: ValueRegs<Writable<Reg>>) -> ValueRegs<Reg> {
131
172k
    regs.map(|r| r.to_reg())
132
86.4k
}