Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove OnceLock #9992

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -564,3 +564,6 @@ opt-level = 's'
inherits = "release"
codegen-units = 1
lto = true

[patch.crates-io]
regalloc2 = { git = "https://github.com/JonasKruckenberg/regalloc2", branch = "jonas/refactor/static-machine-env" }
130 changes: 104 additions & 26 deletions cranelift/codegen/src/isa/aarch64/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ use alloc::boxed::Box;
use alloc::vec::Vec;
use regalloc2::{MachineEnv, PReg, PRegSet};
use smallvec::{smallvec, SmallVec};
use std::borrow::ToOwned;
use std::sync::OnceLock;

// We use a generic implementation that factors out AArch64 and x64 ABI commonalities, because
// these ABIs are very similar.
Expand Down Expand Up @@ -1115,11 +1113,9 @@ impl ABIMachineSpec for AArch64MachineDeps {

fn get_machine_env(flags: &settings::Flags, _call_conv: isa::CallConv) -> &MachineEnv {
if flags.enable_pinned_reg() {
static MACHINE_ENV: OnceLock<MachineEnv> = OnceLock::new();
MACHINE_ENV.get_or_init(|| create_reg_env(true))
&PINNED_MACHINE_ENV
} else {
static MACHINE_ENV: OnceLock<MachineEnv> = OnceLock::new();
MACHINE_ENV.get_or_init(|| create_reg_env(false))
&DEFAULT_MACHINE_ENV
}
}

Expand Down Expand Up @@ -1440,14 +1436,14 @@ const fn default_aapcs_clobbers() -> PRegSet {

const DEFAULT_AAPCS_CLOBBERS: PRegSet = default_aapcs_clobbers();

fn create_reg_env(enable_pinned_reg: bool) -> MachineEnv {
fn preg(r: Reg) -> PReg {
r.to_real_reg().unwrap().into()
}
const fn preg(r: Reg) -> PReg {
r.to_physical_reg().unwrap()
}

let mut env = MachineEnv {
static PINNED_MACHINE_ENV: MachineEnv = {
MachineEnv {
preferred_regs_by_class: [
vec![
&[
preg(xreg(0)),
preg(xreg(1)),
preg(xreg(2)),
Expand All @@ -1471,7 +1467,7 @@ fn create_reg_env(enable_pinned_reg: bool) -> MachineEnv {
// x21 is the pinned register (if enabled) and not allocatable if so.
// x29 is FP, x30 is LR, x31 is SP/ZR.
],
vec![
&[
preg(vreg(0)),
preg(vreg(1)),
preg(vreg(2)),
Expand Down Expand Up @@ -1499,13 +1495,12 @@ fn create_reg_env(enable_pinned_reg: bool) -> MachineEnv {
preg(vreg(31)),
],
// Vector Regclass is unused
vec![],
&[],
],
non_preferred_regs_by_class: [
vec![
&[
preg(xreg(19)),
preg(xreg(20)),
// x21 is pinned reg if enabled; we add to this list below if not.
preg(xreg(22)),
preg(xreg(23)),
preg(xreg(24)),
Expand All @@ -1514,7 +1509,7 @@ fn create_reg_env(enable_pinned_reg: bool) -> MachineEnv {
preg(xreg(27)),
preg(xreg(28)),
],
vec![
&[
preg(vreg(8)),
preg(vreg(9)),
preg(vreg(10)),
Expand All @@ -1525,16 +1520,99 @@ fn create_reg_env(enable_pinned_reg: bool) -> MachineEnv {
preg(vreg(15)),
],
// Vector Regclass is unused
vec![],
&[],
],
fixed_stack_slots: vec![],
fixed_stack_slots: &[],
scratch_by_class: [None, None, None],
};

if !enable_pinned_reg {
debug_assert_eq!(PINNED_REG, 21); // We assumed this above in hardcoded reg list.
env.non_preferred_regs_by_class[0].push(preg(xreg(PINNED_REG)));
}
};

env
}
static DEFAULT_MACHINE_ENV: MachineEnv = {
debug_assert!(PINNED_REG == 21); // We assumed this below in hardcoded reg list.
Copy link
Member

Choose a reason for hiding this comment

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

This probably goes in the PINNED_MACHINE_ENV above, no? (It's load-bearing there that we get it right, because we excluded the pinned register from allocation; the default environment is used when pinning is disabled so doesn't care what the pinned reg is)


MachineEnv {
preferred_regs_by_class: [
&[
preg(xreg(0)),
preg(xreg(1)),
preg(xreg(2)),
preg(xreg(3)),
preg(xreg(4)),
preg(xreg(5)),
preg(xreg(6)),
preg(xreg(7)),
preg(xreg(8)),
preg(xreg(9)),
preg(xreg(10)),
preg(xreg(11)),
preg(xreg(12)),
preg(xreg(13)),
preg(xreg(14)),
preg(xreg(15)),
// x16 and x17 are spilltmp and tmp2 (see above).
// x18 could be used by the platform to carry inter-procedural state;
// conservatively assume so and make it not allocatable.
// x19-28 are callee-saved and so not preferred.
// x21 is the pinned register (if enabled) and not allocatable if so.
// x29 is FP, x30 is LR, x31 is SP/ZR.
],
&[
preg(vreg(0)),
preg(vreg(1)),
preg(vreg(2)),
preg(vreg(3)),
preg(vreg(4)),
preg(vreg(5)),
preg(vreg(6)),
preg(vreg(7)),
// v8-15 are callee-saved and so not preferred.
preg(vreg(16)),
preg(vreg(17)),
preg(vreg(18)),
preg(vreg(19)),
preg(vreg(20)),
preg(vreg(21)),
preg(vreg(22)),
preg(vreg(23)),
preg(vreg(24)),
preg(vreg(25)),
preg(vreg(26)),
preg(vreg(27)),
preg(vreg(28)),
preg(vreg(29)),
preg(vreg(30)),
preg(vreg(31)),
],
// Vector Regclass is unused
&[],
],
non_preferred_regs_by_class: [
&[
preg(xreg(19)),
preg(xreg(20)),
preg(xreg(22)),
preg(xreg(23)),
preg(xreg(24)),
preg(xreg(25)),
preg(xreg(26)),
preg(xreg(27)),
preg(xreg(28)),
preg(xreg(PINNED_REG)),
],
&[
preg(vreg(8)),
preg(vreg(9)),
preg(vreg(10)),
preg(vreg(11)),
preg(vreg(12)),
preg(vreg(13)),
preg(vreg(14)),
preg(vreg(15)),
],
// Vector Regclass is unused
&[],
],
fixed_stack_slots: &[],
scratch_by_class: [None, None, None],
}
};
10 changes: 5 additions & 5 deletions cranelift/codegen/src/isa/aarch64/inst/regs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ pub const PINNED_REG: u8 = 21;

/// Get a reference to an X-register (integer register). Do not use
/// this for xsp / xzr; we have two special registers for those.
pub fn xreg(num: u8) -> Reg {
Reg::from(xreg_preg(num))
pub const fn xreg(num: u8) -> Reg {
Reg::from_preg(xreg_preg(num))
}

/// Get the given X-register as a PReg.
Expand All @@ -36,8 +36,8 @@ pub fn writable_xreg(num: u8) -> Writable<Reg> {
}

/// Get a reference to a V-register (vector/FP register).
pub fn vreg(num: u8) -> Reg {
Reg::from(vreg_preg(num))
pub const fn vreg(num: u8) -> Reg {
Reg::from_preg(vreg_preg(num))
}

/// Get the given V-register as a PReg.
Expand Down Expand Up @@ -101,7 +101,7 @@ pub fn writable_link_reg() -> Writable<Reg> {
}

/// Get a reference to the frame pointer (x29).
pub fn fp_reg() -> Reg {
pub const fn fp_reg() -> Reg {
xreg(29)
}

Expand Down
140 changes: 115 additions & 25 deletions cranelift/codegen/src/isa/pulley_shared/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ use crate::{
use alloc::{boxed::Box, vec::Vec};
use core::marker::PhantomData;
use cranelift_bitset::ScalarBitSet;
use regalloc2::{MachineEnv, PReg, PRegSet};
use regalloc2::{MachineEnv, PRegSet};
use smallvec::{smallvec, SmallVec};
use std::borrow::ToOwned;
use std::sync::OnceLock;

/// Support for the Pulley ABI from the callee side (within a function body).
pub(crate) type PulleyCallee<P> = Callee<PulleyMachineDeps<P>>;
Expand Down Expand Up @@ -525,8 +524,7 @@ where
}

fn get_machine_env(_flags: &settings::Flags, _call_conv: isa::CallConv) -> &MachineEnv {
static MACHINE_ENV: OnceLock<MachineEnv> = OnceLock::new();
MACHINE_ENV.get_or_init(create_reg_environment)
&DEFAULT_MACHINE_ENV
}

fn get_regs_clobbered_by_call(_call_conv_of_callee: isa::CallConv) -> PRegSet {
Expand Down Expand Up @@ -913,31 +911,123 @@ const DEFAULT_CLOBBERS: PRegSet = PRegSet::empty()
.with(pv_reg(30))
.with(pv_reg(31));

fn create_reg_environment() -> MachineEnv {
static DEFAULT_MACHINE_ENV: MachineEnv = {
debug_assert!(XReg::SPECIAL_START == 30);
// Prefer caller-saved registers over callee-saved registers, because that
// way we don't need to emit code to save and restore them if we don't
// mutate them.

let preferred_regs_by_class: [Vec<PReg>; 3] = {
let x_registers: Vec<PReg> = (0..16).map(|x| px_reg(x)).collect();
let f_registers: Vec<PReg> = (0..16).map(|x| pf_reg(x)).collect();
let v_registers: Vec<PReg> = (0..32).map(|x| pv_reg(x)).collect();
[x_registers, f_registers, v_registers]
};

let non_preferred_regs_by_class: [Vec<PReg>; 3] = {
let x_registers: Vec<PReg> = (16..XReg::SPECIAL_START)
.map(|x| px_reg(x.into()))
.collect();
let f_registers: Vec<PReg> = (16..32).map(|x| pf_reg(x)).collect();
let v_registers: Vec<PReg> = vec![];
[x_registers, f_registers, v_registers]
};

MachineEnv {
preferred_regs_by_class,
non_preferred_regs_by_class,
fixed_stack_slots: vec![],
preferred_regs_by_class: [
&[
px_reg(0),
px_reg(1),
px_reg(2),
px_reg(3),
px_reg(4),
px_reg(5),
px_reg(6),
px_reg(7),
px_reg(8),
px_reg(9),
px_reg(10),
px_reg(11),
px_reg(12),
px_reg(13),
px_reg(14),
px_reg(15),
],
&[
pf_reg(0),
pf_reg(1),
pf_reg(2),
pf_reg(3),
pf_reg(4),
pf_reg(5),
pf_reg(6),
pf_reg(7),
pf_reg(8),
pf_reg(9),
pf_reg(10),
pf_reg(11),
pf_reg(12),
pf_reg(13),
pf_reg(14),
pf_reg(15),
],
&[
pv_reg(0),
pv_reg(1),
pv_reg(2),
pv_reg(3),
pv_reg(4),
pv_reg(5),
pv_reg(6),
pv_reg(7),
pv_reg(8),
pv_reg(9),
pv_reg(10),
pv_reg(11),
pv_reg(12),
pv_reg(13),
pv_reg(14),
pv_reg(15),
pv_reg(16),
pv_reg(17),
pv_reg(18),
pv_reg(19),
pv_reg(20),
pv_reg(21),
pv_reg(22),
pv_reg(23),
pv_reg(24),
pv_reg(25),
pv_reg(26),
pv_reg(27),
pv_reg(28),
pv_reg(29),
pv_reg(30),
pv_reg(31),
]
],
non_preferred_regs_by_class: [
&[
px_reg(16),
px_reg(17),
px_reg(18),
px_reg(19),
px_reg(20),
px_reg(21),
px_reg(22),
px_reg(23),
px_reg(24),
px_reg(25),
px_reg(26),
px_reg(27),
px_reg(28),
px_reg(29),
],
&[
pf_reg(16),
pf_reg(17),
pf_reg(18),
pf_reg(19),
pf_reg(20),
pf_reg(21),
pf_reg(22),
pf_reg(23),
pf_reg(24),
pf_reg(25),
pf_reg(26),
pf_reg(27),
pf_reg(28),
pf_reg(29),
pf_reg(30),
pf_reg(31),
],
&[]
],
scratch_by_class: [None, None, None],
fixed_stack_slots: &[],
}
}
};
Loading
Loading