Skip to content
Open
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
7 changes: 4 additions & 3 deletions src/fastalloc/lru.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ pub struct LruNode {
}

impl Lru {
pub fn new(regclass: RegClass, regs: &[PReg]) -> Self {
pub fn new(regclass: RegClass, regs: &PRegSet) -> Self {
let regs = regs.into_iter().collect::<Vec<_>>();
let mut data = vec![
LruNode {
prev: u8::MAX,
Expand Down Expand Up @@ -248,7 +249,7 @@ impl fmt::Debug for Lru {
while node != self.head {
if seen.contains(&node) {
panic!(
"The {:?} LRU is messed up:
"The {:?} LRU is messed up:
head: {:?}, {:?} -> p{node}, actual data: {:?}",
self.regclass, self.head, data_str, self.data
);
Expand Down Expand Up @@ -298,7 +299,7 @@ impl<T: PartialEq> PartialEq for PartedByRegClass<T> {
pub type Lrus = PartedByRegClass<Lru>;

impl Lrus {
pub fn new(int_regs: &[PReg], float_regs: &[PReg], vec_regs: &[PReg]) -> Self {
pub fn new(int_regs: &PRegSet, float_regs: &PRegSet, vec_regs: &PRegSet) -> Self {
Self {
items: [
Lru::new(RegClass::Int, int_regs),
Expand Down
24 changes: 6 additions & 18 deletions src/fastalloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,21 +444,9 @@ impl<'a, F: Function> Env<'a, F> {
env.preferred_regs_by_class[RegClass::Float as usize].clone(),
env.preferred_regs_by_class[RegClass::Vector as usize].clone(),
];
regs[0].extend(
env.non_preferred_regs_by_class[RegClass::Int as usize]
.iter()
.cloned(),
);
regs[1].extend(
env.non_preferred_regs_by_class[RegClass::Float as usize]
.iter()
.cloned(),
);
regs[2].extend(
env.non_preferred_regs_by_class[RegClass::Vector as usize]
.iter()
.cloned(),
);
regs[0].union_from(env.non_preferred_regs_by_class[RegClass::Int as usize]);
regs[1].union_from(env.non_preferred_regs_by_class[RegClass::Float as usize]);
regs[2].union_from(env.non_preferred_regs_by_class[RegClass::Vector as usize]);
let allocatable_regs = PRegSet::from(env);
let num_available_pregs: PartedByRegClass<i16> = PartedByRegClass {
items: [
Expand Down Expand Up @@ -508,9 +496,9 @@ impl<'a, F: Function> Env<'a, F> {
],
preferred_victim: PartedByRegClass {
items: [
regs[0].last().cloned().unwrap_or(PReg::invalid()),
regs[1].last().cloned().unwrap_or(PReg::invalid()),
regs[2].last().cloned().unwrap_or(PReg::invalid()),
regs[0].max_preg().unwrap_or(PReg::invalid()),
regs[1].max_preg().unwrap_or(PReg::invalid()),
regs[2].max_preg().unwrap_or(PReg::invalid()),
],
},
reused_input_to_reuse_op: vec![usize::MAX; max_operand_len as usize],
Expand Down
6 changes: 3 additions & 3 deletions src/fastalloc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ fn mach_env(no_of_regs: usize) -> MachineEnv {
(0..no_of_regs)
.map(|no| PReg::new(no, RegClass::Int))
.collect(),
vec![],
vec![],
PRegSet::empty(),
PRegSet::empty(),
],
non_preferred_regs_by_class: [vec![], vec![], vec![]],
non_preferred_regs_by_class: [PRegSet::empty(); 3],
scratch_by_class: [None, None, None],
fixed_stack_slots: vec![],
}
Expand Down
8 changes: 4 additions & 4 deletions src/fuzzing/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,20 +696,20 @@ impl core::fmt::Debug for Func {
}

pub fn machine_env() -> MachineEnv {
fn regs(r: core::ops::Range<usize>, c: RegClass) -> Vec<PReg> {
fn regs(r: core::ops::Range<usize>, c: RegClass) -> PRegSet {
r.map(|i| PReg::new(i, c)).collect()
}
let preferred_regs_by_class: [Vec<PReg>; 3] = [
let preferred_regs_by_class = [
regs(0..24, RegClass::Int),
regs(0..24, RegClass::Float),
regs(0..24, RegClass::Vector),
];
let non_preferred_regs_by_class: [Vec<PReg>; 3] = [
let non_preferred_regs_by_class = [
regs(24..32, RegClass::Int),
regs(24..32, RegClass::Float),
regs(24..32, RegClass::Vector),
];
let scratch_by_class: [Option<PReg>; 3] = [None, None, None];
let scratch_by_class = [None, None, None];
let fixed_stack_slots = (32..63)
.flat_map(|i| {
[
Expand Down
5 changes: 2 additions & 3 deletions src/ion/liveranges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,8 @@ impl<'a, F: Function> Env<'a, F> {
}
for class in 0..self.preferred_victim_by_class.len() {
self.preferred_victim_by_class[class] = self.env.non_preferred_regs_by_class[class]
.last()
.or(self.env.preferred_regs_by_class[class].last())
.cloned()
.max_preg()
.or(self.env.preferred_regs_by_class[class].max_preg())
.unwrap_or(PReg::invalid());
}
// Create VRegs from the vreg count.
Expand Down
4 changes: 2 additions & 2 deletions src/ion/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1219,8 +1219,8 @@ impl<'a, F: Function> Env<'a, F> {
let mut fixed_assigned = 0;
let mut total_regs = 0;
for preg in self.env.preferred_regs_by_class[class as u8 as usize]
.iter()
.chain(self.env.non_preferred_regs_by_class[class as u8 as usize].iter())
.into_iter()
.chain(self.env.non_preferred_regs_by_class[class as u8 as usize])
{
trace!(" -> PR {:?}", preg);
let start = LiveRangeKey::from_range(&CodeRange {
Expand Down
78 changes: 26 additions & 52 deletions src/ion/reg_traversal.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,28 @@
//! Iterate over available registers.

use crate::{MachineEnv, PReg, RegClass};
use crate::{MachineEnv, PReg, PRegSet, PRegSetIter, RegClass};

/// Keep track of where we are in the register traversal.
struct Cursor<'a> {
registers: &'a [PReg],
index: usize,
offset: usize,
struct Cursor {
first: PRegSetIter,
second: PRegSetIter,
}

impl<'a> Cursor<'a> {
impl Cursor {
#[inline]
fn new(registers: &'a [PReg], offset_hint: usize) -> Self {
let offset = if registers.len() > 0 {
offset_hint % registers.len()
} else {
0
};
fn new(registers: &PRegSet, class: RegClass, offset_hint: usize) -> Self {
let mut mask = PRegSet::empty();
mask.add_up_to(PReg::new(offset_hint % PReg::MAX, class));
let first = *registers & mask.invert();
let second = *registers & mask;
Self {
registers,
index: 0,
offset,
first: first.into_iter(),
second: second.into_iter(),
}
}

/// Wrap around the end of the register list; [`Cursor::done`] guarantees we
/// do not see the same register twice.
#[inline]
fn wrap(index: usize, end: usize) -> usize {
if index >= end {
index - end
} else {
index
}
}

/// Advance to the next register and return it.
#[inline]
fn advance(&mut self) -> PReg {
let loc = Self::wrap(self.index + self.offset, self.registers.len());
let reg = self.registers[loc];
self.index += 1;
reg
}

/// Return `true` if we have seen all registers.
#[inline]
fn done(&self) -> bool {
self.index >= self.registers.len()
fn next(&mut self) -> Option<PReg> {
self.first.next().or_else(|| self.second.next())
}
}

Expand All @@ -65,19 +40,19 @@ impl<'a> Cursor<'a> {
/// registers; then, non-preferred registers. (In normal usage, these consist
/// of caller-save and callee-save registers respectively, to minimize
/// clobber-saves; but they need not.)
pub struct RegTraversalIter<'a> {
pub struct RegTraversalIter {
is_fixed: bool,
fixed: Option<PReg>,
use_hint: bool,
hint: Option<PReg>,
preferred: Cursor<'a>,
non_preferred: Cursor<'a>,
preferred: Cursor,
non_preferred: Cursor,
limit: Option<usize>,
}

impl<'a> RegTraversalIter<'a> {
impl RegTraversalIter {
pub fn new(
env: &'a MachineEnv,
env: &MachineEnv,
class: RegClass,
fixed: Option<PReg>,
hint: Option<PReg>,
Expand All @@ -87,9 +62,10 @@ impl<'a> RegTraversalIter<'a> {
debug_assert!(fixed != Some(PReg::invalid()));
debug_assert!(hint != Some(PReg::invalid()));

let class = class as u8 as usize;
let preferred = Cursor::new(&env.preferred_regs_by_class[class], offset);
let non_preferred = Cursor::new(&env.non_preferred_regs_by_class[class], offset);
let class_index = class as u8 as usize;
let preferred = Cursor::new(&env.preferred_regs_by_class[class_index], class, offset);
let non_preferred =
Cursor::new(&env.non_preferred_regs_by_class[class_index], class, offset);

Self {
is_fixed: fixed.is_some(),
Expand All @@ -103,7 +79,7 @@ impl<'a> RegTraversalIter<'a> {
}
}

impl<'a> core::iter::Iterator for RegTraversalIter<'a> {
impl core::iter::Iterator for RegTraversalIter {
type Item = PReg;

fn next(&mut self) -> Option<PReg> {
Expand All @@ -118,16 +94,14 @@ impl<'a> core::iter::Iterator for RegTraversalIter<'a> {
}
}

while !self.preferred.done() {
let reg = self.preferred.advance();
while let Some(reg) = self.preferred.next() {
if Some(reg) == self.hint || reg.hw_enc() >= self.limit.unwrap_or(usize::MAX) {
continue; // Try again; we already tried the hint or we are outside of the register range limit.
}
return Some(reg);
}

while !self.non_preferred.done() {
let reg = self.non_preferred.advance();
while let Some(reg) = self.non_preferred.next() {
if Some(reg) == self.hint || reg.hw_enc() >= self.limit.unwrap_or(usize::MAX) {
continue; // Try again; we already tried the hint or we are outside of the register range limit.
}
Expand Down
Loading