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
