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

@@ -8,8 +8,9 @@ use crate::isa::x64::settings as x64_settings;
use crate::isa::CallConv;
use crate::machinst::*;
use crate::{settings, CodegenError, CodegenResult};
use alloc::boxed::Box;
use alloc::vec::Vec;
use regalloc2::{Allocation, VReg};
use regalloc2::{Allocation, PRegSet, VReg};
use smallvec::{smallvec, SmallVec};
use std::fmt;
use std::string::{String, ToString};
@@ -29,6 +30,19 @@ use args::*;
// `Inst` is defined inside ISLE as `MInst`. We publicly re-export it here.
pub use super::lower::isle::generated_code::MInst as Inst;
// Out-of-line data for calls, to keep the size of `Inst` downn.
#[derive(Clone, Debug)]
pub struct CallInfo {
/// Register uses of this call.
pub uses: SmallVec<[Reg; 8]>,
/// Register defs of this call.
pub defs: SmallVec<[Writable<Reg>; 8]>,
/// Registers clobbered by this call, as per its calling convention.
pub clobbers: PRegSet,
/// The opcode of this call.
pub opcode: Opcode,
}
pub(crate) fn low32_will_sign_extend_to_64(x: u64) -> bool {
let xs = x as i64;
xs == ((xs << 32) >> 32)
@@ -646,30 +660,38 @@ impl Inst {
pub(crate) fn call_known(
dest: ExternalName,
uses: Vec<Reg>,
defs: Vec<Writable<Reg>>,
uses: SmallVec<[Reg; 8]>,
defs: SmallVec<[Writable<Reg>; 8]>,
clobbers: PRegSet,
opcode: Opcode,
) -> Inst {
Inst::CallKnown {
dest,
uses,
defs,
opcode,
info: Box::new(CallInfo {
uses,
defs,
clobbers,
opcode,
}),
}
}
pub(crate) fn call_unknown(
dest: RegMem,
uses: Vec<Reg>,
defs: Vec<Writable<Reg>>,
uses: SmallVec<[Reg; 8]>,
defs: SmallVec<[Writable<Reg>; 8]>,
clobbers: PRegSet,
opcode: Opcode,
) -> Inst {
dest.assert_regclass_is(RegClass::Int);
Inst::CallUnknown {
dest,
uses,
defs,
opcode,
info: Box::new(CallInfo {
uses,
defs,
clobbers,
opcode,
}),
}
}
@@ -1977,34 +1999,25 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
collector.reg_def(dst.to_writable_reg());
}
Inst::CallKnown {
ref uses, ref defs, ..
} => {
for &u in uses {
Inst::CallKnown { ref info, .. } => {
for &u in &info.uses {
collector.reg_use(u);
}
for &d in defs {
for &d in &info.defs {
collector.reg_def(d);
}
// FIXME: keep clobbers separate in the Inst and use
// `reg_clobber()`.
collector.reg_clobbers(info.clobbers);
}
Inst::CallUnknown {
ref uses,
ref defs,
dest,
..
} => {
Inst::CallUnknown { ref info, dest, .. } => {
dest.get_operands(collector);
for &u in uses {
for &u in &info.uses {
collector.reg_use(u);
}
for &d in defs {
for &d in &info.defs {
collector.reg_def(d);
}
// FIXME: keep clobbers separate in the Inst and use
// `reg_clobber()`.
collector.reg_clobbers(info.clobbers);
}
Inst::JmpTableSeq {
@@ -2076,10 +2089,9 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
// pseudoinstruction (and relocation that it emits) is specific to
// ELF systems; other x86-64 targets with other conventions (i.e.,
// Windows) use different TLS strategies.
for reg in X64ABIMachineSpec::get_regs_clobbered_by_call(CallConv::SystemV) {
// FIXME: use actual clobber functionality.
collector.reg_def(reg);
}
collector.reg_clobbers(X64ABIMachineSpec::get_regs_clobbered_by_call(
CallConv::SystemV,
));
}
Inst::Unwind { .. } => {}