Cranelift: update to latest regalloc2: (#4324)

- Handle call instructions' clobbers with the clobbers API, using RA2's
  clobbers bitmask (bytecodealliance/regalloc2#58) rather than clobbers
  list;

- Pull in changes from bytecodealliance/regalloc2#59 for much more sane
  edge-case behavior w.r.t. liverange splitting.
This commit is contained in:
Chris Fallin
2022-06-28 09:01:59 -07:00
committed by GitHub
parent 66b829b1bf
commit b2e28b917a
21 changed files with 402 additions and 293 deletions

View File

@@ -71,8 +71,7 @@ use crate::settings;
use crate::{CodegenError, CodegenResult};
use alloc::boxed::Box;
use alloc::vec::Vec;
use regalloc2::PReg;
use regalloc2::VReg;
use regalloc2::{PReg, PRegSet, VReg};
use smallvec::{smallvec, SmallVec};
use std::convert::TryFrom;
@@ -618,8 +617,9 @@ impl ABIMachineSpec for S390xMachineDeps {
fn gen_call(
dest: &CallDest,
uses: Vec<Reg>,
defs: Vec<Writable<Reg>>,
uses: SmallVec<[Reg; 8]>,
defs: SmallVec<[Writable<Reg>; 8]>,
clobbers: PRegSet,
opcode: ir::Opcode,
tmp: Writable<Reg>,
_callee_conv: isa::CallConv,
@@ -633,6 +633,7 @@ impl ABIMachineSpec for S390xMachineDeps {
dest: name.clone(),
uses,
defs,
clobbers,
opcode,
}),
}),
@@ -648,6 +649,7 @@ impl ABIMachineSpec for S390xMachineDeps {
rn: tmp.to_reg(),
uses,
defs,
clobbers,
opcode,
}),
});
@@ -658,6 +660,7 @@ impl ABIMachineSpec for S390xMachineDeps {
rn: *reg,
uses,
defs,
clobbers,
opcode,
}),
}),
@@ -693,21 +696,8 @@ impl ABIMachineSpec for S390xMachineDeps {
s.initial_sp_offset
}
fn get_regs_clobbered_by_call(call_conv_of_callee: isa::CallConv) -> Vec<Writable<Reg>> {
let mut caller_saved = Vec::new();
for i in 0..15 {
let x = writable_gpr(i);
if is_reg_clobbered_by_call(call_conv_of_callee, x.to_reg().to_real_reg().unwrap()) {
caller_saved.push(x);
}
}
for i in 0..15 {
let v = writable_fpr(i);
if is_reg_clobbered_by_call(call_conv_of_callee, v.to_reg().to_real_reg().unwrap()) {
caller_saved.push(v);
}
}
caller_saved
fn get_regs_clobbered_by_call(_call_conv_of_callee: isa::CallConv) -> PRegSet {
CLOBBERS
}
fn get_ext_mode(
@@ -783,15 +773,22 @@ fn get_regs_saved_in_prologue(
(int_saves, fpr_saves)
}
fn is_reg_clobbered_by_call(_call_conv: isa::CallConv, r: RealReg) -> bool {
match r.class() {
RegClass::Int => {
// r0 - r5 inclusive are caller-saves.
r.hw_enc() <= 5
}
RegClass::Float => {
// f0 - f7 inclusive are caller-saves.
r.hw_enc() <= 7
}
}
const fn clobbers() -> PRegSet {
PRegSet::empty()
.with(gpr_preg(0))
.with(gpr_preg(1))
.with(gpr_preg(2))
.with(gpr_preg(3))
.with(gpr_preg(4))
.with(gpr_preg(5))
.with(fpr_preg(0))
.with(fpr_preg(1))
.with(fpr_preg(2))
.with(fpr_preg(3))
.with(fpr_preg(4))
.with(fpr_preg(5))
.with(fpr_preg(6))
.with(fpr_preg(7))
}
const CLOBBERS: PRegSet = clobbers();

View File

@@ -6804,8 +6804,9 @@ fn test_s390x_binemit() {
link: writable_gpr(14),
info: Box::new(CallInfo {
dest: ExternalName::testcase("test0"),
uses: Vec::new(),
defs: Vec::new(),
uses: smallvec![],
defs: smallvec![],
clobbers: PRegSet::empty(),
opcode: Opcode::Call,
}),
},
@@ -6818,8 +6819,9 @@ fn test_s390x_binemit() {
link: writable_gpr(14),
info: Box::new(CallIndInfo {
rn: gpr(1),
uses: Vec::new(),
defs: Vec::new(),
uses: smallvec![],
defs: smallvec![],
clobbers: PRegSet::empty(),
opcode: Opcode::CallIndirect,
}),
},

View File

@@ -7,7 +7,7 @@ use crate::{settings, CodegenError, CodegenResult};
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::convert::TryFrom;
use regalloc2::VReg;
use regalloc2::{PRegSet, VReg};
use smallvec::{smallvec, SmallVec};
use std::string::{String, ToString};
pub mod regs;
@@ -36,8 +36,9 @@ pub use crate::isa::s390x::lower::isle::generated_code::{
#[derive(Clone, Debug)]
pub struct CallInfo {
pub dest: ExternalName,
pub uses: Vec<Reg>,
pub defs: Vec<Writable<Reg>>,
pub uses: SmallVec<[Reg; 8]>,
pub defs: SmallVec<[Writable<Reg>; 8]>,
pub clobbers: PRegSet,
pub opcode: Opcode,
}
@@ -46,8 +47,9 @@ pub struct CallInfo {
#[derive(Clone, Debug)]
pub struct CallIndInfo {
pub rn: Reg,
pub uses: Vec<Reg>,
pub defs: Vec<Writable<Reg>>,
pub uses: SmallVec<[Reg; 8]>,
pub defs: SmallVec<[Writable<Reg>; 8]>,
pub clobbers: PRegSet,
pub opcode: Opcode,
}
@@ -660,12 +662,14 @@ fn s390x_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandC
collector.reg_def(link);
collector.reg_uses(&*info.uses);
collector.reg_defs(&*info.defs);
collector.reg_clobbers(info.clobbers);
}
&Inst::CallInd { link, ref info } => {
collector.reg_def(link);
collector.reg_use(info.rn);
collector.reg_uses(&*info.uses);
collector.reg_defs(&*info.defs);
collector.reg_clobbers(info.clobbers);
}
&Inst::Ret { link, ref rets } => {
collector.reg_use(link);

View File

@@ -13,11 +13,15 @@ use crate::settings;
/// Get a reference to a GPR (integer register).
pub fn gpr(num: u8) -> Reg {
assert!(num < 16);
let preg = PReg::new(num as usize, RegClass::Int);
let preg = gpr_preg(num);
Reg::from(VReg::new(preg.index(), RegClass::Int))
}
pub(crate) const fn gpr_preg(num: u8) -> PReg {
assert!(num < 16);
PReg::new(num as usize, RegClass::Int)
}
/// Get a writable reference to a GPR.
pub fn writable_gpr(num: u8) -> Writable<Reg> {
Writable::from_reg(gpr(num))
@@ -25,12 +29,17 @@ pub fn writable_gpr(num: u8) -> Writable<Reg> {
/// Get a reference to a FPR (floating-point register).
pub fn fpr(num: u8) -> Reg {
assert!(num < 16);
let preg = PReg::new(num as usize, RegClass::Float);
let preg = fpr_preg(num);
Reg::from(VReg::new(preg.index(), RegClass::Float))
}
/// Get a writable reference to a V-register.
pub(crate) const fn fpr_preg(num: u8) -> PReg {
assert!(num < 16);
PReg::new(num as usize, RegClass::Float)
}
/// Get a writable reference to a FPR.
#[allow(dead_code)] // used by tests.
pub fn writable_fpr(num: u8) -> Writable<Reg> {
Writable::from_reg(fpr(num))
}