/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 | } |