Skip to content

Commit c1c68ba

Browse files
[AArch64] Define high bits of FPR and GPR registers (take 2) (#114827)
This is a step towards enabling subreg liveness tracking for AArch64, which requires that registers are fully covered by their subregisters, as covered here #109797. There are several changes in this patch: * AArch64RegisterInfo.td and tests: Define the high bits like B0_HI, H0_HI, S0_HI, D0_HI, Q0_HI. Because the bits must be defined by some register class, this added a register class which meant that we had to update 'magic numbers' in several tests. The use of ComposedSubRegIndex helped 'compress' the number of bits required for the lanemask. The correctness of the masks is tested by an explicit unit tests. * LoadStoreOptimizer: previously 'HasDisjunctSubRegs' was only true for register tuples, but with this change to describe the high bits, a register like 'D0' will also have 'HasDisjunctSubRegs' set to true (because it's fullly covered by S0 and S0_HI). The fix here is to explicitly test if the register class is one of the known D/Q/Z tuples.
1 parent e52238b commit c1c68ba

24 files changed

+626
-327
lines changed

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: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,57 @@ AArch64RegisterInfo::explainReservedReg(const MachineFunction &MF,
423423
return {};
424424
}
425425

426+
static const MCPhysReg ReservedHi[] = {
427+
AArch64::B0_HI, AArch64::B1_HI, AArch64::B2_HI, AArch64::B3_HI,
428+
AArch64::B4_HI, AArch64::B5_HI, AArch64::B6_HI, AArch64::B7_HI,
429+
AArch64::B8_HI, AArch64::B9_HI, AArch64::B10_HI, AArch64::B11_HI,
430+
AArch64::B12_HI, AArch64::B13_HI, AArch64::B14_HI, AArch64::B15_HI,
431+
AArch64::B16_HI, AArch64::B17_HI, AArch64::B18_HI, AArch64::B19_HI,
432+
AArch64::B20_HI, AArch64::B21_HI, AArch64::B22_HI, AArch64::B23_HI,
433+
AArch64::B24_HI, AArch64::B25_HI, AArch64::B26_HI, AArch64::B27_HI,
434+
AArch64::B28_HI, AArch64::B29_HI, AArch64::B30_HI, AArch64::B31_HI,
435+
AArch64::H0_HI, AArch64::H1_HI, AArch64::H2_HI, AArch64::H3_HI,
436+
AArch64::H4_HI, AArch64::H5_HI, AArch64::H6_HI, AArch64::H7_HI,
437+
AArch64::H8_HI, AArch64::H9_HI, AArch64::H10_HI, AArch64::H11_HI,
438+
AArch64::H12_HI, AArch64::H13_HI, AArch64::H14_HI, AArch64::H15_HI,
439+
AArch64::H16_HI, AArch64::H17_HI, AArch64::H18_HI, AArch64::H19_HI,
440+
AArch64::H20_HI, AArch64::H21_HI, AArch64::H22_HI, AArch64::H23_HI,
441+
AArch64::H24_HI, AArch64::H25_HI, AArch64::H26_HI, AArch64::H27_HI,
442+
AArch64::H28_HI, AArch64::H29_HI, AArch64::H30_HI, AArch64::H31_HI,
443+
AArch64::S0_HI, AArch64::S1_HI, AArch64::S2_HI, AArch64::S3_HI,
444+
AArch64::S4_HI, AArch64::S5_HI, AArch64::S6_HI, AArch64::S7_HI,
445+
AArch64::S8_HI, AArch64::S9_HI, AArch64::S10_HI, AArch64::S11_HI,
446+
AArch64::S12_HI, AArch64::S13_HI, AArch64::S14_HI, AArch64::S15_HI,
447+
AArch64::S16_HI, AArch64::S17_HI, AArch64::S18_HI, AArch64::S19_HI,
448+
AArch64::S20_HI, AArch64::S21_HI, AArch64::S22_HI, AArch64::S23_HI,
449+
AArch64::S24_HI, AArch64::S25_HI, AArch64::S26_HI, AArch64::S27_HI,
450+
AArch64::S28_HI, AArch64::S29_HI, AArch64::S30_HI, AArch64::S31_HI,
451+
AArch64::D0_HI, AArch64::D1_HI, AArch64::D2_HI, AArch64::D3_HI,
452+
AArch64::D4_HI, AArch64::D5_HI, AArch64::D6_HI, AArch64::D7_HI,
453+
AArch64::D8_HI, AArch64::D9_HI, AArch64::D10_HI, AArch64::D11_HI,
454+
AArch64::D12_HI, AArch64::D13_HI, AArch64::D14_HI, AArch64::D15_HI,
455+
AArch64::D16_HI, AArch64::D17_HI, AArch64::D18_HI, AArch64::D19_HI,
456+
AArch64::D20_HI, AArch64::D21_HI, AArch64::D22_HI, AArch64::D23_HI,
457+
AArch64::D24_HI, AArch64::D25_HI, AArch64::D26_HI, AArch64::D27_HI,
458+
AArch64::D28_HI, AArch64::D29_HI, AArch64::D30_HI, AArch64::D31_HI,
459+
AArch64::Q0_HI, AArch64::Q1_HI, AArch64::Q2_HI, AArch64::Q3_HI,
460+
AArch64::Q4_HI, AArch64::Q5_HI, AArch64::Q6_HI, AArch64::Q7_HI,
461+
AArch64::Q8_HI, AArch64::Q9_HI, AArch64::Q10_HI, AArch64::Q11_HI,
462+
AArch64::Q12_HI, AArch64::Q13_HI, AArch64::Q14_HI, AArch64::Q15_HI,
463+
AArch64::Q16_HI, AArch64::Q17_HI, AArch64::Q18_HI, AArch64::Q19_HI,
464+
AArch64::Q20_HI, AArch64::Q21_HI, AArch64::Q22_HI, AArch64::Q23_HI,
465+
AArch64::Q24_HI, AArch64::Q25_HI, AArch64::Q26_HI, AArch64::Q27_HI,
466+
AArch64::Q28_HI, AArch64::Q29_HI, AArch64::Q30_HI, AArch64::Q31_HI,
467+
AArch64::W0_HI, AArch64::W1_HI, AArch64::W2_HI, AArch64::W3_HI,
468+
AArch64::W4_HI, AArch64::W5_HI, AArch64::W6_HI, AArch64::W7_HI,
469+
AArch64::W8_HI, AArch64::W9_HI, AArch64::W10_HI, AArch64::W11_HI,
470+
AArch64::W12_HI, AArch64::W13_HI, AArch64::W14_HI, AArch64::W15_HI,
471+
AArch64::W16_HI, AArch64::W17_HI, AArch64::W18_HI, AArch64::W19_HI,
472+
AArch64::W20_HI, AArch64::W21_HI, AArch64::W22_HI, AArch64::W23_HI,
473+
AArch64::W24_HI, AArch64::W25_HI, AArch64::W26_HI, AArch64::W27_HI,
474+
AArch64::W28_HI, AArch64::W29_HI, AArch64::W30_HI, AArch64::WSP_HI,
475+
AArch64::WZR_HI};
476+
426477
BitVector
427478
AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
428479
const AArch64FrameLowering *TFI = getFrameLowering(MF);
@@ -489,7 +540,10 @@ AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
489540
markSuperRegs(Reserved, AArch64::W28);
490541
}
491542

492-
assert(checkAllSuperRegsMarked(Reserved));
543+
for (Register R : ReservedHi)
544+
Reserved.set(R);
545+
546+
assert(checkAllSuperRegsMarked(Reserved, ReservedHi));
493547
return Reserved;
494548
}
495549

@@ -513,7 +567,7 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
513567
markSuperRegs(Reserved, AArch64::LR);
514568
}
515569

516-
assert(checkAllSuperRegsMarked(Reserved));
570+
assert(checkAllSuperRegsMarked(Reserved, ReservedHi));
517571
return Reserved;
518572
}
519573

0 commit comments

Comments
 (0)