diff --git a/src/ion/liveranges.rs b/src/ion/liveranges.rs index 5a9b00e4..e226884b 100644 --- a/src/ion/liveranges.rs +++ b/src/ion/liveranges.rs @@ -577,7 +577,7 @@ impl<'a, F: Function> Env<'a, F> { if late_def_fixed.contains(&preg) || self.func.inst_clobbers(inst).contains(preg) { - log::trace!( + trace!( concat!( "-> operand {:?} is fixed to preg {:?}, ", "is downward live, and there is also a ", diff --git a/src/lib.rs b/src/lib.rs index 070608ca..4185530b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -125,7 +125,7 @@ impl PReg { /// The register class. #[inline(always)] pub const fn class(self) -> RegClass { - match self.bits & (0b11 << Self::MAX_BITS) { + match (self.bits >> Self::MAX_BITS) & 0b11 { 0 => RegClass::Int, 1 => RegClass::Float, 2 => RegClass::Vector, @@ -188,49 +188,54 @@ impl core::fmt::Display for PReg { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct PRegSet { - bits: u128, + bits: [u128; 2], } impl PRegSet { /// Create an empty set. pub const fn empty() -> Self { - Self { bits: 0 } + Self { bits: [0; 2] } } /// Returns whether the given register is part of the set. pub fn contains(&self, reg: PReg) -> bool { - let bit = reg.index(); - debug_assert!(bit < 128); - self.bits & 1u128 << bit != 0 + debug_assert!(reg.index() < 256); + let bit = reg.index() & 127; + let index = reg.index() >> 7; + self.bits[index] & (1u128 << bit) != 0 } /// Add a physical register (PReg) to the set, returning the new value. pub const fn with(self, reg: PReg) -> Self { - let bit = reg.index(); - debug_assert!(bit < 128); - Self { - bits: self.bits | (1u128 << bit), - } + debug_assert!(reg.index() < 256); + let bit = reg.index() & 127; + let index = reg.index() >> 7; + let mut out = self; + out.bits[index] |= 1u128 << bit; + out } /// Add a physical register (PReg) to the set. pub fn add(&mut self, reg: PReg) { - let bit = reg.index(); - debug_assert!(bit < 128); - self.bits |= 1u128 << bit; + debug_assert!(reg.index() < 256); + let bit = reg.index() & 127; + let index = reg.index() >> 7; + self.bits[index] |= 1u128 << bit; } /// Remove a physical register (PReg) from the set. pub fn remove(&mut self, reg: PReg) { - let bit = reg.index(); - debug_assert!(bit < 128); - self.bits &= !(1u128 << bit); + debug_assert!(reg.index() < 256); + let bit = reg.index() & 127; + let index = reg.index() >> 7; + self.bits[index] &= !(1u128 << bit); } /// Add all of the registers in one set to this one, mutating in /// place. pub fn union_from(&mut self, other: PRegSet) { - self.bits |= other.bits; + self.bits[0] |= other.bits[0]; + self.bits[1] |= other.bits[1]; } } @@ -243,18 +248,22 @@ impl IntoIterator for PRegSet { } pub struct PRegSetIter { - bits: u128, + bits: [u128; 2], } impl Iterator for PRegSetIter { type Item = PReg; fn next(&mut self) -> Option { - if self.bits == 0 { - None - } else { - let index = self.bits.trailing_zeros(); - self.bits &= !(1u128 << index); + if self.bits[0] != 0 { + let index = self.bits[0].trailing_zeros(); + self.bits[0] &= !(1u128 << index); Some(PReg::from_index(index as usize)) + } else if self.bits[1] != 0 { + let index = self.bits[1].trailing_zeros(); + self.bits[1] &= !(1u128 << index); + Some(PReg::from_index(index as usize + 128)) + } else { + None } } } @@ -822,6 +831,9 @@ impl core::fmt::Debug for Operand { impl core::fmt::Display for Operand { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(preg) = self.as_fixed_nonallocatable() { + return write!(f, "Fixed: {preg}"); + } match (self.kind(), self.pos()) { (OperandKind::Def, OperandPos::Late) | (OperandKind::Use, OperandPos::Early) => { write!(f, "{:?}", self.kind())?;