Skip to content

Commit

Permalink
pulley: Remove special registers as candidates from regalloc (#9666)
Browse files Browse the repository at this point in the history
* pulley: Remove special registers as candidates from regalloc

This commit fixes a minor mistake where regalloc was allowed to allocate
"special registers" such as the stack pointer, the frame pointer, etc.
These register shouldn't participate in general-purpose register
allocation, so they're removed from the list of non-preferred registers
when metadata is provided to regalloc2.

* Assert everything before SPECIAL_START is not special
  • Loading branch information
alexcrichton authored Nov 22, 2024
1 parent 21477c7 commit 6767488
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 65 deletions.
4 changes: 3 additions & 1 deletion cranelift/codegen/src/isa/pulley_shared/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,9 @@ fn create_reg_enviroment() -> MachineEnv {
};

let non_preferred_regs_by_class: [Vec<PReg>; 3] = {
let x_registers: Vec<PReg> = (16..32).map(|x| px_reg(x)).collect();
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]
Expand Down
6 changes: 6 additions & 0 deletions cranelift/codegen/src/isa/pulley_shared/inst/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ newtype_of_reg!(XReg, WritableXReg, RegClass::Int);
newtype_of_reg!(FReg, WritableFReg, RegClass::Float);
newtype_of_reg!(VReg, WritableVReg, RegClass::Vector);

impl XReg {
/// Index of the first "special" register, or the end of which registers
/// regalloc is allowed to use.
pub const SPECIAL_START: u8 = pulley_interpreter::regs::XReg::SPECIAL_START;
}

pub use super::super::lower::isle::generated_code::ExtKind;

pub use super::super::lower::isle::generated_code::Amode;
Expand Down
64 changes: 32 additions & 32 deletions cranelift/filetests/filetests/isa/pulley32/call.clif
Original file line number Diff line number Diff line change
Expand Up @@ -307,32 +307,32 @@ block0:
; x29 = xmov x27
; x30 = xconst8 -64
; x27 = xadd32 x27, x30
; store64 sp+56, x16 // flags = notrap aligned
; store64 sp+48, x18 // flags = notrap aligned
; store64 sp+56, x18 // flags = notrap aligned
; store64 sp+48, x20 // flags = notrap aligned
; block0:
; x0 = load_addr OutgoingArg(0)
; call CallInfo { dest: TestCase(%g), uses: [CallArgPair { vreg: p0i, preg: p0i }], defs: [CallRetPair { vreg: Writable { reg: p0i }, preg: p0i }, CallRetPair { vreg: Writable { reg: p1i }, preg: p1i }, CallRetPair { vreg: Writable { reg: p2i }, preg: p2i }, CallRetPair { vreg: Writable { reg: p3i }, preg: p3i }, CallRetPair { vreg: Writable { reg: p4i }, preg: p4i }, CallRetPair { vreg: Writable { reg: p5i }, preg: p5i }, CallRetPair { vreg: Writable { reg: p6i }, preg: p6i }, CallRetPair { vreg: Writable { reg: p7i }, preg: p7i }, CallRetPair { vreg: Writable { reg: p8i }, preg: p8i }, CallRetPair { vreg: Writable { reg: p9i }, preg: p9i }, CallRetPair { vreg: Writable { reg: p10i }, preg: p10i }, CallRetPair { vreg: Writable { reg: p11i }, preg: p11i }, CallRetPair { vreg: Writable { reg: p12i }, preg: p12i }, CallRetPair { vreg: Writable { reg: p13i }, preg: p13i }, CallRetPair { vreg: Writable { reg: p14i }, preg: p14i }, CallRetPair { vreg: Writable { reg: p15i }, preg: p15i }], clobbers: PRegSet { bits: [0, 65279, 4294967295, 0] }, callee_conv: Fast, caller_conv: Fast, callee_pop_size: 0 }
; x16 = xmov x13
; x18 = xmov x11
; x25 = load64_u OutgoingArg(0) // flags = notrap aligned
; x18 = xmov x13
; x20 = xmov x11
; x24 = load64_u OutgoingArg(0) // flags = notrap aligned
; x11 = load64_u OutgoingArg(8) // flags = notrap aligned
; x13 = load64_u OutgoingArg(16) // flags = notrap aligned
; x31 = load64_u OutgoingArg(24) // flags = notrap aligned
; x17 = load64_u OutgoingArg(32) // flags = notrap aligned
; x30 = xadd64 x0, x1
; x29 = xadd64 x2, x3
; x19 = load64_u OutgoingArg(24) // flags = notrap aligned
; x21 = load64_u OutgoingArg(32) // flags = notrap aligned
; x25 = xadd64 x0, x1
; x23 = xadd64 x2, x3
; x5 = xadd64 x4, x5
; x6 = xadd64 x6, x7
; x7 = xadd64 x8, x9
; x0 = xmov x18
; x0 = xmov x20
; x4 = xadd64 x10, x0
; x10 = xmov x16
; x10 = xmov x18
; x8 = xadd64 x12, x10
; x14 = xadd64 x14, x15
; x15 = xadd64 x25, x11
; x15 = xadd64 x24, x11
; x13 = xadd64 x11, x13
; x0 = xadd64 x31, x17
; x1 = xadd64 x30, x29
; x0 = xadd64 x19, x21
; x1 = xadd64 x25, x23
; x2 = xadd64 x5, x6
; x3 = xadd64 x7, x4
; x14 = xadd64 x8, x14
Expand All @@ -344,8 +344,8 @@ block0:
; x14 = xadd64 x0, x14
; x13 = xadd64 x13, x13
; x0 = xadd64 x14, x13
; x16 = load64_u sp+56 // flags = notrap aligned
; x18 = load64_u sp+48 // flags = notrap aligned
; x18 = load64_u sp+56 // flags = notrap aligned
; x20 = load64_u sp+48 // flags = notrap aligned
; x30 = xconst8 64
; x27 = xadd32 x27, x30
; x28 = load64_u sp+8 // flags = notrap aligned
Expand All @@ -362,31 +362,31 @@ block0:
; xmov fp, sp
; xconst8 spilltmp0, -64
; xadd32 sp, sp, spilltmp0
; store64_offset8 sp, 56, x16
; store64_offset8 sp, 48, x18
; store64_offset8 sp, 56, x18
; store64_offset8 sp, 48, x20
; xmov x0, sp
; call 0x0 // target = 0x21
; xmov x16, x13
; xmov x18, x11
; load64 x25, sp
; xmov x18, x13
; xmov x20, x11
; load64 x24, sp
; load64_offset8 x11, sp, 8
; load64_offset8 x13, sp, 16
; load64_offset8 spilltmp1, sp, 24
; load64_offset8 x17, sp, 32
; xadd64 spilltmp0, x0, x1
; xadd64 fp, x2, x3
; load64_offset8 x19, sp, 24
; load64_offset8 x21, sp, 32
; xadd64 x25, x0, x1
; xadd64 x23, x2, x3
; xadd64 x5, x4, x5
; xadd64 x6, x6, x7
; xadd64 x7, x8, x9
; xmov x0, x18
; xmov x0, x20
; xadd64 x4, x10, x0
; xmov x10, x16
; xmov x10, x18
; xadd64 x8, x12, x10
; xadd64 x14, x14, x15
; xadd64 x15, x25, x11
; xadd64 x15, x24, x11
; xadd64 x13, x11, x13
; xadd64 x0, spilltmp1, x17
; xadd64 x1, spilltmp0, fp
; xadd64 x0, x19, x21
; xadd64 x1, x25, x23
; xadd64 x2, x5, x6
; xadd64 x3, x7, x4
; xadd64 x14, x8, x14
Expand All @@ -398,8 +398,8 @@ block0:
; xadd64 x14, x0, x14
; xadd64 x13, x13, x13
; xadd64 x0, x14, x13
; load64_offset8 x16, sp, 56
; load64_offset8 x18, sp, 48
; load64_offset8 x18, sp, 56
; load64_offset8 x20, sp, 48
; xconst8 spilltmp0, 64
; xadd32 sp, sp, spilltmp0
; load64_offset8 lr, sp, 8
Expand Down
64 changes: 32 additions & 32 deletions cranelift/filetests/filetests/isa/pulley64/call.clif
Original file line number Diff line number Diff line change
Expand Up @@ -307,32 +307,32 @@ block0:
; x29 = xmov x27
; x30 = xconst8 -64
; x27 = xadd32 x27, x30
; store64 sp+56, x16 // flags = notrap aligned
; store64 sp+48, x18 // flags = notrap aligned
; store64 sp+56, x18 // flags = notrap aligned
; store64 sp+48, x20 // flags = notrap aligned
; block0:
; x0 = load_addr OutgoingArg(0)
; call CallInfo { dest: TestCase(%g), uses: [CallArgPair { vreg: p0i, preg: p0i }], defs: [CallRetPair { vreg: Writable { reg: p0i }, preg: p0i }, CallRetPair { vreg: Writable { reg: p1i }, preg: p1i }, CallRetPair { vreg: Writable { reg: p2i }, preg: p2i }, CallRetPair { vreg: Writable { reg: p3i }, preg: p3i }, CallRetPair { vreg: Writable { reg: p4i }, preg: p4i }, CallRetPair { vreg: Writable { reg: p5i }, preg: p5i }, CallRetPair { vreg: Writable { reg: p6i }, preg: p6i }, CallRetPair { vreg: Writable { reg: p7i }, preg: p7i }, CallRetPair { vreg: Writable { reg: p8i }, preg: p8i }, CallRetPair { vreg: Writable { reg: p9i }, preg: p9i }, CallRetPair { vreg: Writable { reg: p10i }, preg: p10i }, CallRetPair { vreg: Writable { reg: p11i }, preg: p11i }, CallRetPair { vreg: Writable { reg: p12i }, preg: p12i }, CallRetPair { vreg: Writable { reg: p13i }, preg: p13i }, CallRetPair { vreg: Writable { reg: p14i }, preg: p14i }, CallRetPair { vreg: Writable { reg: p15i }, preg: p15i }], clobbers: PRegSet { bits: [0, 65279, 4294967295, 0] }, callee_conv: Fast, caller_conv: Fast, callee_pop_size: 0 }
; x16 = xmov x13
; x18 = xmov x11
; x25 = load64_u OutgoingArg(0) // flags = notrap aligned
; x18 = xmov x13
; x20 = xmov x11
; x24 = load64_u OutgoingArg(0) // flags = notrap aligned
; x11 = load64_u OutgoingArg(8) // flags = notrap aligned
; x13 = load64_u OutgoingArg(16) // flags = notrap aligned
; x31 = load64_u OutgoingArg(24) // flags = notrap aligned
; x17 = load64_u OutgoingArg(32) // flags = notrap aligned
; x30 = xadd64 x0, x1
; x29 = xadd64 x2, x3
; x19 = load64_u OutgoingArg(24) // flags = notrap aligned
; x21 = load64_u OutgoingArg(32) // flags = notrap aligned
; x25 = xadd64 x0, x1
; x23 = xadd64 x2, x3
; x5 = xadd64 x4, x5
; x6 = xadd64 x6, x7
; x7 = xadd64 x8, x9
; x0 = xmov x18
; x0 = xmov x20
; x4 = xadd64 x10, x0
; x10 = xmov x16
; x10 = xmov x18
; x8 = xadd64 x12, x10
; x14 = xadd64 x14, x15
; x15 = xadd64 x25, x11
; x15 = xadd64 x24, x11
; x13 = xadd64 x11, x13
; x0 = xadd64 x31, x17
; x1 = xadd64 x30, x29
; x0 = xadd64 x19, x21
; x1 = xadd64 x25, x23
; x2 = xadd64 x5, x6
; x3 = xadd64 x7, x4
; x14 = xadd64 x8, x14
Expand All @@ -344,8 +344,8 @@ block0:
; x14 = xadd64 x0, x14
; x13 = xadd64 x13, x13
; x0 = xadd64 x14, x13
; x16 = load64_u sp+56 // flags = notrap aligned
; x18 = load64_u sp+48 // flags = notrap aligned
; x18 = load64_u sp+56 // flags = notrap aligned
; x20 = load64_u sp+48 // flags = notrap aligned
; x30 = xconst8 64
; x27 = xadd32 x27, x30
; x28 = load64_u sp+8 // flags = notrap aligned
Expand All @@ -362,31 +362,31 @@ block0:
; xmov fp, sp
; xconst8 spilltmp0, -64
; xadd32 sp, sp, spilltmp0
; store64_offset8 sp, 56, x16
; store64_offset8 sp, 48, x18
; store64_offset8 sp, 56, x18
; store64_offset8 sp, 48, x20
; xmov x0, sp
; call 0x0 // target = 0x21
; xmov x16, x13
; xmov x18, x11
; load64 x25, sp
; xmov x18, x13
; xmov x20, x11
; load64 x24, sp
; load64_offset8 x11, sp, 8
; load64_offset8 x13, sp, 16
; load64_offset8 spilltmp1, sp, 24
; load64_offset8 x17, sp, 32
; xadd64 spilltmp0, x0, x1
; xadd64 fp, x2, x3
; load64_offset8 x19, sp, 24
; load64_offset8 x21, sp, 32
; xadd64 x25, x0, x1
; xadd64 x23, x2, x3
; xadd64 x5, x4, x5
; xadd64 x6, x6, x7
; xadd64 x7, x8, x9
; xmov x0, x18
; xmov x0, x20
; xadd64 x4, x10, x0
; xmov x10, x16
; xmov x10, x18
; xadd64 x8, x12, x10
; xadd64 x14, x14, x15
; xadd64 x15, x25, x11
; xadd64 x15, x24, x11
; xadd64 x13, x11, x13
; xadd64 x0, spilltmp1, x17
; xadd64 x1, spilltmp0, fp
; xadd64 x0, x19, x21
; xadd64 x1, x25, x23
; xadd64 x2, x5, x6
; xadd64 x3, x7, x4
; xadd64 x14, x8, x14
Expand All @@ -398,8 +398,8 @@ block0:
; xadd64 x14, x0, x14
; xadd64 x13, x13, x13
; xadd64 x0, x14, x13
; load64_offset8 x16, sp, 56
; load64_offset8 x18, sp, 48
; load64_offset8 x18, sp, 56
; load64_offset8 x20, sp, 48
; xconst8 spilltmp0, 64
; xadd32 sp, sp, spilltmp0
; load64_offset8 lr, sp, 8
Expand Down
16 changes: 16 additions & 0 deletions pulley/src/regs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ pub enum XReg {
}

impl XReg {
/// Index of the first "special" register.
pub const SPECIAL_START: u8 = XReg::sp as u8;

/// Is this `x` register a special register?
pub fn is_special(self) -> bool {
matches!(
Expand All @@ -97,6 +100,19 @@ impl XReg {
}
}

#[test]
fn assert_special_start_is_right() {
for i in 0..XReg::SPECIAL_START {
assert!(!XReg::new(i).unwrap().is_special());
}
for i in XReg::SPECIAL_START.. {
match XReg::new(i) {
Some(r) => assert!(r.is_special()),
None => break,
}
}
}

/// An `f` register: floats.
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down

0 comments on commit 6767488

Please sign in to comment.