Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ion/liveranges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ",
Expand Down
60 changes: 36 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, yikes, thanks for catching this -- sorry I missed it in review!

0 => RegClass::Int,
1 => RegClass::Float,
2 => RegClass::Vector,
Expand Down Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that this logic has become slightly more complex, perhaps we could delegate to add with something like

let mut out = self;
out.add(reg);
out

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that at first, but it's not possible since with is a const fn. add can't be made const because it uses &mut self.

}

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

Expand All @@ -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<PReg> {
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
}
}
}
Expand Down Expand Up @@ -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())?;
Expand Down