Skip to content

Commit

Permalink
Exclude X0 (C_RET_REG) from allocatable registers on arm (#319)
Browse files Browse the repository at this point in the history
* Exclude X0 (C_RET_REG) from allocatable registers on arm

* Add another small test snippett
  • Loading branch information
maximecb authored and k0kubun committed Aug 25, 2022
1 parent 1d54d33 commit 3254d53
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
7 changes: 7 additions & 0 deletions bootstraptest/test_yjit_new_backend.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Run can run this test file directly with:
# make -j miniruby && RUST_BACKTRACE=1 ruby --disable=gems bootstraptest/runner.rb --ruby="./miniruby -I./lib -I. -I.ext/common --disable-gems --yjit-call-threshold=1 --yjit-verify-ctx" bootstraptest/test_yjit_new_backend.rb

assert_equal '1', %q{
def foo()
1
end
foo()
}

assert_equal '3', %q{
def foo(n)
n
Expand Down
9 changes: 6 additions & 3 deletions yjit/src/backend/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,15 @@ impl From<Opnd> for A64Opnd {

impl Assembler
{
/// Get the list of registers from which we can allocate on this platform
/// Get the list of registers from which we will allocate on this platform
/// These are caller-saved registers
/// Note: we intentionally exclude C_RET_REG (X0) from this list
/// because of the way it's used in gen_leave() and gen_leave_exit()
pub fn get_alloc_regs() -> Vec<Reg> {
vec![C_RET_REG, X12_REG]
vec![X11_REG, X12_REG]
}

/// Get a list of all of the caller-save registers
/// Get a list of all of the caller-saved registers
pub fn get_caller_save_regs() -> Vec<Reg> {
vec![X9_REG, X10_REG, X11_REG, X12_REG, X13_REG, X14_REG, X15_REG]
}
Expand Down
20 changes: 14 additions & 6 deletions yjit/src/backend/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,18 +570,26 @@ impl Assembler

// Allocate a specific register
fn take_reg(pool: &mut u32, regs: &Vec<Reg>, reg: &Reg) -> Reg {
let reg_index = regs.iter().position(|elem| elem.reg_no == reg.reg_no).unwrap();
assert_eq!(*pool & (1 << reg_index), 0);
*pool |= 1 << reg_index;
return regs[reg_index];
let reg_index = regs.iter().position(|elem| elem.reg_no == reg.reg_no);

if let Some(reg_index) = reg_index {
assert_eq!(*pool & (1 << reg_index), 0);
*pool |= 1 << reg_index;
//return regs[reg_index];
}

return *reg;
}

// Mutate the pool bitmap to indicate that the given register is being
// returned as it is no longer used by the instruction that previously
// held it.
fn dealloc_reg(pool: &mut u32, regs: &Vec<Reg>, reg: &Reg) {
let reg_index = regs.iter().position(|elem| elem.reg_no == reg.reg_no).unwrap();
*pool &= !(1 << reg_index);
let reg_index = regs.iter().position(|elem| elem.reg_no == reg.reg_no);

if let Some(reg_index) = reg_index {
*pool &= !(1 << reg_index);
}
}

let live_ranges: Vec<usize> = std::mem::take(&mut self.live_ranges);
Expand Down

0 comments on commit 3254d53

Please sign in to comment.