[llvm] [GISel][TableGen] Generate getRegBankFromRegClass (PR #99896)

Kai Nacke via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 24 12:49:02 PDT 2024


https://github.com/redstar updated https://github.com/llvm/llvm-project/pull/99896

>From a6dc08eab1328ec698b3eddecc939c736c1f4efb Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 22 Jul 2024 11:46:43 -0400
Subject: [PATCH 01/10] [GISel][TableGen] Generate getRegBankFromRegClass

Generating the mapping from a register class to a register bank
is complex:
 - there can be lots of register classes
 - the mapping may be ambiguos
    - a register class can span several register banks
      (e.g. a register class containing all registers)
    - the type information is not enough to decide which register
      bank to map to
      (e.g. a register class containing floating point and vector
      registers, and all register can represent a f64 value)

The approach taken here is to encode the register banks in an
array indexed by the ID of the register class. To save space, the
entries are packed into chunks of size 2^n.
---
 .../AArch64/GISel/AArch64RegisterBankInfo.cpp | 49 +----------
 .../AArch64/GISel/AArch64RegisterBankInfo.h   |  2 +-
 llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp   | 38 --------
 llvm/lib/Target/ARM/ARMRegisterBankInfo.h     |  3 -
 .../M68k/GISel/M68kRegisterBankInfo.cpp       |  6 --
 .../Target/M68k/GISel/M68kRegisterBankInfo.h  |  3 -
 llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp | 29 ------
 llvm/lib/Target/Mips/MipsRegisterBankInfo.h   |  3 -
 .../PowerPC/GISel/PPCRegisterBankInfo.cpp     | 20 +----
 .../PowerPC/GISel/PPCRegisterBankInfo.h       |  1 +
 .../RISCV/GISel/RISCVRegisterBankInfo.cpp     | 45 ----------
 .../RISCV/GISel/RISCVRegisterBankInfo.h       |  3 -
 .../Target/SPIRV/SPIRVRegisterBankInfo.cpp    | 12 ---
 llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h |  2 -
 .../Target/X86/GISel/X86RegisterBankInfo.cpp  | 27 ------
 .../Target/X86/GISel/X86RegisterBankInfo.h    |  3 -
 llvm/utils/TableGen/RegisterBankEmitter.cpp   | 88 ++++++++++++++++++-
 17 files changed, 91 insertions(+), 243 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 5616d063f70bc..d4445b0a89654 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -240,57 +240,12 @@ unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
 
 const RegisterBank &
 AArch64RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                                LLT) const {
+                                                LLT Ty) const {
   switch (RC.getID()) {
-  case AArch64::FPR8RegClassID:
-  case AArch64::FPR16RegClassID:
-  case AArch64::FPR16_loRegClassID:
-  case AArch64::FPR32_with_hsub_in_FPR16_loRegClassID:
-  case AArch64::FPR32RegClassID:
-  case AArch64::FPR64RegClassID:
-  case AArch64::FPR128RegClassID:
-  case AArch64::FPR64_loRegClassID:
-  case AArch64::FPR128_loRegClassID:
-  case AArch64::FPR128_0to7RegClassID:
-  case AArch64::DDRegClassID:
-  case AArch64::DDDRegClassID:
-  case AArch64::DDDDRegClassID:
-  case AArch64::QQRegClassID:
-  case AArch64::QQQRegClassID:
-  case AArch64::QQQQRegClassID:
-  case AArch64::ZPRRegClassID:
-  case AArch64::ZPR_3bRegClassID:
-    return getRegBank(AArch64::FPRRegBankID);
-  case AArch64::GPR32commonRegClassID:
-  case AArch64::GPR32RegClassID:
-  case AArch64::GPR32spRegClassID:
-  case AArch64::GPR32sponlyRegClassID:
-  case AArch64::GPR32argRegClassID:
-  case AArch64::GPR32allRegClassID:
-  case AArch64::GPR64commonRegClassID:
-  case AArch64::GPR64RegClassID:
-  case AArch64::GPR64spRegClassID:
   case AArch64::GPR64sponlyRegClassID:
-  case AArch64::GPR64argRegClassID:
-  case AArch64::GPR64allRegClassID:
-  case AArch64::GPR64noipRegClassID:
-  case AArch64::GPR64common_and_GPR64noipRegClassID:
-  case AArch64::GPR64noip_and_tcGPR64RegClassID:
-  case AArch64::tcGPR64RegClassID:
-  case AArch64::tcGPRx16x17RegClassID:
-  case AArch64::tcGPRx17RegClassID:
-  case AArch64::tcGPRnotx16RegClassID:
-  case AArch64::WSeqPairsClassRegClassID:
-  case AArch64::XSeqPairsClassRegClassID:
-  case AArch64::MatrixIndexGPR32_8_11RegClassID:
-  case AArch64::MatrixIndexGPR32_12_15RegClassID:
-  case AArch64::GPR64_with_sub_32_in_MatrixIndexGPR32_8_11RegClassID:
-  case AArch64::GPR64_with_sub_32_in_MatrixIndexGPR32_12_15RegClassID:
     return getRegBank(AArch64::GPRRegBankID);
-  case AArch64::CCRRegClassID:
-    return getRegBank(AArch64::CCRegBankID);
   default:
-    llvm_unreachable("Register class not supported");
+    return AArch64GenRegisterBankInfo::getRegBankFromRegClass(RC, Ty);
   }
 }
 
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h
index 0d89f540650a9..941499b08d05d 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h
@@ -150,7 +150,7 @@ class AArch64RegisterBankInfo final : public AArch64GenRegisterBankInfo {
                     TypeSize Size) const override;
 
   const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT) const override;
+                                             LLT Ty) const override;
 
   InstructionMappings
   getInstrAlternativeMappings(const MachineInstr &MI) const override;
diff --git a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
index 9234881c9407e..447db18b8defa 100644
--- a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
@@ -170,44 +170,6 @@ ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI) {
   llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce);
 }
 
-const RegisterBank &
-ARMRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                            LLT) const {
-  using namespace ARM;
-
-  switch (RC.getID()) {
-  case GPRRegClassID:
-  case GPRwithAPSRRegClassID:
-  case GPRnoipRegClassID:
-  case GPRnopcRegClassID:
-  case GPRnoip_and_GPRnopcRegClassID:
-  case rGPRRegClassID:
-  case GPRspRegClassID:
-  case tcGPRRegClassID:
-  case tcGPRnotr12RegClassID:
-  case tGPRRegClassID:
-  case tGPREvenRegClassID:
-  case tGPROddRegClassID:
-  case tGPR_and_tGPREvenRegClassID:
-  case tGPR_and_tGPROddRegClassID:
-  case tGPREven_and_tcGPRRegClassID:
-  case tGPROdd_and_tcGPRRegClassID:
-  case tGPREven_and_tcGPRnotr12RegClassID:
-    return getRegBank(ARM::GPRRegBankID);
-  case HPRRegClassID:
-  case SPR_8RegClassID:
-  case SPRRegClassID:
-  case DPR_8RegClassID:
-  case DPRRegClassID:
-  case QPRRegClassID:
-    return getRegBank(ARM::FPRRegBankID);
-  default:
-    llvm_unreachable("Unsupported register kind");
-  }
-
-  llvm_unreachable("Switch should handle all register classes");
-}
-
 const RegisterBankInfo::InstructionMapping &
 ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
   auto Opc = MI.getOpcode();
diff --git a/llvm/lib/Target/ARM/ARMRegisterBankInfo.h b/llvm/lib/Target/ARM/ARMRegisterBankInfo.h
index c56134aab38c6..2694174623c5c 100644
--- a/llvm/lib/Target/ARM/ARMRegisterBankInfo.h
+++ b/llvm/lib/Target/ARM/ARMRegisterBankInfo.h
@@ -32,9 +32,6 @@ class ARMRegisterBankInfo final : public ARMGenRegisterBankInfo {
 public:
   ARMRegisterBankInfo(const TargetRegisterInfo &TRI);
 
-  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT) const override;
-
   const InstructionMapping &
   getInstrMapping(const MachineInstr &MI) const override;
 };
diff --git a/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.cpp b/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.cpp
index e7e5bb19c3a07..16d009ab81adc 100644
--- a/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.cpp
+++ b/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.cpp
@@ -58,12 +58,6 @@ const RegisterBankInfo::ValueMapping ValueMappings[] = {
 M68kRegisterBankInfo::M68kRegisterBankInfo(const TargetRegisterInfo &TRI)
     : M68kGenRegisterBankInfo() {}
 
-const RegisterBank &
-M68kRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT) const {
-  return getRegBank(M68k::GPRRegBankID);
-}
-
 const RegisterBankInfo::InstructionMapping &
 M68kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
   auto Opc = MI.getOpcode();
diff --git a/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.h b/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.h
index 493c139f018cd..6122db8b48989 100644
--- a/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.h
+++ b/llvm/lib/Target/M68k/GISel/M68kRegisterBankInfo.h
@@ -35,9 +35,6 @@ class M68kRegisterBankInfo final : public M68kGenRegisterBankInfo {
 public:
   M68kRegisterBankInfo(const TargetRegisterInfo &TRI);
 
-  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT) const override;
-
   const InstructionMapping &
   getInstrMapping(const MachineInstr &MI) const override;
 };
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 62b58cba9f24a..4aecaf18db480 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -75,35 +75,6 @@ using namespace llvm;
 
 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) {}
 
-const RegisterBank &
-MipsRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT) const {
-  using namespace Mips;
-
-  switch (RC.getID()) {
-  case Mips::GPR32RegClassID:
-  case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
-  case Mips::GPRMM16MovePPairFirstRegClassID:
-  case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
-  case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
-  case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
-  case Mips::SP32RegClassID:
-  case Mips::GP32RegClassID:
-    return getRegBank(Mips::GPRBRegBankID);
-  case Mips::FGRCCRegClassID:
-  case Mips::FGR32RegClassID:
-  case Mips::FGR64RegClassID:
-  case Mips::AFGR64RegClassID:
-  case Mips::MSA128BRegClassID:
-  case Mips::MSA128HRegClassID:
-  case Mips::MSA128WRegClassID:
-  case Mips::MSA128DRegClassID:
-    return getRegBank(Mips::FPRBRegBankID);
-  default:
-    llvm_unreachable("Register class not supported");
-  }
-}
-
 // Instructions where use operands are floating point registers.
 // Def operands are general purpose.
 static bool isFloatingPointOpcodeUse(unsigned Opc) {
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
index bc424b93f6056..1e07962fd02b3 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
@@ -32,9 +32,6 @@ class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo {
 public:
   MipsRegisterBankInfo(const TargetRegisterInfo &TRI);
 
-  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT) const override;
-
   const InstructionMapping &
   getInstrMapping(const MachineInstr &MI) const override;
 
diff --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
index 125a49de7b27d..4a004f8960562 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
@@ -34,13 +34,6 @@ const RegisterBank &
 PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
                                             LLT Ty) const {
   switch (RC.getID()) {
-  case PPC::G8RCRegClassID:
-  case PPC::G8RC_NOX0RegClassID:
-  case PPC::G8RC_and_G8RC_NOX0RegClassID:
-  case PPC::GPRCRegClassID:
-  case PPC::GPRC_NOR0RegClassID:
-  case PPC::GPRC_and_GPRC_NOR0RegClassID:
-    return getRegBank(PPC::GPRRegBankID);
   case PPC::VSFRCRegClassID:
   case PPC::SPILLTOVSRRC_and_VSFRCRegClassID:
   case PPC::SPILLTOVSRRC_and_VFRCRegClassID:
@@ -50,19 +43,8 @@ PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
   case PPC::VSSRCRegClassID:
   case PPC::F4RCRegClassID:
     return getRegBank(PPC::FPRRegBankID);
-  case PPC::VSRCRegClassID:
-  case PPC::VRRCRegClassID:
-  case PPC::VRRC_with_sub_64_in_SPILLTOVSRRCRegClassID:
-  case PPC::VSRC_with_sub_64_in_SPILLTOVSRRCRegClassID:
-  case PPC::SPILLTOVSRRCRegClassID:
-  case PPC::VSLRCRegClassID:
-  case PPC::VSLRC_with_sub_64_in_SPILLTOVSRRCRegClassID:
-    return getRegBank(PPC::VECRegBankID);
-  case PPC::CRRCRegClassID:
-  case PPC::CRBITRCRegClassID:
-    return getRegBank(PPC::CRRegBankID);
   default:
-    llvm_unreachable("Unexpected register class");
+    return PPCGenRegisterBankInfo::getRegBankFromRegClass(RC, Ty);
   }
 }
 
diff --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
index 1477fdca917d7..332a34fe022dd 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
@@ -67,6 +67,7 @@ class PPCRegisterBankInfo final : public PPCGenRegisterBankInfo {
 
   const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
                                              LLT Ty) const override;
+
   const InstructionMapping &
   getInstrMapping(const MachineInstr &MI) const override;
 
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index d25e96525399e..43bbc8589e7e2 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -112,51 +112,6 @@ using namespace llvm;
 RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode)
     : RISCVGenRegisterBankInfo(HwMode) {}
 
-const RegisterBank &
-RISCVRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                              LLT Ty) const {
-  switch (RC.getID()) {
-  default:
-    llvm_unreachable("Register class not supported");
-  case RISCV::GPRRegClassID:
-  case RISCV::GPRF16RegClassID:
-  case RISCV::GPRF32RegClassID:
-  case RISCV::GPRNoX0RegClassID:
-  case RISCV::GPRNoX0X2RegClassID:
-  case RISCV::GPRJALRRegClassID:
-  case RISCV::GPRJALRNonX7RegClassID:
-  case RISCV::GPRTCRegClassID:
-  case RISCV::GPRTCNonX7RegClassID:
-  case RISCV::GPRC_and_GPRTCRegClassID:
-  case RISCV::GPRCRegClassID:
-  case RISCV::GPRC_and_SR07RegClassID:
-  case RISCV::SR07RegClassID:
-  case RISCV::SPRegClassID:
-  case RISCV::GPRX0RegClassID:
-    return getRegBank(RISCV::GPRBRegBankID);
-  case RISCV::FPR64RegClassID:
-  case RISCV::FPR16RegClassID:
-  case RISCV::FPR32RegClassID:
-  case RISCV::FPR64CRegClassID:
-  case RISCV::FPR32CRegClassID:
-    return getRegBank(RISCV::FPRBRegBankID);
-  case RISCV::VMRegClassID:
-  case RISCV::VRRegClassID:
-  case RISCV::VRNoV0RegClassID:
-  case RISCV::VRM2RegClassID:
-  case RISCV::VRM2NoV0RegClassID:
-  case RISCV::VRM4RegClassID:
-  case RISCV::VRM4NoV0RegClassID:
-  case RISCV::VMV0RegClassID:
-  case RISCV::VRM2_with_sub_vrm1_0_in_VMV0RegClassID:
-  case RISCV::VRM4_with_sub_vrm1_0_in_VMV0RegClassID:
-  case RISCV::VRM8RegClassID:
-  case RISCV::VRM8NoV0RegClassID:
-  case RISCV::VRM8_with_sub_vrm1_0_in_VMV0RegClassID:
-    return getRegBank(RISCV::VRBRegBankID);
-  }
-}
-
 static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) {
   unsigned Idx;
   switch (Size) {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h
index abd0837395f66..79dddb73a2373 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h
@@ -33,9 +33,6 @@ class RISCVRegisterBankInfo final : public RISCVGenRegisterBankInfo {
 public:
   RISCVRegisterBankInfo(unsigned HwMode);
 
-  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT Ty) const override;
-
   const InstructionMapping &
   getInstrMapping(const MachineInstr &MI) const override;
 
diff --git a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
index ecd99f1840d7e..cc06aded901dc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
@@ -19,15 +19,3 @@
 
 #define GET_TARGET_REGBANK_IMPL
 #include "SPIRVGenRegisterBank.inc"
-
-using namespace llvm;
-
-// This required for .td selection patterns to work or we'd end up with RegClass
-// checks being redundant as all the classes would be mapped to the same bank.
-const RegisterBank &
-SPIRVRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                              LLT Ty) const {
-  if (RC.getID() == SPIRV::TYPERegClassID)
-    return SPIRV::TYPERegBank;
-  return SPIRV::IDRegBank;
-}
diff --git a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h
index 67ddcdefb7ddc..e5c1eb2b1e121 100644
--- a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h
@@ -31,8 +31,6 @@ class SPIRVGenRegisterBankInfo : public RegisterBankInfo {
 // This class provides the information for the target register banks.
 class SPIRVRegisterBankInfo final : public SPIRVGenRegisterBankInfo {
 public:
-  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT Ty) const override;
 };
 } // namespace llvm
 #endif // LLVM_LIB_TARGET_SPIRV_SPIRVREGISTERBANKINFO_H
diff --git a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
index 9e85424e76e62..61633a09d93cf 100644
--- a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
@@ -44,33 +44,6 @@ X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI) {
          "GPRs should hold up to 64-bit");
 }
 
-const RegisterBank &
-X86RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                            LLT) const {
-
-  if (X86::GR8RegClass.hasSubClassEq(&RC) ||
-      X86::GR16RegClass.hasSubClassEq(&RC) ||
-      X86::GR32RegClass.hasSubClassEq(&RC) ||
-      X86::GR64RegClass.hasSubClassEq(&RC) ||
-      X86::LOW32_ADDR_ACCESSRegClass.hasSubClassEq(&RC) ||
-      X86::LOW32_ADDR_ACCESS_RBPRegClass.hasSubClassEq(&RC))
-    return getRegBank(X86::GPRRegBankID);
-
-  if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
-      X86::FR64XRegClass.hasSubClassEq(&RC) ||
-      X86::VR128XRegClass.hasSubClassEq(&RC) ||
-      X86::VR256XRegClass.hasSubClassEq(&RC) ||
-      X86::VR512RegClass.hasSubClassEq(&RC))
-    return getRegBank(X86::VECRRegBankID);
-
-  if (X86::RFP80RegClass.hasSubClassEq(&RC) ||
-      X86::RFP32RegClass.hasSubClassEq(&RC) ||
-      X86::RFP64RegClass.hasSubClassEq(&RC))
-    return getRegBank(X86::PSRRegBankID);
-
-  llvm_unreachable("Unsupported register kind yet.");
-}
-
 // \returns true if a given intrinsic only uses and defines FPRs.
 static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
                           const MachineInstr &MI) {
diff --git a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.h b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.h
index 8f38e717e36b0..f30e9fea1a597 100644
--- a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.h
+++ b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.h
@@ -81,9 +81,6 @@ class X86RegisterBankInfo final : public X86GenRegisterBankInfo {
 public:
   X86RegisterBankInfo(const TargetRegisterInfo &TRI);
 
-  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
-                                             LLT) const override;
-
   InstructionMappings
   getInstrAlternativeMappings(const MachineInstr &MI) const override;
 
diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 5546e727af384..eedc84f27419b 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -16,6 +16,7 @@
 #include "Common/InfoByHwMode.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/TableGenBackend.h"
@@ -151,6 +152,9 @@ void RegisterBankEmitter::emitBaseClassDefinition(
   OS << "private:\n"
      << "  static const RegisterBank *RegBanks[];\n"
      << "  static const unsigned Sizes[];\n\n"
+     << "public:\n"
+     << "  const RegisterBank &getRegBankFromRegClass(const "
+        "TargetRegisterClass &RC, LLT Ty) const override;\n"
      << "protected:\n"
      << "  " << TargetName << "GenRegisterBankInfo(unsigned HwMode = 0);\n"
      << "\n";
@@ -287,8 +291,88 @@ void RegisterBankEmitter::emitBaseClassImplementation(
      << "  for (auto RB : enumerate(RegBanks))\n"
      << "    assert(RB.index() == RB.value()->getID() && \"Index != ID\");\n"
      << "#endif // NDEBUG\n"
-     << "}\n"
-     << "} // end namespace llvm\n";
+     << "}\n";
+
+  uint32_t NoRegBanks = Banks.size();
+  uint32_t BitSize = NextPowerOf2(Log2_32(NoRegBanks));
+  uint32_t ElemsPerWord = 32 / BitSize;
+  uint32_t BitMask = (1 << BitSize) - 1;
+  bool HasAmbigousOrMissingEntry = false;
+  struct Entry {
+    std::string RCIdName;
+    std::string RBIdName;
+  };
+  std::vector<Entry> Entries;
+  for (const auto &Bank : Banks)
+    for (const auto *RC : Bank.register_classes()) {
+      if (RC->EnumValue >= Entries.size())
+        Entries.resize(RC->EnumValue+1);
+      Entry &E = Entries[RC->EnumValue];
+      E.RCIdName = RC->getIdName();
+      if (!E.RBIdName.empty()) {
+        HasAmbigousOrMissingEntry = true;
+        E.RBIdName = "InvalidRegBankID";
+      } else {
+        E.RBIdName = (TargetName + "::" + Bank.getEnumeratorName()).str();
+      }
+    }
+  for (auto &E : Entries) {
+    if (E.RBIdName.empty()) {
+      HasAmbigousOrMissingEntry = true;
+      E.RBIdName = "InvalidRegBankID";
+    }
+  }
+  OS << "const RegisterBank &\n"
+     << TargetName << "GenRegisterBankInfo::getRegBankFromRegClass"
+     << "(const TargetRegisterClass &RC, LLT) const {\n";
+  if (HasAmbigousOrMissingEntry)
+    OS << "  constexpr uint32_t InvalidRegBankID = uint32_t("
+       << TargetName + "::InvalidRegBankID) & " << BitMask << ";\n";
+  unsigned TableSize = Entries.size() / ElemsPerWord + ((Entries.size() % ElemsPerWord) > 0);
+  OS << "  static const uint32_t RegClass2RegBank["
+     << TableSize << "] = {\n";
+  uint32_t Shift = 32 - BitSize;
+  bool First = true;
+  std::string TrailingComment;
+  for (auto &E : Entries) {
+    Shift += BitSize;
+    if (Shift == 32) {
+      Shift = 0;
+      if (First)
+        First = false;
+      else
+        OS << "," << TrailingComment << "\n";
+    } else {
+      OS << " |" << TrailingComment << "\n";
+    }
+    OS << "    ("
+       << (E.RBIdName.empty()
+               ? "InvalidRegBankID"
+               : Twine("uint32_t(").concat(E.RBIdName).concat(")").str())
+       << " << " << Shift << ")";
+    if (!E.RCIdName.empty())
+      TrailingComment = " // " + E.RCIdName;
+    else
+      TrailingComment = "";
+  }
+  OS << TrailingComment << "\n  };\n";
+  OS << "  const unsigned RegClassID = RC.getID();\n";
+  OS << "  if (LLVM_LIKELY(RegClassID < " << Entries.size() << ")) {\n";
+  OS << "    unsigned RegBankID = (RegClass2RegBank[RegClassID / "
+     << ElemsPerWord << "] >> ((RegClassID % " << ElemsPerWord << ") * "
+     << BitSize << ")) & " << BitMask << ";\n";
+  if (HasAmbigousOrMissingEntry)
+    OS << "    if (RegBankID != InvalidRegBankID)\n"
+       << "      return getRegBank(RegBankID);\n";
+  else
+    OS << "    return getRegBank(RegBankID);\n";
+  OS << "  }"
+     << "  llvm_unreachable(llvm::Twine(\"Target needs to handle register "
+        "class ID "
+        "0x\").concat(llvm::Twine::utohexstr(RegClassID)).str().c_str());\n"
+     << "}\n";
+
+  OS << "} // end namespace llvm\n";
 }
 
 void RegisterBankEmitter::run(raw_ostream &OS) {

>From af77038ffb10e779cd78d9c06e71784d88365891 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 22 Jul 2024 13:59:05 -0400
Subject: [PATCH 02/10] Add example output code

---
 llvm/test/TableGen/PPCGenRegisterBank.inc | 176 ++++++++++++++++++++++
 1 file changed, 176 insertions(+)
 create mode 100644 llvm/test/TableGen/PPCGenRegisterBank.inc

diff --git a/llvm/test/TableGen/PPCGenRegisterBank.inc b/llvm/test/TableGen/PPCGenRegisterBank.inc
new file mode 100644
index 0000000000000..57b835202d745
--- /dev/null
+++ b/llvm/test/TableGen/PPCGenRegisterBank.inc
@@ -0,0 +1,176 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|* Register Bank Source Fragments                                             *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifdef GET_REGBANK_DECLARATIONS
+#undef GET_REGBANK_DECLARATIONS
+namespace llvm {
+namespace PPC {
+enum : unsigned {
+  InvalidRegBankID = ~0u,
+  CRRegBankID = 0,
+  FPRRegBankID = 1,
+  GPRRegBankID = 2,
+  VECRegBankID = 3,
+  NumRegisterBanks,
+};
+} // end namespace PPC
+} // end namespace llvm
+#endif // GET_REGBANK_DECLARATIONS
+
+#ifdef GET_TARGET_REGBANK_CLASS
+#undef GET_TARGET_REGBANK_CLASS
+private:
+  static const RegisterBank *RegBanks[];
+  static const unsigned Sizes[];
+
+public:
+  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const override;
+protected:
+  PPCGenRegisterBankInfo(unsigned HwMode = 0);
+
+#endif // GET_TARGET_REGBANK_CLASS
+
+#ifdef GET_TARGET_REGBANK_IMPL
+#undef GET_TARGET_REGBANK_IMPL
+namespace llvm {
+namespace PPC {
+const uint32_t CRRegBankCoverageData[] = {
+    // 0-31
+    (1u << (PPC::CRRCRegClassID - 0)) |
+    (1u << (PPC::CRBITRCRegClassID - 0)) |
+    0,
+    // 32-63
+    0,
+};
+const uint32_t FPRRegBankCoverageData[] = {
+    // 0-31
+    (1u << (PPC::VSSRCRegClassID - 0)) |
+    (1u << (PPC::F4RCRegClassID - 0)) |
+    (1u << (PPC::F8RCRegClassID - 0)) |
+    (1u << (PPC::SPILLTOVSRRC_and_F4RCRegClassID - 0)) |
+    (1u << (PPC::VSFRCRegClassID - 0)) |
+    (1u << (PPC::SPILLTOVSRRC_and_VSFRCRegClassID - 0)) |
+    (1u << (PPC::SPILLTOVSRRC_and_VFRCRegClassID - 0)) |
+    (1u << (PPC::VFRCRegClassID - 0)) |
+    0,
+    // 32-63
+    0,
+};
+const uint32_t GPRRegBankCoverageData[] = {
+    // 0-31
+    (1u << (PPC::G8RCRegClassID - 0)) |
+    (1u << (PPC::GPRCRegClassID - 0)) |
+    (1u << (PPC::G8RC_and_G8RC_NOX0RegClassID - 0)) |
+    (1u << (PPC::GPRC_NOR0RegClassID - 0)) |
+    (1u << (PPC::GPRC_and_GPRC_NOR0RegClassID - 0)) |
+    (1u << (PPC::G8RC_NOX0RegClassID - 0)) |
+    0,
+    // 32-63
+    0,
+};
+const uint32_t VECRegBankCoverageData[] = {
+    // 0-31
+    (1u << (PPC::VSRCRegClassID - 0)) |
+    (1u << (PPC::VSSRCRegClassID - 0)) |
+    (1u << (PPC::VSFRCRegClassID - 0)) |
+    (1u << (PPC::VSRC_with_sub_64_in_SPILLTOVSRRCRegClassID - 0)) |
+    (1u << (PPC::SPILLTOVSRRCRegClassID - 0)) |
+    (1u << (PPC::SPILLTOVSRRC_and_VSFRCRegClassID - 0)) |
+    (1u << (PPC::VRRC_with_sub_64_in_SPILLTOVSRRCRegClassID - 0)) |
+    (1u << (PPC::VFRCRegClassID - 0)) |
+    (1u << (PPC::SPILLTOVSRRC_and_VFRCRegClassID - 0)) |
+    (1u << (PPC::F4RCRegClassID - 0)) |
+    (1u << (PPC::F8RCRegClassID - 0)) |
+    (1u << (PPC::SPILLTOVSRRC_and_F4RCRegClassID - 0)) |
+    (1u << (PPC::VRRCRegClassID - 0)) |
+    (1u << (PPC::VSLRCRegClassID - 0)) |
+    0,
+    // 32-63
+    (1u << (PPC::VSLRC_with_sub_64_in_SPILLTOVSRRCRegClassID - 32)) |
+    0,
+};
+
+constexpr RegisterBank CRRegBank(/* ID */ PPC::CRRegBankID, /* Name */ "CR", /* CoveredRegClasses */ CRRegBankCoverageData, /* NumRegClasses */ 54);
+constexpr RegisterBank FPRRegBank(/* ID */ PPC::FPRRegBankID, /* Name */ "FPR", /* CoveredRegClasses */ FPRRegBankCoverageData, /* NumRegClasses */ 54);
+constexpr RegisterBank GPRRegBank(/* ID */ PPC::GPRRegBankID, /* Name */ "GPR", /* CoveredRegClasses */ GPRRegBankCoverageData, /* NumRegClasses */ 54);
+constexpr RegisterBank VECRegBank(/* ID */ PPC::VECRegBankID, /* Name */ "VEC", /* CoveredRegClasses */ VECRegBankCoverageData, /* NumRegClasses */ 54);
+} // end namespace PPC
+
+const RegisterBank *PPCGenRegisterBankInfo::RegBanks[] = {
+    &PPC::CRRegBank,
+    &PPC::FPRRegBank,
+    &PPC::GPRRegBank,
+    &PPC::VECRegBank,
+};
+
+const unsigned PPCGenRegisterBankInfo::Sizes[] = {
+    // Mode = 0 (Default)
+    32,
+    64,
+    64,
+    128,
+};
+
+PPCGenRegisterBankInfo::PPCGenRegisterBankInfo(unsigned HwMode)
+    : RegisterBankInfo(RegBanks, PPC::NumRegisterBanks, Sizes, HwMode) {
+  // Assert that RegBank indices match their ID's
+#ifndef NDEBUG
+  for (auto RB : enumerate(RegBanks))
+    assert(RB.index() == RB.value()->getID() && "Index != ID");
+#endif // NDEBUG
+}
+const RegisterBank &
+PPCGenRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const {
+  constexpr uint32_t InvalidRegBankID = uint32_t(PPC::InvalidRegBankID) & 15;
+  static const uint32_t RegClass2RegBank[5] = {
+    (uint32_t(InvalidRegBankID) << 0) | // VSSRCRegClassID
+    (uint32_t(PPC::GPRRegBankID) << 4) | // GPRCRegClassID
+    (uint32_t(PPC::GPRRegBankID) << 8) | // GPRC_NOR0RegClassID
+    (uint32_t(PPC::GPRRegBankID) << 12) | // GPRC_and_GPRC_NOR0RegClassID
+    (uint32_t(PPC::CRRegBankID) << 16) | // CRBITRCRegClassID
+    (uint32_t(InvalidRegBankID) << 20) | // F4RCRegClassID
+    (uint32_t(InvalidRegBankID) << 24) |
+    (uint32_t(PPC::CRRegBankID) << 28), // CRRCRegClassID
+    (uint32_t(InvalidRegBankID) << 0) |
+    (uint32_t(InvalidRegBankID) << 4) |
+    (uint32_t(InvalidRegBankID) << 8) |
+    (uint32_t(InvalidRegBankID) << 12) |
+    (uint32_t(PPC::VECRegBankID) << 16) | // SPILLTOVSRRCRegClassID
+    (uint32_t(InvalidRegBankID) << 20) | // VSFRCRegClassID
+    (uint32_t(PPC::GPRRegBankID) << 24) | // G8RCRegClassID
+    (uint32_t(PPC::GPRRegBankID) << 28), // G8RC_NOX0RegClassID
+    (uint32_t(InvalidRegBankID) << 0) | // SPILLTOVSRRC_and_VSFRCRegClassID
+    (uint32_t(PPC::GPRRegBankID) << 4) | // G8RC_and_G8RC_NOX0RegClassID
+    (uint32_t(InvalidRegBankID) << 8) | // F8RCRegClassID
+    (uint32_t(InvalidRegBankID) << 12) |
+    (uint32_t(InvalidRegBankID) << 16) | // VFRCRegClassID
+    (uint32_t(InvalidRegBankID) << 20) |
+    (uint32_t(InvalidRegBankID) << 24) | // SPILLTOVSRRC_and_VFRCRegClassID
+    (uint32_t(InvalidRegBankID) << 28), // SPILLTOVSRRC_and_F4RCRegClassID
+    (uint32_t(InvalidRegBankID) << 0) |
+    (uint32_t(InvalidRegBankID) << 4) |
+    (uint32_t(InvalidRegBankID) << 8) |
+    (uint32_t(PPC::VECRegBankID) << 12) | // VSRCRegClassID
+    (uint32_t(PPC::VECRegBankID) << 16) | // VSRC_with_sub_64_in_SPILLTOVSRRCRegClassID
+    (uint32_t(PPC::VECRegBankID) << 20) | // VRRCRegClassID
+    (uint32_t(PPC::VECRegBankID) << 24) | // VSLRCRegClassID
+    (uint32_t(PPC::VECRegBankID) << 28), // VRRC_with_sub_64_in_SPILLTOVSRRCRegClassID
+    (uint32_t(InvalidRegBankID) << 0) |
+    (uint32_t(InvalidRegBankID) << 4) |
+    (uint32_t(InvalidRegBankID) << 8) |
+    (uint32_t(PPC::VECRegBankID) << 12) // VSLRC_with_sub_64_in_SPILLTOVSRRCRegClassID
+  };
+  const unsigned RegClassID = RC.getID();
+  if (LLVM_LIKELY(RegClassID < 36)) {
+    unsigned RegBankID = (RegClass2RegBank[RegClassID / 8] >> ((RegClassID % 8) * 4)) & 15;
+    if (RegBankID != InvalidRegBankID)
+      return getRegBank(RegBankID);
+  }  llvm_unreachable(llvm::Twine("Target needs to handle register class ID 0x").concat(llvm::Twine::utohexstr(RegClassID)).str().c_str());
+}
+} // end namespace llvm
+#endif // GET_TARGET_REGBANK_IMPL

>From 43b721cb1bab26ccdc82119449bd652ffe0fc97f Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai at redstar.de>
Date: Mon, 22 Jul 2024 14:06:06 -0400
Subject: [PATCH 03/10] Update llvm/utils/TableGen/RegisterBankEmitter.cpp

Use char for single character.

Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
 llvm/utils/TableGen/RegisterBankEmitter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index eedc84f27419b..7b6f173255cc2 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -349,7 +349,7 @@ void RegisterBankEmitter::emitBaseClassImplementation(
        << (E.RBIdName.empty()
                ? "InvalidRegBankID"
                : Twine("uint32_t(").concat(E.RBIdName).concat(")").str())
-       << " << " << Shift << ")";
+       << " << " << Shift << ')';
     if (!E.RCIdName.empty())
       TrailingComment = " // " + E.RCIdName;
     else

>From 53bb980582ca320080ef2db89b52be40361423d8 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai at redstar.de>
Date: Mon, 22 Jul 2024 14:06:30 -0400
Subject: [PATCH 04/10] Update llvm/utils/TableGen/RegisterBankEmitter.cpp

Again use single char instead of string.

Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
 llvm/utils/TableGen/RegisterBankEmitter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 7b6f173255cc2..215b5a09eb746 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -341,7 +341,7 @@ void RegisterBankEmitter::emitBaseClassImplementation(
       if (First)
         First = false;
       else
-        OS << "," << TrailingComment << "\n";
+        OS << ',' << TrailingComment << '\n';
     } else {
       OS << " |" << TrailingComment << "\n";
     }

>From fa78f2259f92af47a68a1849cf773c628601d216 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 22 Jul 2024 14:15:45 -0400
Subject: [PATCH 05/10] Fix formatting.

---
 llvm/utils/TableGen/RegisterBankEmitter.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 215b5a09eb746..4e7aeaa8752c1 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -306,7 +306,7 @@ void RegisterBankEmitter::emitBaseClassImplementation(
   for (const auto &Bank : Banks)
     for (const auto *RC : Bank.register_classes()) {
       if (RC->EnumValue >= Entries.size())
-        Entries.resize(RC->EnumValue+1);
+        Entries.resize(RC->EnumValue + 1);
       Entry &E = Entries[RC->EnumValue];
       E.RCIdName = RC->getIdName();
       if (!E.RBIdName.empty()) {
@@ -328,9 +328,9 @@ void RegisterBankEmitter::emitBaseClassImplementation(
   if (HasAmbigousOrMissingEntry)
     OS << "  constexpr uint32_t InvalidRegBankID = uint32_t("
        << TargetName + "::InvalidRegBankID) & " << BitMask << ";\n";
-  unsigned TableSize = Entries.size() / ElemsPerWord + ((Entries.size() % ElemsPerWord) > 0);
-  OS << "  static const uint32_t RegClass2RegBank["
-     << TableSize << "] = {\n";
+  unsigned TableSize =
+      Entries.size() / ElemsPerWord + ((Entries.size() % ElemsPerWord) > 0);
+  OS << "  static const uint32_t RegClass2RegBank[" << TableSize << "] = {\n";
   uint32_t Shift = 32 - BitSize;
   bool First = true;
   std::string TrailingComment;

>From 785c866b1d806a06df69005ce325a0259890d6cf Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 22 Jul 2024 14:17:48 -0400
Subject: [PATCH 06/10] Fix another instance of char vs. string

---
 llvm/utils/TableGen/RegisterBankEmitter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 4e7aeaa8752c1..8a352b990a9c0 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -343,7 +343,7 @@ void RegisterBankEmitter::emitBaseClassImplementation(
       else
         OS << ',' << TrailingComment << '\n';
     } else {
-      OS << " |" << TrailingComment << "\n";
+      OS << " |" << TrailingComment << '\n';
     }
     OS << "    ("
        << (E.RBIdName.empty()

>From c7185e0bc422a39982961c92947026c04eccb85e Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 23 Jul 2024 09:37:29 -0400
Subject: [PATCH 07/10] Replace code generation example with real test

---
 llvm/test/TableGen/PPCGenRegisterBank.inc   | 176 --------------------
 llvm/test/TableGen/RegBankFromRegClass.td   |  45 +++++
 llvm/utils/TableGen/RegisterBankEmitter.cpp |   2 +-
 3 files changed, 46 insertions(+), 177 deletions(-)
 delete mode 100644 llvm/test/TableGen/PPCGenRegisterBank.inc
 create mode 100644 llvm/test/TableGen/RegBankFromRegClass.td

diff --git a/llvm/test/TableGen/PPCGenRegisterBank.inc b/llvm/test/TableGen/PPCGenRegisterBank.inc
deleted file mode 100644
index 57b835202d745..0000000000000
--- a/llvm/test/TableGen/PPCGenRegisterBank.inc
+++ /dev/null
@@ -1,176 +0,0 @@
-/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
-|*                                                                            *|
-|* Register Bank Source Fragments                                             *|
-|*                                                                            *|
-|* Automatically generated file, do not edit!                                 *|
-|*                                                                            *|
-\*===----------------------------------------------------------------------===*/
-
-#ifdef GET_REGBANK_DECLARATIONS
-#undef GET_REGBANK_DECLARATIONS
-namespace llvm {
-namespace PPC {
-enum : unsigned {
-  InvalidRegBankID = ~0u,
-  CRRegBankID = 0,
-  FPRRegBankID = 1,
-  GPRRegBankID = 2,
-  VECRegBankID = 3,
-  NumRegisterBanks,
-};
-} // end namespace PPC
-} // end namespace llvm
-#endif // GET_REGBANK_DECLARATIONS
-
-#ifdef GET_TARGET_REGBANK_CLASS
-#undef GET_TARGET_REGBANK_CLASS
-private:
-  static const RegisterBank *RegBanks[];
-  static const unsigned Sizes[];
-
-public:
-  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const override;
-protected:
-  PPCGenRegisterBankInfo(unsigned HwMode = 0);
-
-#endif // GET_TARGET_REGBANK_CLASS
-
-#ifdef GET_TARGET_REGBANK_IMPL
-#undef GET_TARGET_REGBANK_IMPL
-namespace llvm {
-namespace PPC {
-const uint32_t CRRegBankCoverageData[] = {
-    // 0-31
-    (1u << (PPC::CRRCRegClassID - 0)) |
-    (1u << (PPC::CRBITRCRegClassID - 0)) |
-    0,
-    // 32-63
-    0,
-};
-const uint32_t FPRRegBankCoverageData[] = {
-    // 0-31
-    (1u << (PPC::VSSRCRegClassID - 0)) |
-    (1u << (PPC::F4RCRegClassID - 0)) |
-    (1u << (PPC::F8RCRegClassID - 0)) |
-    (1u << (PPC::SPILLTOVSRRC_and_F4RCRegClassID - 0)) |
-    (1u << (PPC::VSFRCRegClassID - 0)) |
-    (1u << (PPC::SPILLTOVSRRC_and_VSFRCRegClassID - 0)) |
-    (1u << (PPC::SPILLTOVSRRC_and_VFRCRegClassID - 0)) |
-    (1u << (PPC::VFRCRegClassID - 0)) |
-    0,
-    // 32-63
-    0,
-};
-const uint32_t GPRRegBankCoverageData[] = {
-    // 0-31
-    (1u << (PPC::G8RCRegClassID - 0)) |
-    (1u << (PPC::GPRCRegClassID - 0)) |
-    (1u << (PPC::G8RC_and_G8RC_NOX0RegClassID - 0)) |
-    (1u << (PPC::GPRC_NOR0RegClassID - 0)) |
-    (1u << (PPC::GPRC_and_GPRC_NOR0RegClassID - 0)) |
-    (1u << (PPC::G8RC_NOX0RegClassID - 0)) |
-    0,
-    // 32-63
-    0,
-};
-const uint32_t VECRegBankCoverageData[] = {
-    // 0-31
-    (1u << (PPC::VSRCRegClassID - 0)) |
-    (1u << (PPC::VSSRCRegClassID - 0)) |
-    (1u << (PPC::VSFRCRegClassID - 0)) |
-    (1u << (PPC::VSRC_with_sub_64_in_SPILLTOVSRRCRegClassID - 0)) |
-    (1u << (PPC::SPILLTOVSRRCRegClassID - 0)) |
-    (1u << (PPC::SPILLTOVSRRC_and_VSFRCRegClassID - 0)) |
-    (1u << (PPC::VRRC_with_sub_64_in_SPILLTOVSRRCRegClassID - 0)) |
-    (1u << (PPC::VFRCRegClassID - 0)) |
-    (1u << (PPC::SPILLTOVSRRC_and_VFRCRegClassID - 0)) |
-    (1u << (PPC::F4RCRegClassID - 0)) |
-    (1u << (PPC::F8RCRegClassID - 0)) |
-    (1u << (PPC::SPILLTOVSRRC_and_F4RCRegClassID - 0)) |
-    (1u << (PPC::VRRCRegClassID - 0)) |
-    (1u << (PPC::VSLRCRegClassID - 0)) |
-    0,
-    // 32-63
-    (1u << (PPC::VSLRC_with_sub_64_in_SPILLTOVSRRCRegClassID - 32)) |
-    0,
-};
-
-constexpr RegisterBank CRRegBank(/* ID */ PPC::CRRegBankID, /* Name */ "CR", /* CoveredRegClasses */ CRRegBankCoverageData, /* NumRegClasses */ 54);
-constexpr RegisterBank FPRRegBank(/* ID */ PPC::FPRRegBankID, /* Name */ "FPR", /* CoveredRegClasses */ FPRRegBankCoverageData, /* NumRegClasses */ 54);
-constexpr RegisterBank GPRRegBank(/* ID */ PPC::GPRRegBankID, /* Name */ "GPR", /* CoveredRegClasses */ GPRRegBankCoverageData, /* NumRegClasses */ 54);
-constexpr RegisterBank VECRegBank(/* ID */ PPC::VECRegBankID, /* Name */ "VEC", /* CoveredRegClasses */ VECRegBankCoverageData, /* NumRegClasses */ 54);
-} // end namespace PPC
-
-const RegisterBank *PPCGenRegisterBankInfo::RegBanks[] = {
-    &PPC::CRRegBank,
-    &PPC::FPRRegBank,
-    &PPC::GPRRegBank,
-    &PPC::VECRegBank,
-};
-
-const unsigned PPCGenRegisterBankInfo::Sizes[] = {
-    // Mode = 0 (Default)
-    32,
-    64,
-    64,
-    128,
-};
-
-PPCGenRegisterBankInfo::PPCGenRegisterBankInfo(unsigned HwMode)
-    : RegisterBankInfo(RegBanks, PPC::NumRegisterBanks, Sizes, HwMode) {
-  // Assert that RegBank indices match their ID's
-#ifndef NDEBUG
-  for (auto RB : enumerate(RegBanks))
-    assert(RB.index() == RB.value()->getID() && "Index != ID");
-#endif // NDEBUG
-}
-const RegisterBank &
-PPCGenRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const {
-  constexpr uint32_t InvalidRegBankID = uint32_t(PPC::InvalidRegBankID) & 15;
-  static const uint32_t RegClass2RegBank[5] = {
-    (uint32_t(InvalidRegBankID) << 0) | // VSSRCRegClassID
-    (uint32_t(PPC::GPRRegBankID) << 4) | // GPRCRegClassID
-    (uint32_t(PPC::GPRRegBankID) << 8) | // GPRC_NOR0RegClassID
-    (uint32_t(PPC::GPRRegBankID) << 12) | // GPRC_and_GPRC_NOR0RegClassID
-    (uint32_t(PPC::CRRegBankID) << 16) | // CRBITRCRegClassID
-    (uint32_t(InvalidRegBankID) << 20) | // F4RCRegClassID
-    (uint32_t(InvalidRegBankID) << 24) |
-    (uint32_t(PPC::CRRegBankID) << 28), // CRRCRegClassID
-    (uint32_t(InvalidRegBankID) << 0) |
-    (uint32_t(InvalidRegBankID) << 4) |
-    (uint32_t(InvalidRegBankID) << 8) |
-    (uint32_t(InvalidRegBankID) << 12) |
-    (uint32_t(PPC::VECRegBankID) << 16) | // SPILLTOVSRRCRegClassID
-    (uint32_t(InvalidRegBankID) << 20) | // VSFRCRegClassID
-    (uint32_t(PPC::GPRRegBankID) << 24) | // G8RCRegClassID
-    (uint32_t(PPC::GPRRegBankID) << 28), // G8RC_NOX0RegClassID
-    (uint32_t(InvalidRegBankID) << 0) | // SPILLTOVSRRC_and_VSFRCRegClassID
-    (uint32_t(PPC::GPRRegBankID) << 4) | // G8RC_and_G8RC_NOX0RegClassID
-    (uint32_t(InvalidRegBankID) << 8) | // F8RCRegClassID
-    (uint32_t(InvalidRegBankID) << 12) |
-    (uint32_t(InvalidRegBankID) << 16) | // VFRCRegClassID
-    (uint32_t(InvalidRegBankID) << 20) |
-    (uint32_t(InvalidRegBankID) << 24) | // SPILLTOVSRRC_and_VFRCRegClassID
-    (uint32_t(InvalidRegBankID) << 28), // SPILLTOVSRRC_and_F4RCRegClassID
-    (uint32_t(InvalidRegBankID) << 0) |
-    (uint32_t(InvalidRegBankID) << 4) |
-    (uint32_t(InvalidRegBankID) << 8) |
-    (uint32_t(PPC::VECRegBankID) << 12) | // VSRCRegClassID
-    (uint32_t(PPC::VECRegBankID) << 16) | // VSRC_with_sub_64_in_SPILLTOVSRRCRegClassID
-    (uint32_t(PPC::VECRegBankID) << 20) | // VRRCRegClassID
-    (uint32_t(PPC::VECRegBankID) << 24) | // VSLRCRegClassID
-    (uint32_t(PPC::VECRegBankID) << 28), // VRRC_with_sub_64_in_SPILLTOVSRRCRegClassID
-    (uint32_t(InvalidRegBankID) << 0) |
-    (uint32_t(InvalidRegBankID) << 4) |
-    (uint32_t(InvalidRegBankID) << 8) |
-    (uint32_t(PPC::VECRegBankID) << 12) // VSLRC_with_sub_64_in_SPILLTOVSRRCRegClassID
-  };
-  const unsigned RegClassID = RC.getID();
-  if (LLVM_LIKELY(RegClassID < 36)) {
-    unsigned RegBankID = (RegClass2RegBank[RegClassID / 8] >> ((RegClassID % 8) * 4)) & 15;
-    if (RegBankID != InvalidRegBankID)
-      return getRegBank(RegBankID);
-  }  llvm_unreachable(llvm::Twine("Target needs to handle register class ID 0x").concat(llvm::Twine::utohexstr(RegClassID)).str().c_str());
-}
-} // end namespace llvm
-#endif // GET_TARGET_REGBANK_IMPL
diff --git a/llvm/test/TableGen/RegBankFromRegClass.td b/llvm/test/TableGen/RegBankFromRegClass.td
new file mode 100644
index 0000000000000..072a436035052
--- /dev/null
+++ b/llvm/test/TableGen/RegBankFromRegClass.td
@@ -0,0 +1,45 @@
+// RUN: llvm-tblgen -gen-register-bank -I %p/../../include %s | FileCheck %s
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+def R0 : Register<"r0">;
+def GR : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
+
+def F0 : Register<"f0">;
+def FR : RegisterClass<"MyTarget", [f32], 32, (add F0)>;
+
+def V0 : Register<"V0">;
+def VR : RegisterClass<"MyTarget", [v4i8, f32], 32, (add V0)>;
+
+def AllFloatR : RegisterClass<"MyTarget", [f32], 32, (add F0, V0)>;
+def AnyR : RegisterClass<"MyTarget", [i32, f32, v4i8], 32, (add R0, F0, V0)>;
+
+def GRRegBank : RegisterBank<"GRB", [GR]>;
+def FRRegBank : RegisterBank<"FRB", [FR]>;
+def VRRegBank : RegisterBank<"VRB", [VR]>;
+
+
+// CHECK:      #ifdef GET_TARGET_REGBANK_CLASS
+// CHECK:        const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const override;
+
+// CHECK:      #ifdef GET_TARGET_REGBANK_IMPL
+// CHECK:      const RegisterBank &
+// CHECK-NEXT: MyTargetGenRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const {
+// CHECK-NEXT:   constexpr uint32_t InvalidRegBankID = uint32_t(MyTarget::InvalidRegBankID) & 3;
+// CHECK-NEXT:   static const uint32_t RegClass2RegBank[1] = {
+// CHECK-NEXT:     (uint32_t(InvalidRegBankID) << 0) |
+// CHECK-NEXT:     (uint32_t(InvalidRegBankID) << 2) |
+// CHECK-NEXT:     (uint32_t(MyTarget::FRRegBankID) << 4) | // FRRegClassID
+// CHECK-NEXT:     (uint32_t(MyTarget::GRRegBankID) << 6) | // GRRegClassID
+// CHECK-NEXT:     (uint32_t(MyTarget::VRRegBankID) << 8) // VRRegClassID
+// CHECK-NEXT:   };
+// CHECK-NEXT:   const unsigned RegClassID = RC.getID();
+// CHECK-NEXT:   if (LLVM_LIKELY(RegClassID < 5)) {
+// CHECK-NEXT:     unsigned RegBankID = (RegClass2RegBank[RegClassID / 16] >> ((RegClassID % 16) * 2)) & 3;
+// CHECK-NEXT:     if (RegBankID != InvalidRegBankID)
+// CHECK-NEXT:       return getRegBank(RegBankID);
+// CHECK-NEXT:   }
+// CHECK-NEXT:   llvm_unreachable(llvm::Twine("Target needs to handle register class ID 0x").concat(llvm::Twine::utohexstr(RegClassID)).str().c_str());
+// CHECK-NEXT: }
diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 8a352b990a9c0..062ea242c6ce3 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -366,7 +366,7 @@ void RegisterBankEmitter::emitBaseClassImplementation(
        << "      return getRegBank(RegBankID);\n";
   else
     OS << "    return getRegBank(RegBankID);\n";
-  OS << "  }"
+  OS << "  }\n"
      << "  llvm_unreachable(llvm::Twine(\"Target needs to handle register "
         "class ID "
         "0x\").concat(llvm::Twine::utohexstr(RegClassID)).str().c_str());\n"

>From a9a9a670ccdbea66ce37598d65527695e07d6792 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 24 Jul 2024 12:14:50 -0400
Subject: [PATCH 08/10] Fix compile error in SPIRV

---
 llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
index cc06aded901dc..9e51b71d80a5a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
@@ -12,6 +12,7 @@
 
 #include "SPIRVRegisterBankInfo.h"
 #include "SPIRVRegisterInfo.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/CodeGen/RegisterBank.h"
 
 #define GET_REGINFO_ENUM

>From fb7922ef63c96462795282cd22f11d119065ca90 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 24 Jul 2024 15:24:21 -0400
Subject: [PATCH 09/10] Revert handling of SPIRV

SPIRV maps ANYIDRegClass and ANYRegClass to IDRegBank. This is not handled by the generated code.
Handling only those 2 exceptions is longer than the original code, so keep it.
---
 llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp | 12 ++++++++++++
 llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h   |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
index 9e51b71d80a5a..0ed45466788a0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.cpp
@@ -20,3 +20,15 @@
 
 #define GET_TARGET_REGBANK_IMPL
 #include "SPIRVGenRegisterBank.inc"
+
+using namespace llvm;
+
+// This required for .td selection patterns to work or we'd end up with RegClass
+// checks being redundant as all the classes would be mapped to the same bank.
+const RegisterBank &
+SPIRVRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
+                                              LLT Ty) const {
+  if (RC.getID() == SPIRV::TYPERegClassID)
+    return SPIRV::TYPERegBank;
+  return SPIRV::IDRegBank;
+}
diff --git a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h
index e5c1eb2b1e121..67ddcdefb7ddc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVRegisterBankInfo.h
@@ -31,6 +31,8 @@ class SPIRVGenRegisterBankInfo : public RegisterBankInfo {
 // This class provides the information for the target register banks.
 class SPIRVRegisterBankInfo final : public SPIRVGenRegisterBankInfo {
 public:
+  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
+                                             LLT Ty) const override;
 };
 } // namespace llvm
 #endif // LLVM_LIB_TARGET_SPIRV_SPIRVREGISTERBANKINFO_H

>From 19e54b461ca0db84b6f2dceb2f3c04df90a8b1c1 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 24 Jul 2024 15:48:44 -0400
Subject: [PATCH 10/10] Address reviews comments

---
 llvm/utils/TableGen/RegisterBankEmitter.cpp | 38 ++++++++++++---------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 062ea242c6ce3..6872f16df4724 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -293,8 +293,8 @@ void RegisterBankEmitter::emitBaseClassImplementation(
      << "#endif // NDEBUG\n"
      << "}\n";
 
-  uint32_t NoRegBanks = Banks.size();
-  uint32_t BitSize = NextPowerOf2(Log2_32(NoRegBanks));
+  uint32_t NumRegBanks = Banks.size();
+  uint32_t BitSize = NextPowerOf2(Log2_32(NumRegBanks));
   uint32_t ElemsPerWord = 32 / BitSize;
   uint32_t BitMask = (1 << BitSize) - 1;
   bool HasAmbigousOrMissingEntry = false;
@@ -302,8 +302,8 @@ void RegisterBankEmitter::emitBaseClassImplementation(
     std::string RCIdName;
     std::string RBIdName;
   };
-  std::vector<Entry> Entries;
-  for (const auto &Bank : Banks)
+  SmallVector<Entry, 0> Entries;
+  for (const auto &Bank : Banks) {
     for (const auto *RC : Bank.register_classes()) {
       if (RC->EnumValue >= Entries.size())
         Entries.resize(RC->EnumValue + 1);
@@ -316,6 +316,7 @@ void RegisterBankEmitter::emitBaseClassImplementation(
         E.RBIdName = (TargetName + "::" + Bank.getEnumeratorName()).str();
       }
     }
+  }
   for (auto &E : Entries) {
     if (E.RBIdName.empty()) {
       HasAmbigousOrMissingEntry = true;
@@ -323,11 +324,13 @@ void RegisterBankEmitter::emitBaseClassImplementation(
     }
   }
   OS << "const RegisterBank &\n"
-     << TargetName << "GenRegisterBankInfo::getRegBankFromRegClass"
-     << "(const TargetRegisterClass &RC, LLT) const {\n";
-  if (HasAmbigousOrMissingEntry)
+     << TargetName
+     << "GenRegisterBankInfo::getRegBankFromRegClass"
+        "(const TargetRegisterClass &RC, LLT) const {\n";
+  if (HasAmbigousOrMissingEntry) {
     OS << "  constexpr uint32_t InvalidRegBankID = uint32_t("
        << TargetName + "::InvalidRegBankID) & " << BitMask << ";\n";
+  }
   unsigned TableSize =
       Entries.size() / ElemsPerWord + ((Entries.size() % ElemsPerWord) > 0);
   OS << "  static const uint32_t RegClass2RegBank[" << TableSize << "] = {\n";
@@ -355,22 +358,25 @@ void RegisterBankEmitter::emitBaseClassImplementation(
     else
       TrailingComment = "";
   }
-  OS << TrailingComment << "\n  };\n";
-  OS << "  const unsigned RegClassID = RC.getID();\n";
-  OS << "  if (LLVM_LIKELY(RegClassID < " << Entries.size() << ")) {\n";
-  OS << "    unsigned RegBankID = (RegClass2RegBank[RegClassID / "
+  OS << TrailingComment
+     << "\n  };\n"
+        "  const unsigned RegClassID = RC.getID();\n"
+        "  if (LLVM_LIKELY(RegClassID < "
+     << Entries.size()
+     << ")) {\n"
+        "    unsigned RegBankID = (RegClass2RegBank[RegClassID / "
      << ElemsPerWord << "] >> ((RegClassID % " << ElemsPerWord << ") * "
      << BitSize << ")) & " << BitMask << ";\n";
-  if (HasAmbigousOrMissingEntry)
+  if (HasAmbigousOrMissingEntry) {
     OS << "    if (RegBankID != InvalidRegBankID)\n"
-       << "      return getRegBank(RegBankID);\n";
-  else
+          "      return getRegBank(RegBankID);\n";
+  } else
     OS << "    return getRegBank(RegBankID);\n";
   OS << "  }\n"
-     << "  llvm_unreachable(llvm::Twine(\"Target needs to handle register "
+        "  llvm_unreachable(llvm::Twine(\"Target needs to handle register "
         "class ID "
         "0x\").concat(llvm::Twine::utohexstr(RegClassID)).str().c_str());\n"
-     << "}\n";
+        "}\n";
 
   OS << "} // end namespace llvm\n";
 }



More information about the llvm-commits mailing list