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

Kai Nacke via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 22 11:06:41 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 1/4] [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 2/4] 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 3/4] 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 4/4] 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";
     }



More information about the llvm-commits mailing list