[llvm-branch-commits] [clang] [llvm] AMDGPU: Handle more TargetParser queries in tablegen (PR #212357)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Jul 27 21:59:06 PDT 2026
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 <Matthew.Arsenault at amd.com>
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,
More information about the llvm-branch-commits
mailing list