Skip to content

Commit 3cf4ab5

Browse files
committed
[AArch64] Add an option to reserve physical registers from RA
This patch adds an option --reserve-regs-for-regalloc, so we can reserve a list of physical registers. These registers will not be used by register allocator, but can still be used as ABI requests such as passing arguments to function call. Its main purpose is simulating high register pressure by reserving many physical registers. So it will be much easier to test and debug register allocation changes. Differential Revision: https://reviews.llvm.org/D132717
1 parent 5fab33a commit 3cf4ab5

File tree

5 files changed

+67
-3
lines changed

5 files changed

+67
-3
lines changed

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ const uint32_t *AArch64RegisterInfo::getWindowsStackProbePreservedMask() const {
309309
}
310310

311311
BitVector
312-
AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
312+
AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
313313
const AArch64FrameLowering *TFI = getFrameLowering(MF);
314314

315315
// FIXME: avoid re-calculating this every time.
@@ -355,14 +355,32 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
355355
return Reserved;
356356
}
357357

358+
BitVector
359+
AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
360+
BitVector Reserved = getStrictlyReservedRegs(MF);
361+
362+
for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
363+
if (MF.getSubtarget<AArch64Subtarget>().isXRegisterReservedForRA(i))
364+
markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
365+
}
366+
367+
assert(checkAllSuperRegsMarked(Reserved));
368+
return Reserved;
369+
}
370+
358371
bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
359372
MCRegister Reg) const {
360373
return getReservedRegs(MF)[Reg];
361374
}
362375

376+
bool AArch64RegisterInfo::isStrictlyReservedReg(const MachineFunction &MF,
377+
MCRegister Reg) const {
378+
return getStrictlyReservedRegs(MF)[Reg];
379+
}
380+
363381
bool AArch64RegisterInfo::isAnyArgRegReserved(const MachineFunction &MF) const {
364382
return llvm::any_of(*AArch64::GPR64argRegClass.MC, [this, &MF](MCPhysReg r) {
365-
return isReservedReg(MF, r);
383+
return isStrictlyReservedReg(MF, r);
366384
});
367385
}
368386

llvm/lib/Target/AArch64/AArch64RegisterInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
3535
}
3636

3737
bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const;
38+
bool isStrictlyReservedReg(const MachineFunction &MF, MCRegister Reg) const;
3839
bool isAnyArgRegReserved(const MachineFunction &MF) const;
3940
void emitReservedArgRegCallError(const MachineFunction &MF) const;
4041

@@ -88,6 +89,7 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
8889
/// Stack probing calls preserve different CSRs to the normal CC.
8990
const uint32_t *getWindowsStackProbePreservedMask() const;
9091

92+
BitVector getStrictlyReservedRegs(const MachineFunction &MF) const;
9193
BitVector getReservedRegs(const MachineFunction &MF) const override;
9294
bool isAsmClobberable(const MachineFunction &MF,
9395
MCRegister PhysReg) const override;

llvm/lib/Target/AArch64/AArch64Subtarget.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ static cl::opt<unsigned> OverrideVectorInsertExtractBaseCost(
5656
"aarch64-insert-extract-base-cost",
5757
cl::desc("Base cost of vector insert/extract element"), cl::Hidden);
5858

59+
// Reserve a list of X# registers, so they are unavailable for register
60+
// allocator, but can still be used as ABI requests, such as passing arguments
61+
// to function call.
62+
static cl::list<std::string>
63+
ReservedRegsForRA("reserve-regs-for-regalloc", cl::desc("Reserve physical "
64+
"registers, so they can't be used by register allocator. "
65+
"Should only be used for testing register allocator."),
66+
cl::CommaSeparated, cl::Hidden);
67+
5968
unsigned AArch64Subtarget::getVectorInsertExtractBaseCost() const {
6069
if (OverrideVectorInsertExtractBaseCost.getNumOccurrences() > 0)
6170
return OverrideVectorInsertExtractBaseCost;
@@ -265,6 +274,7 @@ AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
265274
unsigned MaxSVEVectorSizeInBitsOverride)
266275
: AArch64GenSubtargetInfo(TT, CPU, TuneCPU, FS),
267276
ReserveXRegister(AArch64::GPR64commonRegClass.getNumRegs()),
277+
ReserveXRegisterForRA(AArch64::GPR64commonRegClass.getNumRegs()),
268278
CustomCallSavedXRegs(AArch64::GPR64commonRegClass.getNumRegs()),
269279
IsLittle(LittleEndian),
270280
MinSVEVectorSizeInBits(MinSVEVectorSizeInBitsOverride),
@@ -287,6 +297,14 @@ AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
287297
*static_cast<const AArch64TargetMachine *>(&TM), *this, *RBI));
288298

289299
RegBankInfo.reset(RBI);
300+
301+
auto TRI = getRegisterInfo();
302+
StringSet<> ReservedRegNames;
303+
ReservedRegNames.insert(ReservedRegsForRA.begin(), ReservedRegsForRA.end());
304+
for (unsigned i = 0; i < 31; ++i) {
305+
if (ReservedRegNames.count(TRI->getName(AArch64::X0 + i)))
306+
ReserveXRegisterForRA.set(i);
307+
}
290308
}
291309

292310
const CallLowering *AArch64Subtarget::getCallLowering() const {

llvm/lib/Target/AArch64/AArch64Subtarget.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
110110
// ReserveXRegister[i] - X#i is not available as a general purpose register.
111111
BitVector ReserveXRegister;
112112

113+
// ReserveXRegisterForRA[i] - X#i is not available for register allocator.
114+
BitVector ReserveXRegisterForRA;
115+
113116
// CustomCallUsedXRegister[i] - X#i call saved.
114117
BitVector CustomCallSavedXRegs;
115118

@@ -196,7 +199,13 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
196199
}
197200

198201
bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
199-
unsigned getNumXRegisterReserved() const { return ReserveXRegister.count(); }
202+
bool isXRegisterReservedForRA(size_t i) const { return ReserveXRegisterForRA[i]; }
203+
unsigned getNumXRegisterReserved() const {
204+
BitVector AllReservedX(AArch64::GPR64commonRegClass.getNumRegs());
205+
AllReservedX |= ReserveXRegister;
206+
AllReservedX |= ReserveXRegisterForRA;
207+
return AllReservedX.count();
208+
}
200209
bool isXRegCustomCalleeSaved(size_t i) const {
201210
return CustomCallSavedXRegs[i];
202211
}

llvm/test/CodeGen/AArch64/arm64-platform-reg.ll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@
1313
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x5 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X5
1414
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x6 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X6
1515
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x7 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X7
16+
; RUN: llc -mtriple=arm64-linux-gnu -reserve-regs-for-regalloc=X8 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X8
1617
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x9 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X9
1718
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x10 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X10
1819
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x11 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X11
1920
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x12 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X12
2021
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x13 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X13
2122
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x14 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X14
2223
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x15 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X15
24+
; RUN: llc -mtriple=arm64-linux-gnu -reserve-regs-for-regalloc=X16 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X16
25+
; RUN: llc -mtriple=arm64-linux-gnu -reserve-regs-for-regalloc=X17 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X17
26+
; RUN: llc -mtriple=arm64-linux-gnu -reserve-regs-for-regalloc=X19 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X19
2327
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x20 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X20
2428
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x21 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X21
2529
; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x22 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X22
@@ -69,6 +73,7 @@
6973
; RUN: -mattr=+reserve-x27 \
7074
; RUN: -mattr=+reserve-x28 \
7175
; RUN: -mattr=+reserve-x30 \
76+
; RUN: -reserve-regs-for-regalloc=X8,X16,X17,X19 \
7277
; RUN: -o - %s | FileCheck %s \
7378
; RUN: --check-prefix=CHECK-RESERVE \
7479
; RUN: --check-prefix=CHECK-RESERVE-X1 \
@@ -78,14 +83,18 @@
7883
; RUN: --check-prefix=CHECK-RESERVE-X5 \
7984
; RUN: --check-prefix=CHECK-RESERVE-X6 \
8085
; RUN: --check-prefix=CHECK-RESERVE-X7 \
86+
; RUN: --check-prefix=CHECK-RESERVE-X8 \
8187
; RUN: --check-prefix=CHECK-RESERVE-X9 \
8288
; RUN: --check-prefix=CHECK-RESERVE-X10 \
8389
; RUN: --check-prefix=CHECK-RESERVE-X11 \
8490
; RUN: --check-prefix=CHECK-RESERVE-X12 \
8591
; RUN: --check-prefix=CHECK-RESERVE-X13 \
8692
; RUN: --check-prefix=CHECK-RESERVE-X14 \
8793
; RUN: --check-prefix=CHECK-RESERVE-X15 \
94+
; RUN: --check-prefix=CHECK-RESERVE-X16 \
95+
; RUN: --check-prefix=CHECK-RESERVE-X17 \
8896
; RUN: --check-prefix=CHECK-RESERVE-X18 \
97+
; RUN: --check-prefix=CHECK-RESERVE-X19 \
8998
; RUN: --check-prefix=CHECK-RESERVE-X20 \
9099
; RUN: --check-prefix=CHECK-RESERVE-X21 \
91100
; RUN: --check-prefix=CHECK-RESERVE-X22 \
@@ -113,6 +122,8 @@ define void @keep_live() {
113122
; CHECK: str x18
114123

115124
; CHECK-RESERVE-NOT: ldr fp
125+
; CHECK-RESERVE-X8-NOT: adrp x8
126+
; CHECK-RESERVE-X8-NOT: ldr x8
116127
; CHECK-RESERVE-X1-NOT: ldr x1,
117128
; CHECK-RESERVE-X2-NOT: ldr x2,
118129
; CHECK-RESERVE-X3-NOT: ldr x3,
@@ -127,7 +138,10 @@ define void @keep_live() {
127138
; CHECK-RESERVE-X13-NOT: ldr x13,
128139
; CHECK-RESERVE-X14-NOT: ldr x14,
129140
; CHECK-RESERVE-X15-NOT: ldr x15,
141+
; CHECK-RESERVE-X16-NOT: ldr x16
142+
; CHECK-RESERVE-X17-NOT: ldr x17
130143
; CHECK-RESERVE-X18-NOT: ldr x18
144+
; CHECK-RESERVE-X19-NOT: ldr x19
131145
; CHECK-RESERVE-X20-NOT: ldr x20
132146
; CHECK-RESERVE-X21-NOT: ldr x21
133147
; CHECK-RESERVE-X22-NOT: ldr x22
@@ -154,7 +168,10 @@ define void @keep_live() {
154168
; CHECK-RESERVE-X13-NOT: ldr x13,
155169
; CHECK-RESERVE-X14-NOT: ldr x14,
156170
; CHECK-RESERVE-X15-NOT: ldr x15,
171+
; CHECK-RESERVE-X16-NOT: ldr x16
172+
; CHECK-RESERVE-X17-NOT: ldr x17
157173
; CHECK-RESERVE-X18-NOT: ldr x18
174+
; CHECK-RESERVE-X19-NOT: ldr x19
158175
; CHECK-RESERVE-X20-NOT: ldr x20
159176
; CHECK-RESERVE-X21-NOT: ldr x21
160177
; CHECK-RESERVE-X22-NOT: ldr x22

0 commit comments

Comments
 (0)