1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 13:11:39 +01:00

[AArch64] Support reserving x20 register

Register x20 is a callee-saved register which may be used for other
purposes in certain contexts, for example to hold special variables
within the kernel. This change adds support for reserving this register
both to frontend and backend to make this register usable for these
purposes.

Differential Revision: https://reviews.llvm.org/D46552

llvm-svn: 334531
This commit is contained in:
Petr Hosek 2018-06-12 20:00:50 +00:00
parent 72d5015e27
commit 4239933fa7
5 changed files with 37 additions and 13 deletions

View File

@ -76,6 +76,10 @@ def FeatureReserveX18 : SubtargetFeature<"reserve-x18", "ReserveX18", "true",
"Reserve X18, making it unavailable "
"as a GPR">;
def FeatureReserveX20 : SubtargetFeature<"reserve-x20", "ReserveX20", "true",
"Reserve X20, making it unavailable "
"as a GPR">;
def FeatureUseAA : SubtargetFeature<"use-aa", "UseAA", "true",
"Use alias analysis during codegen">;

View File

@ -4930,9 +4930,13 @@ unsigned AArch64TargetLowering::getRegisterByName(const char* RegName, EVT VT,
.Case("sp", AArch64::SP)
.Case("x18", AArch64::X18)
.Case("w18", AArch64::W18)
.Case("x20", AArch64::X20)
.Case("w20", AArch64::W20)
.Default(0);
if ((Reg == AArch64::X18 || Reg == AArch64::W18) &&
!Subtarget->isX18Reserved())
if (((Reg == AArch64::X18 || Reg == AArch64::W18) &&
!Subtarget->isX18Reserved()) ||
((Reg == AArch64::X20 || Reg == AArch64::W20) &&
!Subtarget->isX20Reserved()))
Reg = 0;
if (Reg)
return Reg;

View File

@ -137,6 +137,9 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
if (MF.getSubtarget<AArch64Subtarget>().isX18Reserved())
markSuperRegs(Reserved, AArch64::W18); // Platform register
if (MF.getSubtarget<AArch64Subtarget>().isX20Reserved())
markSuperRegs(Reserved, AArch64::W20); // Platform register
if (hasBasePointer(MF))
markSuperRegs(Reserved, AArch64::W19);
@ -159,12 +162,15 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
case AArch64::X18:
case AArch64::W18:
return MF.getSubtarget<AArch64Subtarget>().isX18Reserved();
case AArch64::X19:
case AArch64::W19:
return hasBasePointer(MF);
case AArch64::X20:
case AArch64::W20:
return MF.getSubtarget<AArch64Subtarget>().isX20Reserved();
case AArch64::FP:
case AArch64::W29:
return TFI->hasFP(MF) || TT.isOSDarwin();
case AArch64::W19:
case AArch64::X19:
return hasBasePointer(MF);
}
return false;
@ -432,6 +438,8 @@ unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
- (TFI->hasFP(MF) || TT.isOSDarwin()) // FP
- MF.getSubtarget<AArch64Subtarget>()
.isX18Reserved() // X18 reserved as platform register
- MF.getSubtarget<AArch64Subtarget>()
.isX20Reserved() // X20 reserved as platform register
- hasBasePointer(MF); // X19
case AArch64::FPR8RegClassID:
case AArch64::FPR16RegClassID:

View File

@ -131,6 +131,9 @@ protected:
// ReserveX18 - X18 is not available as a general purpose register.
bool ReserveX18;
// ReserveX20 - X20 is not available as a general purpose register.
bool ReserveX20 = false;
bool IsLittle;
/// TargetTriple - What processor and OS we're targeting.
@ -216,6 +219,7 @@ public:
}
bool isX18Reserved() const { return ReserveX18; }
bool isX20Reserved() const { return ReserveX20; }
bool hasFPARMv8() const { return HasFPARMv8; }
bool hasNEON() const { return HasNEON; }
bool hasCrypto() const { return HasCrypto; }

View File

@ -1,8 +1,10 @@
; RUN: llc -mtriple=arm64-apple-ios -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18
; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18
; RUN: llc -mtriple=arm64-apple-ios -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18
; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18
; RUN: llc -mtriple=aarch64-fuchsia -mattr=+reserve-x20 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X20
; RUN: llc -mtriple=aarch64-fuchsia -mattr=+reserve-x18,+reserve-x20 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 --check-prefix=CHECK-RESERVE-X20
; RUN: llc -mtriple=arm64-linux-gnu -o - %s | FileCheck %s
; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18
; RUN: llc -mtriple=aarch64-windows -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18
; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18
; RUN: llc -mtriple=aarch64-windows -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18
; x18 is reserved as a platform register on Darwin but not on other
; systems. Create loads of register pressure and make sure this is respected.
@ -19,11 +21,13 @@ define void @keep_live() {
; CHECK: ldr x18
; CHECK: str x18
; CHECK-RESERVE-X18-NOT: ldr fp
; CHECK-RESERVE-NOT: ldr fp
; CHECK-RESERVE-X18-NOT: ldr x18
; CHECK-RESERVE-X18: Spill
; CHECK-RESERVE-X18-NOT: ldr fp
; CHECK-RESERVE-X20-NOT: ldr x20
; CHECK-RESERVE: Spill
; CHECK-RESERVE-NOT: ldr fp
; CHECK-RESERVE-X18-NOT: ldr x18
; CHECK-RESERVE-X18: ret
; CHECK-RESERVE-X20-NOT: ldr x20
; CHECK-RESERVE: ret
ret void
}