https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/212608
>From 88554dceb0e1df633f2af1e7395c93211faef821 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Mon, 27 Jul 2026 22:35:25 +0200 Subject: [PATCH] AMDGPU: Eliminate old macro driven processor name parsing Previously the generated inc file had a series of macros for use with StringSwitch; now just directly scan the generated name table. Co-authored-by: Claude (Claude-Opus-4.8) --- .../Misc/target-invalid-cpu-note/amdgcn.c | 36 +-- .../test/Misc/target-invalid-cpu-note/r600.c | 20 +- .../llvm/TargetParser/AMDGPUTargetParser.h | 4 +- llvm/lib/TargetParser/AMDGPUTargetParser.cpp | 115 +++++--- .../TableGen/Basic/AMDGPUTargetDefEmitter.cpp | 256 +++++++++++------- 5 files changed, 254 insertions(+), 177 deletions(-) diff --git a/clang/test/Misc/target-invalid-cpu-note/amdgcn.c b/clang/test/Misc/target-invalid-cpu-note/amdgcn.c index c898accc6db5f..3e641a3944397 100644 --- a/clang/test/Misc/target-invalid-cpu-note/amdgcn.c +++ b/clang/test/Misc/target-invalid-cpu-note/amdgcn.c @@ -6,37 +6,19 @@ // CHECK: error: unknown target CPU 'not-a-cpu' // CHECK-NEXT: note: valid target CPU values are: // CHECK-SAME: {{^}} gfx600 -// CHECK-SAME: {{^}}, tahiti // CHECK-SAME: {{^}}, gfx601 -// CHECK-SAME: {{^}}, pitcairn -// CHECK-SAME: {{^}}, verde // CHECK-SAME: {{^}}, gfx602 -// CHECK-SAME: {{^}}, hainan -// CHECK-SAME: {{^}}, oland // CHECK-SAME: {{^}}, gfx700 -// CHECK-SAME: {{^}}, kaveri // CHECK-SAME: {{^}}, gfx701 -// CHECK-SAME: {{^}}, hawaii // CHECK-SAME: {{^}}, gfx702 // CHECK-SAME: {{^}}, gfx703 -// CHECK-SAME: {{^}}, kabini -// CHECK-SAME: {{^}}, mullins // CHECK-SAME: {{^}}, gfx704 -// CHECK-SAME: {{^}}, bonaire // CHECK-SAME: {{^}}, gfx705 // CHECK-SAME: {{^}}, gfx801 -// CHECK-SAME: {{^}}, carrizo // CHECK-SAME: {{^}}, gfx802 -// CHECK-SAME: {{^}}, iceland -// CHECK-SAME: {{^}}, tonga // CHECK-SAME: {{^}}, gfx803 -// CHECK-SAME: {{^}}, fiji -// CHECK-SAME: {{^}}, polaris10 -// CHECK-SAME: {{^}}, polaris11 // CHECK-SAME: {{^}}, gfx805 -// CHECK-SAME: {{^}}, tongapro // CHECK-SAME: {{^}}, gfx810 -// CHECK-SAME: {{^}}, stoney // CHECK-SAME: {{^}}, gfx900 // CHECK-SAME: {{^}}, gfx902 // CHECK-SAME: {{^}}, gfx904 @@ -84,6 +66,24 @@ // CHECK-SAME: {{^}}, gfx12-generic // CHECK-SAME: {{^}}, gfx12-5-generic // CHECK-SAME: {{^}}, gfx13-generic +// CHECK-SAME: {{^}}, tahiti +// CHECK-SAME: {{^}}, pitcairn +// CHECK-SAME: {{^}}, verde +// CHECK-SAME: {{^}}, hainan +// CHECK-SAME: {{^}}, oland +// CHECK-SAME: {{^}}, kaveri +// CHECK-SAME: {{^}}, hawaii +// CHECK-SAME: {{^}}, kabini +// CHECK-SAME: {{^}}, mullins +// CHECK-SAME: {{^}}, bonaire +// CHECK-SAME: {{^}}, carrizo +// CHECK-SAME: {{^}}, iceland +// CHECK-SAME: {{^}}, tonga +// CHECK-SAME: {{^}}, fiji +// CHECK-SAME: {{^}}, polaris10 +// CHECK-SAME: {{^}}, polaris11 +// CHECK-SAME: {{^}}, tongapro +// CHECK-SAME: {{^}}, stoney // CHECK-SAME: {{$}} // The pseudo targets "generic"/"generic-hsa" may not be used. diff --git a/clang/test/Misc/target-invalid-cpu-note/r600.c b/clang/test/Misc/target-invalid-cpu-note/r600.c index 1481d41745ea9..bc0d27e832442 100644 --- a/clang/test/Misc/target-invalid-cpu-note/r600.c +++ b/clang/test/Misc/target-invalid-cpu-note/r600.c @@ -6,29 +6,29 @@ // CHECK: error: unknown target CPU 'not-a-cpu' // CHECK-NEXT: note: valid target CPU values are: // CHECK-SAME: {{^}} r600 -// CHECK-SAME: {{^}}, rv630 -// CHECK-SAME: {{^}}, rv635 // CHECK-SAME: {{^}}, r630 -// CHECK-SAME: {{^}}, rs780 // CHECK-SAME: {{^}}, rs880 -// CHECK-SAME: {{^}}, rv610 -// CHECK-SAME: {{^}}, rv620 // CHECK-SAME: {{^}}, rv670 // CHECK-SAME: {{^}}, rv710 // CHECK-SAME: {{^}}, rv730 -// CHECK-SAME: {{^}}, rv740 // CHECK-SAME: {{^}}, rv770 // CHECK-SAME: {{^}}, cedar -// CHECK-SAME: {{^}}, palm // CHECK-SAME: {{^}}, cypress -// CHECK-SAME: {{^}}, hemlock // CHECK-SAME: {{^}}, juniper // CHECK-SAME: {{^}}, redwood // CHECK-SAME: {{^}}, sumo -// CHECK-SAME: {{^}}, sumo2 // CHECK-SAME: {{^}}, barts // CHECK-SAME: {{^}}, caicos -// CHECK-SAME: {{^}}, aruba // CHECK-SAME: {{^}}, cayman // CHECK-SAME: {{^}}, turks +// CHECK-SAME: {{^}}, rv630 +// CHECK-SAME: {{^}}, rv635 +// CHECK-SAME: {{^}}, rs780 +// CHECK-SAME: {{^}}, rv610 +// CHECK-SAME: {{^}}, rv620 +// CHECK-SAME: {{^}}, rv740 +// CHECK-SAME: {{^}}, palm +// CHECK-SAME: {{^}}, hemlock +// CHECK-SAME: {{^}}, sumo2 +// CHECK-SAME: {{^}}, aruba // CHECK-SAME: {{$}} diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h index c83528b76c7f9..8f8decdb373ce 100644 --- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h +++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h @@ -35,10 +35,10 @@ enum GPUKind : uint32_t { // Not specified processor. GK_NONE = 0, -#define R600_GPU(NAME, ENUM, FEATURES) ENUM, +#define GET_R600_GPU_ENUM #include "llvm/TargetParser/R600TargetParserDef.inc" -#define AMDGPU_GPU(NAME, ENUM) ENUM, +#define GET_AMDGPU_GPU_ENUM #include "llvm/TargetParser/AMDGPUTargetParserDef.inc" }; diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp index 72b474cff7cc1..f866a092d6697 100644 --- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp +++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp @@ -13,10 +13,8 @@ #include "llvm/TargetParser/AMDGPUTargetParser.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringTable.h" #include "llvm/ADT/Twine.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include <array> @@ -28,6 +26,12 @@ namespace { constexpr unsigned NumAMDGPUSubArches = Triple::LastAMDGPUSubArch - Triple::FirstAMDGPUSubArch + 1; +// A legacy GPU name (e.g. "tahiti") mapped to the GPUKind it aliases. +struct GPUNameAlias { + StringTable::Offset AltName; + GPUKind Kind; +}; + // Per-GPU data for the AMDGCN GPUKinds, from the generated table below. struct GPUInfo { StringTable::Offset Name; @@ -37,15 +41,28 @@ struct GPUInfo { StringTable::Offset FamilyName; }; +// Per-GPU data for the R600 GPUKinds. +struct R600Info { + StringTable::Offset Name; + R600FeatureKind ArchFeatures; +}; + #define GET_AMDGPU_NAME_TABLE #define GET_AMDGPU_GPU_TABLE +#define GET_AMDGPU_GPU_ALIAS_TABLE #define GET_AMDGPU_MAJOR_SUBARCH #define GET_AMDGPU_SUBARCH_NAME #include "llvm/TargetParser/AMDGPUTargetParserDef.inc" -// The string table shared by every generated table that stores GPU-name-derived -// strings as offsets. +#define GET_R600_NAME_TABLE +#define GET_R600_GPU_TABLE +#define GET_R600_GPU_ALIAS_TABLE +#include "llvm/TargetParser/R600TargetParserDef.inc" + +// The string tables holding GPU-name-derived strings as offsets. R600 and +// AMDGPU come from separate generated headers, each with its own pool. constexpr StringTable AMDGPUNameStrTab = AMDGPUNameTable; +constexpr StringTable R600NameStrTab = R600NameTable; // Look up the GPUInfo row for an AMDGCN GPUKind, or nullptr for GK_NONE / a // non-AMDGCN (R600) kind. @@ -58,6 +75,34 @@ const GPUInfo *getAMDGPUInfo(GPUKind AK) { return &AMDGPUGPUTable[Idx]; } +// Look up the R600Info row for an R600 GPUKind, or nullptr for a non-R600 kind. +const R600Info *getR600Info(GPUKind AK) { + if (AK < R600FirstGPUKind) + return nullptr; + unsigned Idx = AK - R600FirstGPUKind; + if (Idx >= std::size(R600GPUTable)) + return nullptr; + return &R600GPUTable[Idx]; +} + +// Scan a name -> GPUKind table (canonical names, then aliases) for \p CPU. +template <typename InfoT, size_t N, size_t M> +GPUKind parseArchImpl(StringRef CPU, const InfoT (&Table)[N], GPUKind FirstKind, + const StringTable &StrTab, + const GPUNameAlias (&Aliases)[M]) { + for (unsigned I = 0; I != N; ++I) { + if (CPU == StrTab[Table[I].Name]) + return static_cast<GPUKind>(FirstKind + I); + } + + for (const GPUNameAlias &A : Aliases) { + if (CPU == StrTab[A.AltName]) + return A.Kind; + } + + return GK_NONE; +} + // Reverse map: SubArch -> GPUKind, indexed by (SubArch - FirstAMDGPUSubArch). // Subarches with no GPU (incl. the NoSubArch pseudo targets) map to GK_NONE. constexpr std::array<GPUKind, NumAMDGPUSubArches> AMDGPUSubArchToGPUKind = [] { @@ -220,30 +265,18 @@ StringRef llvm::AMDGPU::getArchNameFromSubArch(Triple::SubArchType SubArch) { } StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) { - switch (AK) { -#define R600_GPU(NAME, ENUM, FEATURES) \ - case ENUM: \ - return NAME; -#include "llvm/TargetParser/R600TargetParserDef.inc" - default: - return ""; - } + const R600Info *Info = getR600Info(AK); + return Info ? R600NameStrTab[Info->Name] : ""; } AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) { - return StringSwitch<AMDGPU::GPUKind>(CPU) -#define AMDGPU_GPU(NAME, ENUM) .Case(NAME, ENUM) -#define AMDGPU_GPU_ALIAS(NAME, ENUM) .Case(NAME, ENUM) -#include "llvm/TargetParser/AMDGPUTargetParserDef.inc" - .Default(AMDGPU::GPUKind::GK_NONE); + return parseArchImpl(CPU, AMDGPUGPUTable, AMDGPUFirstGPUKind, + AMDGPUNameStrTab, AMDGPUGPUAliases); } AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) { - return StringSwitch<AMDGPU::GPUKind>(CPU) -#define R600_GPU(NAME, ENUM, FEATURES) .Case(NAME, ENUM) -#define R600_GPU_ALIAS(NAME, ENUM) .Case(NAME, ENUM) -#include "llvm/TargetParser/R600TargetParserDef.inc" - .Default(AMDGPU::GPUKind::GK_NONE); + return parseArchImpl(CPU, R600GPUTable, R600FirstGPUKind, R600NameStrTab, + R600GPUAliases); } unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) { @@ -256,36 +289,32 @@ unsigned AMDGPU::getArchAttrAMDGCN(Triple::SubArchType SubArch) { } R600FeatureKind AMDGPU::getArchAttrR600(GPUKind AK) { - switch (AK) { -#define R600_GPU(NAME, ENUM, FEATURES) \ - case ENUM: \ - return FEATURES; -#include "llvm/TargetParser/R600TargetParserDef.inc" - default: - return R600_FEATURE_NONE; - } + const R600Info *Info = getR600Info(AK); + return Info ? Info->ArchFeatures : R600_FEATURE_NONE; } 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) \ - if (getSubArch(ENUM) != Triple::NoSubArch && \ - isCPUValidForSubArch(SubArch, ENUM)) \ - Values.push_back(NAME); -#define AMDGPU_GPU_ALIAS(NAME, ENUM) \ - if (isCPUValidForSubArch(SubArch, ENUM)) \ - Values.push_back(NAME); -#include "llvm/TargetParser/AMDGPUTargetParserDef.inc" + for (unsigned I = 0; I != std::size(AMDGPUGPUTable); ++I) { + GPUKind Kind = static_cast<GPUKind>(AMDGPUFirstGPUKind + I); + if (AMDGPUGPUTable[I].SubArch != Triple::NoSubArch && + isCPUValidForSubArch(SubArch, Kind)) + Values.push_back(AMDGPUNameStrTab[AMDGPUGPUTable[I].Name]); + } + + for (const GPUNameAlias &A : AMDGPUGPUAliases) { + if (isCPUValidForSubArch(SubArch, A.Kind)) + Values.push_back(AMDGPUNameStrTab[A.AltName]); + } } void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) { - Values.append({ -#define R600_GPU(NAME, ENUM, FEATURES) NAME, -#define R600_GPU_ALIAS(NAME, ENUM) NAME, -#include "llvm/TargetParser/R600TargetParserDef.inc" - }); + for (const R600Info &Info : R600GPUTable) + Values.push_back(R600NameStrTab[Info.Name]); + for (const GPUNameAlias &A : R600GPUAliases) + Values.push_back(R600NameStrTab[A.AltName]); } AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) { diff --git a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp index 4a675bd8f8339..5588a74719428 100644 --- a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp @@ -179,121 +179,155 @@ static void validate(ArrayRef<GPUEntry> Entries) { } } -static void emitR600(raw_ostream &OS, const RecordKeeper &RK) { +// The canonical R600 GPU records, in GPUKind-enum / TableGen definition order. +static std::vector<const Record *> +collectR600Canonicals(const RecordKeeper &RK) { + std::vector<GPUEntry> Entries = collectGPUs(RK, /*WantR600=*/true); + std::vector<const Record *> Canon; + Canon.reserve(Entries.size()); + + for (const GPUEntry &E : Entries) { + if (!E.IsAlias) + Canon.push_back(E.Rec); + } + + return Canon; +} + +// Emit the R600 GPUKind enumerators (canonical GPUs only; aliases share a +// canonical's kind). Guarded by GET_R600_GPU_ENUM. +static void emitR600Enum(raw_ostream &OS, const RecordKeeper &RK) { + std::vector<const Record *> Canon = collectR600Canonicals(RK); + if (Canon.empty()) + return; + OS << "#ifdef GET_R600_GPU_ENUM\n" + "#undef GET_R600_GPU_ENUM\n"; + for (const Record *R : Canon) { + OS << " "; + emitGPUKindEnum(OS, R->getValueAsString("Name")); + OS << ",\n"; + } + OS << "#endif // GET_R600_GPU_ENUM\n\n"; +} + +// Emit the R600Info table indexed by (GPUKind - R600FirstGPUKind). Names are +// offsets into the shared \p Names table. Guarded by GET_R600_GPU_TABLE. +static void emitR600Table(raw_ostream &OS, const RecordKeeper &RK, + StringToOffsetTable &Names) { + std::vector<const Record *> Canon = collectR600Canonicals(RK); + if (Canon.empty()) + return; + + OS << "#ifdef GET_R600_GPU_TABLE\n" + "#undef GET_R600_GPU_TABLE\n"; + OS << "static constexpr GPUKind R600FirstGPUKind = "; + emitGPUKindEnum(OS, Canon.front()->getValueAsString("Name")); + OS << ";\n" + "static constexpr R600Info R600GPUTable[] = {\n"; + for (const Record *R : Canon) { + OS << " {" << Names.GetOrAddStringOffset(R->getValueAsString("Name")) + << ", "; + emitFeatureExpr(OS, R, "R600_FEATURE_NONE"); + OS << "},\n"; + } + OS << "};\n" + "#endif // GET_R600_GPU_TABLE\n\n"; +} + +// Emit the R600 name -> GPUKind alias table. Guarded by +// GET_R600_GPU_ALIAS_TABLE; names are offsets into \p Names. +static void emitR600Aliases(raw_ostream &OS, const RecordKeeper &RK, + StringToOffsetTable &Names) { std::vector<GPUEntry> Entries = collectGPUs(RK, /*WantR600=*/true); validate(Entries); if (Entries.empty()) return; - OS << "#ifndef R600_GPU\n" - "#define R600_GPU(NAME, ENUM, FEATURES)\n" - "#endif\n\n" - "#ifndef R600_GPU_ALIAS\n" - "#define R600_GPU_ALIAS(NAME, ENUM)\n" - "#endif\n\n"; - + OS << "#ifdef GET_R600_GPU_ALIAS_TABLE\n" + "#undef GET_R600_GPU_ALIAS_TABLE\n" + "static constexpr GPUNameAlias R600GPUAliases[] = {\n"; for (const GPUEntry &E : Entries) { - StringRef Name = E.Rec->getValueAsString("Name"); - if (E.IsAlias) { - OS << "R600_GPU_ALIAS(\"" << Name << "\", "; - emitGPUKindEnum(OS, E.Rec->getValueAsString("Alias")); - OS << ")\n"; + if (!E.IsAlias) continue; - } - OS << "R600_GPU(\"" << Name << "\", "; - emitGPUKindEnum(OS, Name); - OS << ", "; - emitFeatureExpr(OS, E.Rec, "R600_FEATURE_NONE"); - OS << ")\n"; + OS << " {" << Names.GetOrAddStringOffset(E.Rec->getValueAsString("Name")) + << ", "; + emitGPUKindEnum(OS, E.Rec->getValueAsString("Alias")); + OS << "},\n"; } - - OS << "\n#undef R600_GPU\n" - "#undef R600_GPU_ALIAS\n"; + OS << "};\n" + "#endif // GET_R600_GPU_ALIAS_TABLE\n\n"; } -// Return \p Entries with the generic-family entries moved after the non-generic -// ones, each group keeping definition order. The GPUKind enum and GPUInfo table -// are positional and rely on the generics forming a contiguous block at the -// end, so both are emitted in this order. -static std::vector<GPUEntry> -orderGenericsLast(ArrayRef<GPUEntry> Entries, - const StringMap<const Record *> &Canonicals) { - std::vector<GPUEntry> Ordered; - Ordered.reserve(Entries.size()); +// Canonical AMDGPU GPUs in GPUKind-enum order: non-generic targets first, then +// the "gfxN-generic" targets. The enum and the GPUInfo table share this order. +static std::vector<const Record *> +collectAMDGPUCanonicals(const RecordKeeper &RK) { + std::vector<GPUEntry> Entries = collectGPUs(RK, /*WantR600=*/false); + std::vector<const Record *> Canon; + Canon.reserve(Entries.size()); for (const GPUEntry &E : Entries) { - if (!E.isGeneric(Canonicals)) - Ordered.push_back(E); + if (!E.IsAlias && !isGenericTarget(E.Rec)) + Canon.push_back(E.Rec); } for (const GPUEntry &E : Entries) { - if (E.isGeneric(Canonicals)) - Ordered.push_back(E); + if (!E.IsAlias && isGenericTarget(E.Rec)) + Canon.push_back(E.Rec); } - return Ordered; + return Canon; } -static void emitAMDGPUEntry(raw_ostream &OS, const GPUEntry &E) { - StringRef Name = E.Rec->getValueAsString("Name"); - if (E.IsAlias) { - OS << "AMDGPU_GPU_ALIAS(\"" << Name << "\", "; - emitGPUKindEnum(OS, E.Rec->getValueAsString("Alias")); - OS << ")\n"; - } else { - OS << "AMDGPU_GPU(\"" << Name << "\", "; - emitGPUKindEnum(OS, Name); - OS << ")\n"; +// Emit the AMDGPU GPUKind enumerators (canonical GPUs only; aliases share a +// canonical's kind). Guarded by GET_AMDGPU_GPU_ENUM. +static void emitAMDGPUEnum(raw_ostream &OS, const RecordKeeper &RK) { + std::vector<const Record *> Canon = collectAMDGPUCanonicals(RK); + if (Canon.empty()) + return; + OS << "#ifdef GET_AMDGPU_GPU_ENUM\n" + "#undef GET_AMDGPU_GPU_ENUM\n"; + for (const Record *R : Canon) { + OS << " "; + emitGPUKindEnum(OS, R->getValueAsString("Name")); + OS << ",\n"; } + OS << "#endif // GET_AMDGPU_GPU_ENUM\n\n"; } -static void emitAMDGPU(raw_ostream &OS, const RecordKeeper &RK) { +// Emit the name -> GPUKind alias table (legacy names such as "tahiti" -> +// gfx600). Guarded by GET_AMDGPU_GPU_ALIAS_TABLE; names are offsets into \p +// Names. +static void emitAMDGPUAliases(raw_ostream &OS, const RecordKeeper &RK, + StringToOffsetTable &Names) { std::vector<GPUEntry> Entries = collectGPUs(RK, /*WantR600=*/false); validate(Entries); if (Entries.empty()) return; - StringMap<const Record *> Canonicals; + OS << "#ifdef GET_AMDGPU_GPU_ALIAS_TABLE\n" + "#undef GET_AMDGPU_GPU_ALIAS_TABLE\n" + "static constexpr GPUNameAlias AMDGPUGPUAliases[] = {\n"; for (const GPUEntry &E : Entries) { if (!E.IsAlias) - Canonicals[E.Rec->getValueAsString("Name")] = E.Rec; + continue; + OS << " {" << Names.GetOrAddStringOffset(E.Rec->getValueAsString("Name")) + << ", "; + emitGPUKindEnum(OS, E.Rec->getValueAsString("Alias")); + OS << "},\n"; } - - OS << "#ifndef AMDGPU_GPU\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"; - - for (const GPUEntry &E : orderGenericsLast(Entries, Canonicals)) - emitAMDGPUEntry(OS, E); - - OS << "\n#undef AMDGPU_GPU\n" - "#undef AMDGPU_GPU_ALIAS\n"; + OS << "};\n" + "#endif // GET_AMDGPU_GPU_ALIAS_TABLE\n\n"; } /// Emit a GPUInfo table indexed by (GPUKind - AMDGPUFirstGPUKind). Name and /// family strings are stored as offsets into the shared \p Names table. static void emitAMDGPUTable(raw_ostream &OS, const RecordKeeper &RK, StringToOffsetTable &Names) { - std::vector<GPUEntry> Entries = collectGPUs(RK, /*WantR600=*/false); - if (Entries.empty()) + std::vector<const Record *> Canon = collectAMDGPUCanonicals(RK); + if (Canon.empty()) return; - StringMap<const Record *> Canonicals; - for (const GPUEntry &E : Entries) { - if (!E.IsAlias) - Canonicals[E.Rec->getValueAsString("Name")] = E.Rec; - } - - // Canonicals only; aliases share a canonical's GPUKind row. - std::vector<const Record *> Canon; - for (const GPUEntry &E : orderGenericsLast(Entries, Canonicals)) { - if (!E.IsAlias) - Canon.push_back(E.Rec); - } - OS << "#ifdef GET_AMDGPU_GPU_TABLE\n" "#undef GET_AMDGPU_GPU_TABLE\n"; OS << "static constexpr GPUKind AMDGPUFirstGPUKind = "; @@ -314,11 +348,10 @@ static void emitAMDGPUTable(raw_ostream &OS, const RecordKeeper &RK, "#endif // GET_AMDGPU_GPU_TABLE\n\n"; } -// Emit the subarch -> major-family-subarch overrides; a subarch not listed here -// is its own major subarch. Each entry maps a member GPU's own subarch to its -// family's major subarch, from one of two sources: a "gfxN-generic" target, -// whose subarch is the major for every GPU it lists in CoveredGPUs, or an -// AMDGPUFamily's MajorSubArch for the gfx6/gfx7/gfx8 families that have no +// Emit the subarch -> major-family-subarch overrides for getMajorSubArch (a +// subarch not listed here is its own major). Each member GPU maps to its +// family's major, sourced from a "gfxN-generic" target's CoveredGPUs, or from +// an AMDGPUFamily's MajorSubArch for the gfx6/gfx7/gfx8 families that have no // generic target. static void emitAMDGPUMajorSubArch(raw_ostream &OS, const RecordKeeper &RK) { ArrayRef<const Record *> GPUs = @@ -408,30 +441,45 @@ static void emitAMDGPUSubArchNames(raw_ostream &OS, const RecordKeeper &RK, static void emitAMDGPUTargetDef(const RecordKeeper &RK, raw_ostream &OS) { OS << "// Autogenerated by AMDGPUTargetDefEmitter.cpp\n\n"; - // R600 processors are Processor records; AMDGPU processors are - // ProcessorModel records. R600.td and AMDGPU.td are separate top-level files - // (neither includes the other), so exactly one family is present in a given - // run; the other section emits nothing. - emitR600(OS, RK); - emitAMDGPU(OS, RK); + // R600.td and AMDGPU.td are separate top-level files, so a run sees exactly + // one family; the other family's sections emit nothing. + emitR600Enum(OS, RK); + emitAMDGPUEnum(OS, RK); emitAMDGPUMajorSubArch(OS, RK); - // The GPUInfo and SubArchName tables both reference GPU-name strings; pool - // them into a single string table. Buffer the two tables first so every - // referenced string is interned, then emit the shared table def (guarded so - // consumers pull it in once) ahead of the buffered tables. - StringToOffsetTable Names; - std::string GPUTable, SubArchNames; - raw_string_ostream GPUTableOS(GPUTable), SubArchNamesOS(SubArchNames); - emitAMDGPUTable(GPUTableOS, RK, Names); - emitAMDGPUSubArchNames(SubArchNamesOS, RK, Names); - - OS << "#ifdef GET_AMDGPU_NAME_TABLE\n" - "#undef GET_AMDGPU_NAME_TABLE\n"; - Names.EmitStringTableDef(OS, "AMDGPUNameTable"); - OS << "#endif // GET_AMDGPU_NAME_TABLE\n\n"; - - OS << GPUTable << SubArchNames; + // Each family gets its own string pool with a distinct guard/symbol so the + // two generated headers stay independent when a consumer includes both. + // Buffer the tables first to intern their strings, then emit the pool ahead. + { + StringToOffsetTable Names; + std::string Tables; + raw_string_ostream TablesOS(Tables); + emitR600Table(TablesOS, RK, Names); + emitR600Aliases(TablesOS, RK, Names); + if (!Tables.empty()) { + OS << "#ifdef GET_R600_NAME_TABLE\n" + "#undef GET_R600_NAME_TABLE\n"; + Names.EmitStringTableDef(OS, "R600NameTable"); + OS << "#endif // GET_R600_NAME_TABLE\n\n"; + OS << Tables; + } + } + + { + StringToOffsetTable Names; + std::string Tables; + raw_string_ostream TablesOS(Tables); + emitAMDGPUTable(TablesOS, RK, Names); + emitAMDGPUAliases(TablesOS, RK, Names); + emitAMDGPUSubArchNames(TablesOS, RK, Names); + if (!Tables.empty()) { + OS << "#ifdef GET_AMDGPU_NAME_TABLE\n" + "#undef GET_AMDGPU_NAME_TABLE\n"; + Names.EmitStringTableDef(OS, "AMDGPUNameTable"); + OS << "#endif // GET_AMDGPU_NAME_TABLE\n\n"; + OS << Tables; + } + } } static TableGen::Emitter::Opt X("gen-amdgpu-target-def", emitAMDGPUTargetDef, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
