https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/212357

>From c380e0767688ad89a684dfa32bfb7b97fc678ea8 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <[email protected]>
Date: Sun, 26 Jul 2026 23:04:40 +0200
Subject: [PATCH] AMDGPU: Handle more TargetParser queries in tablegen

Previously we had various enum switches. Start generated tables
indexed by enums. Avoid some special cases by defining the dummy
"generic" and "generic-hsa" targets as real processors.

Co-authored-by: Claude (Claude-Opus-4.8)
---
 clang/lib/Basic/Targets/AMDGPU.cpp            |   7 +-
 .../llvm/TargetParser/AMDGPUTargetParser.h    |   6 +-
 llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td  |   4 +
 llvm/lib/Target/AMDGPU/GCNProcessors.td       |  11 +-
 .../MCTargetDesc/AMDGPUTargetStreamer.cpp     |   2 +
 llvm/lib/TargetParser/AMDGPUTargetParser.cpp  | 144 ++++++++----------
 .../test/CodeGen/AMDGPU/hsa-default-device.ll |   2 +-
 llvm/test/TableGen/AMDGPUTargetDefErrors.td   |   1 +
 .../TableGen/Basic/AMDGPUTargetDefEmitter.cpp | 117 ++++++++++----
 9 files changed, 168 insertions(+), 126 deletions(-)

diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp 
b/clang/lib/Basic/Targets/AMDGPU.cpp
index 370ef52a9bdb0..1d74fcc3428b4 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -291,12 +291,9 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions 
&Opts,
       (getTriple().isAMDGCN() ? getArchNameAMDGCN(GPUKind)
                               : getArchNameR600(GPUKind));
 
-  // Sanitize the name of generic targets.
+  // Sanitize the name of generic targets, the only names containing '-'.
   // e.g. gfx10-1-generic -> gfx10_1_generic
-  if (GPUKind >= llvm::AMDGPU::GK_AMDGPU_GENERIC_FIRST &&
-      GPUKind <= llvm::AMDGPU::GK_AMDGPU_GENERIC_LAST) {
-    llvm::replace(CanonName, '-', '_');
-  }
+  llvm::replace(CanonName, '-', '_');
 
   Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__"));
   // Emit macros for gfx family e.g. gfx906 -> __GFX9__, gfx1030 -> __GFX10___
diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h 
b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
index fe2e89fa0daf0..f9df364490106 100644
--- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
+++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
@@ -37,11 +37,9 @@ enum GPUKind : uint32_t {
 
 #define R600_GPU(NAME, ENUM, FEATURES) ENUM,
 #include "llvm/TargetParser/R600TargetParserDef.inc"
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) ENUM,
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
 
-  GK_AMDGPU_GENERIC_FIRST = GK_GFX9_GENERIC,
-  GK_AMDGPU_GENERIC_LAST = GK_GFX13_GENERIC,
+#define AMDGPU_GPU(NAME, ENUM) ENUM,
+#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
 };
 
 /// Instruction set architecture version.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td 
b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
index 396804468877e..40ad681de576e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
@@ -43,6 +43,10 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   // should be used for a "gfxN-generic" targets only, and empty for
   // individual GPUs.
   list<Processor> CoveredGPUs = [];
+
+  // A pseudo target ("generic"/"generic-hsa") that represents no
+  // hardware.
+  bit IsPseudoTarget = false;
 }
 
 // An R600 processor that is also a canonical TargetParser GPU.
diff --git a/llvm/lib/Target/AMDGPU/GCNProcessors.td 
b/llvm/lib/Target/AMDGPU/GCNProcessors.td
index b5e648d277fe5..f6f72be108f05 100644
--- a/llvm/lib/Target/AMDGPU/GCNProcessors.td
+++ b/llvm/lib/Target/AMDGPU/GCNProcessors.td
@@ -19,11 +19,14 @@ defvar ArchFeaturesW32Wgp = [FEATURE_FAST_FMA_F32, 
FEATURE_FAST_DENORMAL_F32,
 
 // The code produced for "generic" is only useful for tests and cannot
 // be expected to execute on any target.
-def : ProcessorModel<"generic", NoSchedModel, []>;
+def : AMDGPUProcessorModel<"generic", NoSchedModel, [], [6, 0, 0]> {
+  let IsPseudoTarget = true;
+}
 
-def : ProcessorModel<"generic-hsa", NoSchedModel,
-  [FeatureFlatAddressSpace]
->;
+def : AMDGPUProcessorModel<"generic-hsa", NoSchedModel,
+  [FeatureFlatAddressSpace], [7, 0, 0]> {
+  let IsPseudoTarget = true;
+}
 
 //===------------------------------------------------------------===//
 // GCN GFX6 (Southern Islands (SI)).
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp 
b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index ea752e44b7fad..463387f064ef0 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -239,6 +239,8 @@ unsigned AMDGPUTargetStreamer::getElfMach(StringRef GPU) {
   case GK_GFX12_GENERIC:    return ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC;
   case GK_GFX12_5_GENERIC:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_5_GENERIC;
   case GK_GFX13_GENERIC:    return ELF::EF_AMDGPU_MACH_AMDGCN_GFX13_GENERIC;
+  case GK_GENERIC:
+  case GK_GENERIC_HSA:
   case GK_NONE:    return ELF::EF_AMDGPU_MACH_NONE;
   }
   // clang-format on
diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp 
b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index a1e7a12e55d85..6f76e01fb6ec0 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -18,43 +18,68 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
+#include <array>
 
 using namespace llvm;
 using namespace AMDGPU;
 
-StringRef llvm::AMDGPU::getArchFamilyNameAMDGCN(GPUKind AK) {
-  StringRef ArchName = getArchNameAMDGCN(AK);
-  assert((AK >= GK_AMDGPU_GENERIC_FIRST && AK <= GK_AMDGPU_GENERIC_LAST) ==
-             ArchName.ends_with("-generic") &&
-         "Generic AMDGCN arch not classified correctly!");
-  if (AK >= GK_AMDGPU_GENERIC_FIRST && AK <= GK_AMDGPU_GENERIC_LAST) {
-    // Return the part before the first '-', e.g. "gfx9-4-generic" -> "gfx9".
-    return ArchName.take_front(ArchName.find('-'));
+namespace {
+// Per-GPU data for the AMDGCN GPUKinds, from the generated table below.
+struct GPUInfo {
+  StringRef Name;
+  Triple::SubArchType SubArch;
+  unsigned ArchFeatures;
+  IsaVersion Version;
+  StringRef FamilyName;
+};
+
+#define GET_AMDGPU_GPU_TABLE
+#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
+
+// Look up the GPUInfo row for an AMDGCN GPUKind, or nullptr for GK_NONE / a
+// non-AMDGCN (R600) kind.
+const GPUInfo *getAMDGPUInfo(GPUKind AK) {
+  if (AK < AMDGPUFirstGPUKind)
+    return nullptr;
+  unsigned Idx = AK - AMDGPUFirstGPUKind;
+  if (Idx >= std::size(AMDGPUGPUTable))
+    return nullptr;
+  return &AMDGPUGPUTable[Idx];
+}
+
+// Reverse map: SubArch -> GPUKind, indexed by (SubArch - FirstAMDGPUSubArch).
+// Subarches with no GPU (incl. the NoSubArch pseudo targets) map to GK_NONE.
+constexpr auto AMDGPUSubArchToGPUKind = [] {
+  constexpr unsigned N =
+      Triple::LastAMDGPUSubArch - Triple::FirstAMDGPUSubArch + 1;
+  std::array<GPUKind, N> Map{}; // value-initialized to GK_NONE (== 0)
+  for (unsigned I = 0; I < std::size(AMDGPUGPUTable); ++I) {
+    Triple::SubArchType SubArch = AMDGPUGPUTable[I].SubArch;
+    if (SubArch != Triple::NoSubArch) {
+      Map[SubArch - Triple::FirstAMDGPUSubArch] =
+          static_cast<GPUKind>(AMDGPUFirstGPUKind + I);
+    }
   }
-  return ArchName.empty() ? "" : ArchName.drop_back(2);
+  return Map;
+}();
+} // namespace
+
+StringRef llvm::AMDGPU::getArchFamilyNameAMDGCN(GPUKind AK) {
+  const GPUInfo *Info = getAMDGPUInfo(AK);
+  return Info ? Info->FamilyName : "";
 }
 
 Triple::SubArchType llvm::AMDGPU::getSubArch(GPUKind AK) {
-  switch (AK) {
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  case ENUM:                                                                   
\
-    return SUBARCH;
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-  default:
-    return Triple::SubArchType::NoSubArch;
-  }
+  const GPUInfo *Info = getAMDGPUInfo(AK);
+  return Info ? Info->SubArch : Triple::SubArchType::NoSubArch;
 }
 
 AMDGPU::GPUKind
 llvm::AMDGPU::getGPUKindFromSubArch(Triple::SubArchType SubArch) {
-  switch (SubArch) {
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  case SUBARCH:                                                                
\
-    return ENUM;
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-  default:
+  if (SubArch < Triple::FirstAMDGPUSubArch ||
+      SubArch > Triple::LastAMDGPUSubArch)
     return GK_NONE;
-  }
+  return AMDGPUSubArchToGPUKind[SubArch - Triple::FirstAMDGPUSubArch];
 }
 
 static const Triple::SubArchType
@@ -185,14 +210,8 @@ std::string AMDGPU::mergeSubArch(const Triple &A, const 
Triple &B) {
 }
 
 StringRef llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK) {
-  switch (AK) {
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  case ENUM:                                                                   
\
-    return NAME;
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-  default:
-    return "";
-  }
+  const GPUInfo *Info = getAMDGPUInfo(AK);
+  return Info ? Info->Name : "";
 }
 
 // Canonical GPU name for each AMDGPU subarch, indexed by SubArch -
@@ -253,11 +272,9 @@ StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) {
 
 AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) {
   return StringSwitch<AMDGPU::GPUKind>(CPU)
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) .Case(NAME, ENUM)
+#define AMDGPU_GPU(NAME, ENUM) .Case(NAME, ENUM)
 #define AMDGPU_GPU_ALIAS(NAME, ENUM) .Case(NAME, ENUM)
 #include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-      .Case("generic", AMDGPU::GPUKind::GK_GFX600)
-      .Case("generic-hsa", AMDGPU::GPUKind::GK_GFX700)
       .Default(AMDGPU::GPUKind::GK_NONE);
 }
 
@@ -270,25 +287,12 @@ AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef 
CPU) {
 }
 
 unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) {
-  switch (AK) {
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  case ENUM:                                                                   
\
-    return FEATURES;
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-  default:
-    return FEATURE_NONE;
-  }
+  const GPUInfo *Info = getAMDGPUInfo(AK);
+  return Info ? Info->ArchFeatures : FEATURE_NONE;
 }
 
 unsigned AMDGPU::getArchAttrAMDGCN(Triple::SubArchType SubArch) {
-  switch (SubArch) {
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  case SUBARCH:                                                                
\
-    return FEATURES;
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-  default:
-    return FEATURE_NONE;
-  }
+  return getArchAttrAMDGCN(getGPUKindFromSubArch(SubArch));
 }
 
 unsigned AMDGPU::getArchAttrR600(GPUKind AK) {
@@ -306,8 +310,9 @@ void 
AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values,
                                      Triple::SubArchType SubArch) {
   // XXX: Should this only report unique canonical names?
   // An alias shares its GPU's GPUKind, so it is filtered alongside it.
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  if (isCPUValidForSubArch(SubArch, ENUM))                                     
\
+#define AMDGPU_GPU(NAME, ENUM)                                                 
\
+  if (getSubArch(ENUM) != Triple::NoSubArch &&                                 
\
+      isCPUValidForSubArch(SubArch, ENUM))                                     
\
     Values.push_back(NAME);
 #define AMDGPU_GPU_ALIAS(NAME, ENUM)                                           
\
   if (isCPUValidForSubArch(SubArch, ENUM))                                     
\
@@ -324,38 +329,13 @@ void 
AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) {
 }
 
 AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
-  AMDGPU::GPUKind AK = parseArchAMDGCN(GPU);
-  if (AK == AMDGPU::GPUKind::GK_NONE) {
-    if (GPU == "generic-hsa")
-      return {7, 0, 0};
-    if (GPU == "generic")
-      return {6, 0, 0};
-    return {0, 0, 0};
-  }
-
-  switch (AK) {
-#define MAKE_ISAVERSION(A, B, C) {A, B, C}
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  case ENUM:                                                                   
\
-    return MAKE_ISAVERSION ISAVERSION;
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-#undef MAKE_ISAVERSION
-  default:
-    return {0, 0, 0};
-  }
+  const GPUInfo *Info = getAMDGPUInfo(parseArchAMDGCN(GPU));
+  return Info ? Info->Version : IsaVersion{0, 0, 0};
 }
 
 AMDGPU::IsaVersion AMDGPU::getIsaVersion(Triple::SubArchType SubArch) {
-  switch (SubArch) {
-#define MAKE_ISAVERSION(A, B, C) {A, B, C}
-#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)                  
\
-  case SUBARCH:                                                                
\
-    return MAKE_ISAVERSION ISAVERSION;
-#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
-#undef MAKE_ISAVERSION
-  default:
-    return {0, 0, 0};
-  }
+  const GPUInfo *Info = getAMDGPUInfo(getGPUKindFromSubArch(SubArch));
+  return Info ? Info->Version : IsaVersion{0, 0, 0};
 }
 
 unsigned AMDGPU::getTotalNumSGPRs(GPUKind AK) {
diff --git a/llvm/test/CodeGen/AMDGPU/hsa-default-device.ll 
b/llvm/test/CodeGen/AMDGPU/hsa-default-device.ll
index e10010d256a30..0a6959519722d 100644
--- a/llvm/test/CodeGen/AMDGPU/hsa-default-device.ll
+++ b/llvm/test/CodeGen/AMDGPU/hsa-default-device.ll
@@ -3,7 +3,7 @@
 ; Make sure that with an HSA triple, we don't default to an
 ; unsupported device.
 
-; CHECK: .amdgcn_target "amdgcn-unknown-amdhsa-unknown-gfx700"
+; CHECK: .amdgcn_target "amdgcn-unknown-amdhsa-unknown-generic-hsa"
 define amdgpu_kernel void @test_kernel(ptr addrspace(1) %out0, ptr 
addrspace(1) %out1) nounwind {
   store float 0.0, ptr addrspace(1) %out0
   ret void
diff --git a/llvm/test/TableGen/AMDGPUTargetDefErrors.td 
b/llvm/test/TableGen/AMDGPUTargetDefErrors.td
index 7e72f0ea23489..c861d9fc69b21 100644
--- a/llvm/test/TableGen/AMDGPUTargetDefErrors.td
+++ b/llvm/test/TableGen/AMDGPUTargetDefErrors.td
@@ -51,6 +51,7 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   list<AMDGPUArchFeature> ArchFeatures = [];
   list<int> IsaVersion = isa;
   list<string> CoveredGPUs = [];
+  bit IsPseudoTarget = false;
 }
 // A malformed IsaVersion is reported (not asserted), so this stays a clean
 // diagnostic in release builds.
diff --git a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp 
b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
index e28f7f93da371..1be0ce2d92778 100644
--- a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
@@ -29,11 +29,14 @@ static void emitGPUKindEnum(raw_ostream &OS, StringRef 
Name) {
     OS << ((C == '-') ? '_' : toUpper(C));
 }
 
-// Derive the Triple::SubArchType from an AMDGPU processor name, e.g. "gfx90a"
-// -> Triple::AMDGPUSubArch90A. A generic target uses its family's major
-// subarch, e.g. "gfx9-generic" -> Triple::AMDGPUSubArch9.
-static void emitSubArch(raw_ostream &OS, StringRef Name) {
-  StringRef Suffix = Name;
+/// Derive the Triple::SubArchType for a canonical GPU record.
+static void emitSubArch(raw_ostream &OS, const Record *Rec) {
+  if (Rec->getValueAsBit("IsPseudoTarget")) {
+    OS << "Triple::NoSubArch";
+    return;
+  }
+
+  StringRef Suffix = Rec->getValueAsString("Name");
   Suffix.consume_front("gfx");
   Suffix.consume_back("-generic");
 
@@ -42,8 +45,24 @@ static void emitSubArch(raw_ostream &OS, StringRef Name) {
     OS << ((C == '-') ? '_' : toUpper(C));
 }
 
-// Emit the ISA version tuple "(major, minor, stepping)".
-static void emitIsaVersion(raw_ostream &OS, const Record *Rec) {
+/// The gfx family for a canonical GPU record: the "-generic" family prefix
+/// (e.g.  "gfx9-4-generic" -> "gfx9"), or the name with its last two chars
+/// dropped for a concrete GPU (e.g. "gfx90a" -> "gfx9", "gfx1030" ->
+/// "gfx10"). Empty for a pseudo target.
+static StringRef getArchFamily(const Record *Rec) {
+  if (Rec->getValueAsBit("IsPseudoTarget"))
+    return "";
+  StringRef Name = Rec->getValueAsString("Name");
+  if (Name.ends_with("-generic"))
+    return Name.take_front(Name.find('-'));
+  return Name.drop_back(2);
+}
+
+// Emit the ISA version tuple as "major, minor, stepping" wrapped in \p Open 
and
+// \p Close (parens for the AMDGPU_GPU macro's ISAVERSION argument, braces for 
a
+// struct initializer).
+static void emitIsaVersion(raw_ostream &OS, const Record *Rec, char Open,
+                           char Close) {
   std::vector<int64_t> V = Rec->getValueAsListOfInts("IsaVersion");
   if (V.size() != 3) {
     PrintFatalError(Rec->getLoc(),
@@ -52,7 +71,14 @@ static void emitIsaVersion(raw_ostream &OS, const Record 
*Rec) {
                         "IsaVersion");
   }
 
-  OS << '(' << V[0] << ", " << V[1] << ", " << V[2] << ')';
+  OS << Open << V[0] << ", " << V[1] << ", " << V[2] << Close;
+}
+
+// A canonical GPU record is a "gfxN-generic" family target if it covers a set
+// of concrete GPUs (via CoveredGPUs) rather than being a single piece of
+// hardware.
+static bool isGenericTarget(const Record *Rec) {
+  return !Rec->getValueAsListOfDefs("CoveredGPUs").empty();
 }
 
 // A canonical GPU or a ProcessorAlias.
@@ -61,14 +87,12 @@ struct GPUEntry {
   const Record *Rec;
   bool IsAlias;
 
-  // An entry is generic if it is (or aliases) a "gfxN-generic" family target,
-  // i.e. a canonical that covers a set of concrete GPUs (non-empty
-  // CoveredGPUs).
-  // \p Canonicals maps canonical GPU names to their records.
+  // Whether this entry is (or aliases) a generic family target. \p Canonicals
+  // maps canonical GPU names to their records.
   bool isGeneric(const StringMap<const Record *> &Canonicals) const {
     const Record *Canon =
         IsAlias ? Canonicals.lookup(Rec->getValueAsString("Alias")) : Rec;
-    return Canon && !Canon->getValueAsListOfDefs("CoveredGPUs").empty();
+    return Canon && isGenericTarget(Canon);
   }
 };
 } // namespace
@@ -161,13 +185,13 @@ static void emitR600(raw_ostream &OS, const RecordKeeper 
&RK) {
       OS << "R600_GPU_ALIAS(\"" << Name << "\", ";
       emitGPUKindEnum(OS, E.Rec->getValueAsString("Alias"));
       OS << ")\n";
-    } else {
-      OS << "R600_GPU(\"" << Name << "\", ";
-      emitGPUKindEnum(OS, Name);
-      OS << ", ";
-      emitFeatureExpr(OS, E.Rec);
-      OS << ")\n";
+      continue;
     }
+    OS << "R600_GPU(\"" << Name << "\", ";
+    emitGPUKindEnum(OS, Name);
+    OS << ", ";
+    emitFeatureExpr(OS, E.Rec);
+    OS << ")\n";
   }
 
   OS << "\n#undef R600_GPU\n"
@@ -183,12 +207,6 @@ static void emitAMDGPUEntry(raw_ostream &OS, const 
GPUEntry &E) {
   } else {
     OS << "AMDGPU_GPU(\"" << Name << "\", ";
     emitGPUKindEnum(OS, Name);
-    OS << ", ";
-    emitSubArch(OS, Name);
-    OS << ", ";
-    emitIsaVersion(OS, E.Rec);
-    OS << ", ";
-    emitFeatureExpr(OS, E.Rec);
     OS << ")\n";
   }
 }
@@ -206,16 +224,15 @@ static void emitAMDGPU(raw_ostream &OS, const 
RecordKeeper &RK) {
   }
 
   OS << "#ifndef AMDGPU_GPU\n"
-        "#define AMDGPU_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES)\n"
+        "#define AMDGPU_GPU(NAME, ENUM)\n"
         "#endif\n\n"
         "#ifndef AMDGPU_GPU_ALIAS\n"
         "#define AMDGPU_GPU_ALIAS(NAME, ENUM)\n"
         "#endif\n\n";
 
-  // The GPUKind enum is positional and code relies on the generic targets
-  // being a contiguous block at the end (GK_AMDGPU_GENERIC_FIRST/LAST), so 
emit
-  // all non-generic entries first, then the generics, each group preserving
-  // TableGen definition order.
+  // The GPUKind enum is positional and code relies on the generic targets 
being
+  // a contiguous block at the end, so emit all non-generic entries first, then
+  // the generics, each group preserving TableGen definition order.
   for (const GPUEntry &E : Entries) {
     if (!E.isGeneric(Canonicals))
       emitAMDGPUEntry(OS, E);
@@ -230,6 +247,45 @@ static void emitAMDGPU(raw_ostream &OS, const RecordKeeper 
&RK) {
         "#undef AMDGPU_GPU_ALIAS\n";
 }
 
+/// Emit a GPUInfo table indexed by (GPUKind - AMDGPUFirstGPUKind).
+static void emitAMDGPUTable(raw_ostream &OS, const RecordKeeper &RK) {
+  std::vector<GPUEntry> Entries = collectGPUs(RK, /*WantR600=*/false);
+  if (Entries.empty())
+    return;
+
+  // Canonicals only (aliases share a canonical's GPUKind row), in the same
+  // non-generic-then-generic order as the GPUKind e¯num.
+  std::vector<const Record *> Canon;
+  for (const GPUEntry &E : Entries) {
+    if (!E.IsAlias && !isGenericTarget(E.Rec))
+      Canon.push_back(E.Rec);
+  }
+
+  for (const GPUEntry &E : Entries) {
+    if (!E.IsAlias && isGenericTarget(E.Rec))
+      Canon.push_back(E.Rec);
+  }
+
+  OS << "#ifdef GET_AMDGPU_GPU_TABLE\n"
+        "#undef GET_AMDGPU_GPU_TABLE\n";
+  OS << "static constexpr GPUKind AMDGPUFirstGPUKind = ";
+  emitGPUKindEnum(OS, Canon.front()->getValueAsString("Name"));
+  OS << ";\n"
+        "static constexpr GPUInfo AMDGPUGPUTable[] = {\n";
+  for (const Record *R : Canon) {
+    StringRef Name = R->getValueAsString("Name");
+    OS << "  {\"" << Name << "\", ";
+    emitSubArch(OS, R);
+    OS << ", ";
+    emitFeatureExpr(OS, R);
+    OS << ", ";
+    emitIsaVersion(OS, R, '{', '}');
+    OS << ", \"" << getArchFamily(R) << "\"},\n";
+  }
+  OS << "};\n"
+        "#endif // GET_AMDGPU_GPU_TABLE\n\n";
+}
+
 static void emitAMDGPUTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
   OS << "// Autogenerated by AMDGPUTargetDefEmitter.cpp\n\n";
   // R600 processors are Processor records; AMDGPU processors are
@@ -238,6 +294,7 @@ static void emitAMDGPUTargetDef(const RecordKeeper &RK, 
raw_ostream &OS) {
   // run; the other section emits nothing.
   emitR600(OS, RK);
   emitAMDGPU(OS, RK);
+  emitAMDGPUTable(OS, RK);
 }
 
 static TableGen::Emitter::Opt X("gen-amdgpu-target-def", emitAMDGPUTargetDef,

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to