Skip to content

Commit aa7eace

Browse files
committed
[TableGen][GlobalISel] Account for HwMode in RegisterBank register sizes
This patch adds logic for determining RegisterBank size to RegisterBankInfo, which allows accounting for the HwMode of the target. Individual RegisterBanks cannot be constructed with HwMode information as construction is generated by TableGen, but a RegisterBankInfo subclass can provide the HwMode as a constructor argument. The HwMode is used to select the appropriate RegisterBank size from an array relating sizes to RegisterBanks. Targets simply need to provide the HwMode argument to the <target>GenRegisterBankInfo constructor. The RISC-V RegisterBankInfo constructor has been updated accordingly (plus an unused argument removed). Reviewed By: simoncook, craig.topper Differential Revision: https://reviews.llvm.org/D76007
1 parent e501ed8 commit aa7eace

File tree

12 files changed

+106
-64
lines changed

12 files changed

+106
-64
lines changed

llvm/include/llvm/CodeGen/RegisterBank.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class RegisterBank {
2929
private:
3030
unsigned ID;
3131
const char *Name;
32-
unsigned Size;
3332
BitVector ContainedRegClasses;
3433

3534
/// Sentinel value used to recognize register bank not properly
@@ -40,8 +39,8 @@ class RegisterBank {
4039
friend RegisterBankInfo;
4140

4241
public:
43-
RegisterBank(unsigned ID, const char *Name, unsigned Size,
44-
const uint32_t *CoveredClasses, unsigned NumRegClasses);
42+
RegisterBank(unsigned ID, const char *Name, const uint32_t *CoveredClasses,
43+
unsigned NumRegClasses);
4544

4645
/// Get the identifier of this register bank.
4746
unsigned getID() const { return ID; }
@@ -50,9 +49,6 @@ class RegisterBank {
5049
/// Should be used only for debugging purposes.
5150
const char *getName() const { return Name; }
5251

53-
/// Get the maximal size in bits that fits in this register bank.
54-
unsigned getSize() const { return Size; }
55-
5652
/// Check whether this instance is ready to be used.
5753
bool isValid() const;
5854

@@ -62,7 +58,7 @@ class RegisterBank {
6258
/// \note This method does not check anything when assertions are disabled.
6359
///
6460
/// \return True is the check was successful.
65-
bool verify(const TargetRegisterInfo &TRI) const;
61+
bool verify(const RegisterBankInfo &RBI, const TargetRegisterInfo &TRI) const;
6662

6763
/// Check whether this register bank covers \p RC.
6864
/// In other words, check if this register bank fully covers

llvm/include/llvm/CodeGen/RegisterBankInfo.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ADT/iterator_range.h"
2121
#include "llvm/CodeGen/LowLevelType.h"
2222
#include "llvm/CodeGen/Register.h"
23+
#include "llvm/CodeGen/RegisterBank.h"
2324
#include "llvm/Support/ErrorHandling.h"
2425
#include <cassert>
2526
#include <initializer_list>
@@ -30,7 +31,6 @@ namespace llvm {
3031
class MachineInstr;
3132
class MachineRegisterInfo;
3233
class raw_ostream;
33-
class RegisterBank;
3434
class TargetInstrInfo;
3535
class TargetRegisterClass;
3636
class TargetRegisterInfo;
@@ -83,7 +83,7 @@ class RegisterBankInfo {
8383
/// \note This method does not check anything when assertions are disabled.
8484
///
8585
/// \return True is the check was successful.
86-
bool verify() const;
86+
bool verify(const RegisterBankInfo &RBI) const;
8787
};
8888

8989
/// Helper struct that represents how a value is mapped through
@@ -175,7 +175,7 @@ class RegisterBankInfo {
175175
/// \note This method does not check anything when assertions are disabled.
176176
///
177177
/// \return True is the check was successful.
178-
bool verify(unsigned MeaningfulBitWidth) const;
178+
bool verify(const RegisterBankInfo &RBI, unsigned MeaningfulBitWidth) const;
179179

180180
/// Print this on dbgs() stream.
181181
void dump() const;
@@ -384,11 +384,17 @@ class RegisterBankInfo {
384384

385385
protected:
386386
/// Hold the set of supported register banks.
387-
RegisterBank **RegBanks;
387+
const RegisterBank **RegBanks;
388388

389389
/// Total number of register banks.
390390
unsigned NumRegBanks;
391391

392+
/// Hold the sizes of the register banks for all HwModes.
393+
const unsigned *Sizes;
394+
395+
/// Current HwMode for the target.
396+
unsigned HwMode;
397+
392398
/// Keep dynamically allocated PartialMapping in a separate map.
393399
/// This shouldn't be needed when everything gets TableGen'ed.
394400
mutable DenseMap<unsigned, std::unique_ptr<const PartialMapping>>
@@ -415,7 +421,8 @@ class RegisterBankInfo {
415421

416422
/// Create a RegisterBankInfo that can accommodate up to \p NumRegBanks
417423
/// RegisterBank instances.
418-
RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
424+
RegisterBankInfo(const RegisterBank **RegBanks, unsigned NumRegBanks,
425+
const unsigned *Sizes, unsigned HwMode);
419426

420427
/// This constructor is meaningless.
421428
/// It just provides a default constructor that can be used at link time
@@ -428,7 +435,7 @@ class RegisterBankInfo {
428435
}
429436

430437
/// Get the register bank identified by \p ID.
431-
RegisterBank &getRegBank(unsigned ID) {
438+
const RegisterBank &getRegBank(unsigned ID) {
432439
assert(ID < getNumRegBanks() && "Accessing an unknown register bank");
433440
return *RegBanks[ID];
434441
}
@@ -576,6 +583,11 @@ class RegisterBankInfo {
576583
return const_cast<RegisterBankInfo *>(this)->getRegBank(ID);
577584
}
578585

586+
/// Get the maximum size in bits that fits in the given register bank.
587+
unsigned getMaximumSize(unsigned RegBankID) const {
588+
return Sizes[RegBankID + HwMode * NumRegBanks];
589+
}
590+
579591
/// Get the register bank of \p Reg.
580592
/// If Reg has not been assigned a register, a register class,
581593
/// or a register bank, then this returns nullptr.

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,6 +2174,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
21742174
}
21752175

21762176
const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg);
2177+
const RegisterBankInfo *RBI = MF->getSubtarget().getRegBankInfo();
21772178

21782179
// If we're post-RegBankSelect, the gvreg must have a bank.
21792180
if (!RegBank && isFunctionRegBankSelected) {
@@ -2185,12 +2186,12 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
21852186

21862187
// Make sure the register fits into its register bank if any.
21872188
if (RegBank && Ty.isValid() &&
2188-
RegBank->getSize() < Ty.getSizeInBits()) {
2189+
RBI->getMaximumSize(RegBank->getID()) < Ty.getSizeInBits()) {
21892190
report("Register bank is too small for virtual register", MO,
21902191
MONum);
21912192
errs() << "Register bank " << RegBank->getName() << " too small("
2192-
<< RegBank->getSize() << ") to fit " << Ty.getSizeInBits()
2193-
<< "-bits\n";
2193+
<< RBI->getMaximumSize(RegBank->getID()) << ") to fit "
2194+
<< Ty.getSizeInBits() << "-bits\n";
21942195
return;
21952196
}
21962197
}

llvm/lib/CodeGen/RegisterBank.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "llvm/CodeGen/RegisterBank.h"
1313
#include "llvm/ADT/StringExtras.h"
14+
#include "llvm/CodeGen/RegisterBankInfo.h"
1415
#include "llvm/CodeGen/TargetRegisterInfo.h"
1516
#include "llvm/Config/llvm-config.h"
1617
#include "llvm/Support/Debug.h"
@@ -21,15 +22,16 @@ using namespace llvm;
2122

2223
const unsigned RegisterBank::InvalidID = UINT_MAX;
2324

24-
RegisterBank::RegisterBank(
25-
unsigned ID, const char *Name, unsigned Size,
26-
const uint32_t *CoveredClasses, unsigned NumRegClasses)
27-
: ID(ID), Name(Name), Size(Size) {
25+
RegisterBank::RegisterBank(unsigned ID, const char *Name,
26+
const uint32_t *CoveredClasses,
27+
unsigned NumRegClasses)
28+
: ID(ID), Name(Name) {
2829
ContainedRegClasses.resize(NumRegClasses);
2930
ContainedRegClasses.setBitsInMask(CoveredClasses);
3031
}
3132

32-
bool RegisterBank::verify(const TargetRegisterInfo &TRI) const {
33+
bool RegisterBank::verify(const RegisterBankInfo &RBI,
34+
const TargetRegisterInfo &TRI) const {
3335
assert(isValid() && "Invalid register bank");
3436
for (unsigned RCId = 0, End = TRI.getNumRegClasses(); RCId != End; ++RCId) {
3537
const TargetRegisterClass &RC = *TRI.getRegClass(RCId);
@@ -50,7 +52,7 @@ bool RegisterBank::verify(const TargetRegisterInfo &TRI) const {
5052

5153
// Verify that the Size of the register bank is big enough to cover
5254
// all the register classes it covers.
53-
assert(getSize() >= TRI.getRegSizeInBits(SubRC) &&
55+
assert(RBI.getMaximumSize(getID()) >= TRI.getRegSizeInBits(SubRC) &&
5456
"Size is not big enough for all the subclasses!");
5557
assert(covers(SubRC) && "Not all subclasses are covered");
5658
}
@@ -64,7 +66,7 @@ bool RegisterBank::covers(const TargetRegisterClass &RC) const {
6466
}
6567

6668
bool RegisterBank::isValid() const {
67-
return ID != InvalidID && Name != nullptr && Size != 0 &&
69+
return ID != InvalidID && Name != nullptr &&
6870
// A register bank that does not cover anything is useless.
6971
!ContainedRegClasses.empty();
7072
}
@@ -89,7 +91,7 @@ void RegisterBank::print(raw_ostream &OS, bool IsForDebug,
8991
OS << getName();
9092
if (!IsForDebug)
9193
return;
92-
OS << "(ID:" << getID() << ", Size:" << getSize() << ")\n"
94+
OS << "(ID:" << getID() << ")\n"
9395
<< "isValid:" << isValid() << '\n'
9496
<< "Number of Covered register classes: " << ContainedRegClasses.count()
9597
<< '\n';

llvm/lib/CodeGen/RegisterBankInfo.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,11 @@ const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1;
5252
//------------------------------------------------------------------------------
5353
// RegisterBankInfo implementation.
5454
//------------------------------------------------------------------------------
55-
RegisterBankInfo::RegisterBankInfo(RegisterBank **RegBanks,
56-
unsigned NumRegBanks)
57-
: RegBanks(RegBanks), NumRegBanks(NumRegBanks) {
55+
RegisterBankInfo::RegisterBankInfo(const RegisterBank **RegBanks,
56+
unsigned NumRegBanks, const unsigned *Sizes,
57+
unsigned HwMode)
58+
: RegBanks(RegBanks), NumRegBanks(NumRegBanks), Sizes(Sizes),
59+
HwMode(HwMode) {
5860
#ifndef NDEBUG
5961
for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) {
6062
assert(RegBanks[Idx] != nullptr && "Invalid RegisterBank");
@@ -70,7 +72,7 @@ bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const {
7072
assert(Idx == RegBank.getID() &&
7173
"ID does not match the index in the array");
7274
LLVM_DEBUG(dbgs() << "Verify " << RegBank << '\n');
73-
assert(RegBank.verify(TRI) && "RegBank is invalid");
75+
assert(RegBank.verify(*this, TRI) && "RegBank is invalid");
7476
}
7577
#endif // NDEBUG
7678
return true;
@@ -516,12 +518,14 @@ LLVM_DUMP_METHOD void RegisterBankInfo::PartialMapping::dump() const {
516518
}
517519
#endif
518520

519-
bool RegisterBankInfo::PartialMapping::verify() const {
521+
bool RegisterBankInfo::PartialMapping::verify(
522+
const RegisterBankInfo &RBI) const {
520523
assert(RegBank && "Register bank not set");
521524
assert(Length && "Empty mapping");
522525
assert((StartIdx <= getHighBitIdx()) && "Overflow, switch to APInt?");
523526
// Check if the minimum width fits into RegBank.
524-
assert(RegBank->getSize() >= Length && "Register bank too small for Mask");
527+
assert(RBI.getMaximumSize(RegBank->getID()) >= Length &&
528+
"Register bank too small for Mask");
525529
return true;
526530
}
527531

@@ -546,13 +550,14 @@ bool RegisterBankInfo::ValueMapping::partsAllUniform() const {
546550
return true;
547551
}
548552

549-
bool RegisterBankInfo::ValueMapping::verify(unsigned MeaningfulBitWidth) const {
553+
bool RegisterBankInfo::ValueMapping::verify(const RegisterBankInfo &RBI,
554+
unsigned MeaningfulBitWidth) const {
550555
assert(NumBreakDowns && "Value mapped nowhere?!");
551556
unsigned OrigValueBitWidth = 0;
552557
for (const RegisterBankInfo::PartialMapping &PartMap : *this) {
553558
// Check that each register bank is big enough to hold the partial value:
554559
// this check is done by PartialMapping::verify
555-
assert(PartMap.verify() && "Partial mapping is invalid");
560+
assert(PartMap.verify(RBI) && "Partial mapping is invalid");
556561
// The original value should completely be mapped.
557562
// Thus the maximum accessed index + 1 is the size of the original value.
558563
OrigValueBitWidth =
@@ -626,8 +631,9 @@ bool RegisterBankInfo::InstructionMapping::verify(
626631
(void)MOMapping;
627632
// Register size in bits.
628633
// This size must match what the mapping expects.
629-
assert(MOMapping.verify(RBI->getSizeInBits(
630-
Reg, MF.getRegInfo(), *MF.getSubtarget().getRegisterInfo())) &&
634+
assert(MOMapping.verify(*RBI, RBI->getSizeInBits(
635+
Reg, MF.getRegInfo(),
636+
*MF.getSubtarget().getRegisterInfo())) &&
631637
"Value mapping is invalid");
632638
}
633639
return true;

llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,22 @@ AArch64RegisterBankInfo::AArch64RegisterBankInfo(
7171
// GR64all + its subclasses.
7272
assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
7373
"Subclass not added?");
74-
assert(RBGPR.getSize() == 128 && "GPRs should hold up to 128-bit");
74+
assert(getMaximumSize(RBGPR.getID()) == 128 &&
75+
"GPRs should hold up to 128-bit");
7576

7677
// The FPR register bank is fully defined by all the registers in
7778
// GR64all + its subclasses.
7879
assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
7980
"Subclass not added?");
8081
assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
8182
"Subclass not added?");
82-
assert(RBFPR.getSize() == 512 &&
83+
assert(getMaximumSize(RBFPR.getID()) == 512 &&
8384
"FPRs should hold up to 512-bit via QQQQ sequence");
8485

8586
assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
8687
"Class not added?");
87-
assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
88+
assert(getMaximumSize(RBCCR.getID()) == 32 &&
89+
"CCR should hold up to 32-bit");
8890

8991
// Check that the TableGen'ed like file is in sync we our expectations.
9092
// First, the Idx.

llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI) {
162162
"Subclass not added?");
163163
assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPROdd_and_tcGPRRegClassID)) &&
164164
"Subclass not added?");
165-
assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit");
165+
assert(getMaximumSize(RBGPR.getID()) == 32 &&
166+
"GPRs should hold up to 32-bit");
166167

167168
#ifndef NDEBUG
168169
ARM::checkPartialMappings();

llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@
2222

2323
using namespace llvm;
2424

25-
RISCVRegisterBankInfo::RISCVRegisterBankInfo(const TargetRegisterInfo &TRI) {}
25+
RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode)
26+
: RISCVGenRegisterBankInfo(HwMode) {}

llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class RISCVGenRegisterBankInfo : public RegisterBankInfo {
3131
/// This class provides the information for the target register banks.
3232
class RISCVRegisterBankInfo final : public RISCVGenRegisterBankInfo {
3333
public:
34-
RISCVRegisterBankInfo(const TargetRegisterInfo &TRI);
34+
RISCVRegisterBankInfo(unsigned HwMode);
3535
};
3636
} // end namespace llvm
3737
#endif

llvm/lib/Target/RISCV/RISCVSubtarget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
8686
CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
8787
Legalizer.reset(new RISCVLegalizerInfo(*this));
8888

89-
auto *RBI = new RISCVRegisterBankInfo(*getRegisterInfo());
89+
auto *RBI = new RISCVRegisterBankInfo(getHwMode());
9090
RegBankInfo.reset(RBI);
9191
InstSelector.reset(createRISCVInstructionSelector(
9292
*static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));

llvm/lib/Target/X86/X86RegisterBankInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI) {
3636
// GR64 + its subclasses.
3737
assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
3838
"Subclass not added?");
39-
assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
39+
assert(getMaximumSize(RBGPR.getID()) == 64 &&
40+
"GPRs should hold up to 64-bit");
4041
}
4142

4243
const RegisterBank &

0 commit comments

Comments
 (0)