Skip to content

Commit 318c69d

Browse files
committed
Reland "[AArch64] Define high bits of FPR and GPR registers (take 2) (#114827)"
The issue with slow compile-time was caused by an assert in AArch64RegisterInfo.cpp. The assert invokes 'checkAllSuperRegsMarked' after adding all the reserved registers. This call gets very expensive after adding the _HI registers due to the way the function searches in the 'Exception' list, which is expected to be a small list but isn't (the patch added 190 _HI regs). It was possible to rewrite the code in such a way that the _HI registers are marked as reserved after the check. This makes the problem go away entirely and restores compile-time to what it was before (tested for `check-runtimes`, which previously showed a ~5x slowdown). This reverts commits: 1434d2a 2704647
1 parent dddeec4 commit 318c69d

25 files changed

+603
-329
lines changed

bolt/unittests/Core/MCPlusBuilder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,15 @@ INSTANTIATE_TEST_SUITE_P(AArch64, MCPlusBuilderTester,
9090
::testing::Values(Triple::aarch64));
9191

9292
TEST_P(MCPlusBuilderTester, AliasX0) {
93-
uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0, AArch64::W0_W1,
93+
uint64_t AliasesX0[] = {AArch64::W0, AArch64::W0_HI,
94+
AArch64::X0, AArch64::W0_W1,
9495
AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7};
9596
size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
9697
testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count);
9798
}
9899

99100
TEST_P(MCPlusBuilderTester, AliasSmallerX0) {
100-
uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0};
101+
uint64_t AliasesX0[] = {AArch64::W0, AArch64::W0_HI, AArch64::X0};
101102
size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
102103
testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count, true);
103104
}

llvm/include/llvm/MC/MCRegisterInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ struct MCRegisterDesc {
129129

130130
// Is true for constant registers.
131131
bool IsConstant;
132+
133+
// Is true for artificial registers.
134+
bool IsArtificial;
132135
};
133136

134137
/// MCRegisterInfo base class - We assume that the target defines a static
@@ -396,6 +399,11 @@ class MCRegisterInfo {
396399
/// Returns true if the given register is constant.
397400
bool isConstant(MCRegister RegNo) const { return get(RegNo).IsConstant; }
398401

402+
/// Returns true if the given register is artificial, which means it
403+
/// represents a regunit that is not separately addressable but still needs to
404+
/// be modelled, such as the top 16-bits of a 32-bit GPR.
405+
bool isArtificial(MCRegister RegNo) const { return get(RegNo).IsArtificial; }
406+
399407
/// Return the number of registers this target has (useful for
400408
/// sizing arrays holding per register information)
401409
unsigned getNumRegs() const {

llvm/lib/MCA/HardwareUnits/RegisterFile.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ namespace mca {
2424

2525
const unsigned WriteRef::INVALID_IID = std::numeric_limits<unsigned>::max();
2626

27+
static std::function<bool(MCPhysReg)>
28+
isNonArtificial(const MCRegisterInfo &MRI) {
29+
return [&MRI](MCPhysReg R) { return !MRI.isArtificial(R); };
30+
}
31+
2732
WriteRef::WriteRef(unsigned SourceIndex, WriteState *WS)
2833
: IID(SourceIndex), WriteBackCycle(), WriteResID(), RegisterID(),
2934
Write(WS) {}
@@ -282,7 +287,8 @@ void RegisterFile::addRegisterWrite(WriteRef Write,
282287
MCPhysReg ZeroRegisterID =
283288
WS.clearsSuperRegisters() ? RegID : WS.getRegisterID();
284289
ZeroRegisters.setBitVal(ZeroRegisterID, IsWriteZero);
285-
for (MCPhysReg I : MRI.subregs(ZeroRegisterID))
290+
for (MCPhysReg I :
291+
make_filter_range(MRI.subregs(ZeroRegisterID), isNonArtificial(MRI)))
286292
ZeroRegisters.setBitVal(I, IsWriteZero);
287293

288294
// If this move has been eliminated, then method tryEliminateMoveOrSwap should
@@ -304,7 +310,8 @@ void RegisterFile::addRegisterWrite(WriteRef Write,
304310
// Update the mapping for register RegID including its sub-registers.
305311
RegisterMappings[RegID].first = Write;
306312
RegisterMappings[RegID].second.AliasRegID = 0U;
307-
for (MCPhysReg I : MRI.subregs(RegID)) {
313+
for (MCPhysReg I :
314+
make_filter_range(MRI.subregs(RegID), isNonArtificial(MRI))) {
308315
RegisterMappings[I].first = Write;
309316
RegisterMappings[I].second.AliasRegID = 0U;
310317
}
@@ -472,7 +479,8 @@ bool RegisterFile::tryEliminateMoveOrSwap(MutableArrayRef<WriteState> Writes,
472479
AliasedReg = RMAlias.AliasRegID;
473480

474481
RegisterMappings[AliasReg].second.AliasRegID = AliasedReg;
475-
for (MCPhysReg I : MRI.subregs(AliasReg))
482+
for (MCPhysReg I :
483+
make_filter_range(MRI.subregs(AliasReg), isNonArtificial(MRI)))
476484
RegisterMappings[I].second.AliasRegID = AliasedReg;
477485

478486
if (ZeroRegisters[RS.getRegisterID()]) {

llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,10 @@ static bool canRenameMOP(const MachineOperand &MOP,
15401540
// Note that this relies on the structure of the AArch64 register file. In
15411541
// particular, a subregister cannot be written without overwriting the
15421542
// whole register.
1543-
if (RegClass->HasDisjunctSubRegs) {
1543+
if (RegClass->HasDisjunctSubRegs && RegClass->CoveredBySubRegs &&
1544+
(TRI->getSubRegisterClass(RegClass, AArch64::dsub0) ||
1545+
TRI->getSubRegisterClass(RegClass, AArch64::qsub0) ||
1546+
TRI->getSubRegisterClass(RegClass, AArch64::zsub0))) {
15441547
LLVM_DEBUG(
15451548
dbgs()
15461549
<< " Cannot rename operands with multiple disjunct subregisters ("

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,13 +490,36 @@ AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
490490
}
491491

492492
assert(checkAllSuperRegsMarked(Reserved));
493+
494+
// Add _HI registers after checkAllSuperRegsMarked as this check otherwise
495+
// becomes considerably more expensive.
496+
Reserved.set(AArch64::WSP_HI);
497+
Reserved.set(AArch64::WZR_HI);
498+
static_assert(AArch64::W30_HI - AArch64::W0_HI == 30,
499+
"Unexpected order of registers");
500+
Reserved.set(AArch64::W0_HI, AArch64::W30_HI);
501+
static_assert(AArch64::B31_HI - AArch64::B0_HI == 31,
502+
"Unexpected order of registers");
503+
Reserved.set(AArch64::B0_HI, AArch64::B31_HI);
504+
static_assert(AArch64::H31_HI - AArch64::H0_HI == 31,
505+
"Unexpected order of registers");
506+
Reserved.set(AArch64::H0_HI, AArch64::H31_HI);
507+
static_assert(AArch64::S31_HI - AArch64::S0_HI == 31,
508+
"Unexpected order of registers");
509+
Reserved.set(AArch64::S0_HI, AArch64::S31_HI);
510+
static_assert(AArch64::D31_HI - AArch64::D0_HI == 31,
511+
"Unexpected order of registers");
512+
Reserved.set(AArch64::D0_HI, AArch64::D31_HI);
513+
static_assert(AArch64::Q31_HI - AArch64::Q0_HI == 31,
514+
"Unexpected order of registers");
515+
Reserved.set(AArch64::Q0_HI, AArch64::Q31_HI);
516+
493517
return Reserved;
494518
}
495519

496520
BitVector
497521
AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
498-
BitVector Reserved = getStrictlyReservedRegs(MF);
499-
522+
BitVector Reserved(getNumRegs());
500523
for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
501524
if (MF.getSubtarget<AArch64Subtarget>().isXRegisterReservedForRA(i))
502525
markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
@@ -514,6 +537,11 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
514537
}
515538

516539
assert(checkAllSuperRegsMarked(Reserved));
540+
541+
// Handle strictlyReservedRegs separately to avoid re-evaluating the assert,
542+
// which becomes considerably expensive when considering the _HI registers.
543+
Reserved |= getStrictlyReservedRegs(MF);
544+
517545
return Reserved;
518546
}
519547

0 commit comments

Comments
 (0)