//===- AMDGPUTargetDefEmitter.cpp - Generate lists of AMDGPU GPUs ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend emits the AMDGPU GPU tables used by
// AMDGPUTargetParser.cpp.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringToOffsetTable.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <string>
#include <utility>
#include <vector>

using namespace llvm;

// Derive the GPUKind enum from a processor name, e.g. "gfx90a" -> "GK_GFX90A".
static void emitGPUKindEnum(raw_ostream &OS, StringRef Name) {
  OS << "GK_";
  for (char C : Name)
    OS << ((C == '-') ? '_' : toUpper(C));
}

// Feature string to enumerator, e.g. "16-bit-insts" -> "FEAT_16_BIT_INSTS".
// AMDGCN uses the "FEAT_" prefix, R600 the "R600_FEAT_" prefix.
static void emitFeatureEnum(raw_ostream &OS, StringRef Prefix, StringRef Name) {
  OS << Prefix;
  for (char C : Name)
    OS << ((C == '-') ? '_' : toUpper(C));
}

// Emit the Triple::AMDGPUSubArch enumerator suffix for a "gfx..." GPU name,
// e.g. "gfx90a" -> "90A", "gfx9-generic" -> "9" (the family major).
static void emitSubArchSuffix(raw_ostream &OS, StringRef Name) {
  StringRef Suffix = Name;
  Suffix.consume_front("gfx");
  Suffix.consume_back("-generic");

  for (char C : Suffix)
    OS << static_cast<char>((C == '-') ? '_' : toUpper(C));
}

/// Derive the Triple::SubArchType from a "gfx..." GPU name, e.g. "gfx90a" ->
/// Triple::AMDGPUSubArch90A
static void emitSubArchForName(raw_ostream &OS, StringRef Name) {
  OS << "Triple::AMDGPUSubArch";
  emitSubArchSuffix(OS, Name);
}

// The explicit subarch spelling for a GPU whose subarch is not derivable from
// its name, or empty. Optional so test stubs may omit it.
static std::optional<StringRef> getSubArchSpelling(const Record *Rec) {
  return Rec->getValueAsOptionalString("SubArchSpelling");
}

// Emit a subarch enumerator suffix for a spelling, dropping '.' and upcasing,
// e.g. "12.50s" -> "1250S", matching the sibling name-derived enumerators.
static void emitSpellingSuffix(raw_ostream &OS, StringRef Spelling) {
  for (char C : Spelling)
    if (C != '.')
      OS << static_cast<char>(toUpper(C));
}

// Derive the Triple::SubArchType for a canonical GPU record. A pseudo target
// maps to Triple::NoSubArch; an explicit SubArchSpelling maps to that (e.g.
// "4.67q" -> AMDGPUSubArch4_67Q); otherwise it is derived from the name.
static void emitSubArch(raw_ostream &OS, const Record *Rec) {
  if (Rec->getValueAsBit("IsPseudoTarget")) {
    OS << "Triple::NoSubArch";
    return;
  }

  if (std::optional<StringRef> Spelling = getSubArchSpelling(Rec)) {
    OS << "Triple::AMDGPUSubArch";
    emitSpellingSuffix(OS, *Spelling);
    return;
  }

  emitSubArchForName(OS, Rec->getValueAsString("Name"));
}

// 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();
}

// Emit the gfx family for a canonical GPU record: "gfx" + the ISA major version
// (e.g. "gfx90a"/[9,0,10] -> "gfx9", "gfx1250"/[12,5,0] -> "gfx12").
// Nothing for a pseudo target.
static void emitArchFamily(raw_ostream &OS, const Record *Rec) {
  if (Rec->getValueAsBit("IsPseudoTarget"))
    return;
  OS << "gfx" << Rec->getValueAsListOfInts("IsaVersion")[0];
}

// 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(),
                    "GPU '" + Rec->getValueAsString("Name") +
                        "' must have a 3-element [major, minor, stepping] "
                        "IsaVersion");
  }

  // Each component is stored in a uint8_t field, and the stepping is
  // additionally spelled as a single lowercase hex digit in the device and
  // subarch names. Reject out-of-range values.
  for (int64_t Component : V) {
    if (!isUInt<8>(Component)) {
      PrintFatalError(Rec->getLoc(),
                      "GPU '" + Rec->getValueAsString("Name") +
                          "' IsaVersion components must each fit in a byte");
    }
  }

  if (!isUInt<4>(V[2])) {
    PrintFatalError(Rec->getLoc(), "GPU '" + Rec->getValueAsString("Name") +
                                       "' stepping must be a single hex digit");
  }

  OS << Open << V[0] << ", " << V[1] << ", " << V[2] << Close;
}

// Emit the triple subarch name for a concrete GPU, e.g. gfx90c / [9, 0, 12] ->
// "amdgpu9.0c". The stepping is spelled as a single lowercase hex digit
// (validated by emitIsaVersion).
static void emitConcreteSubArchTripleName(raw_ostream &OS, const Record *Rec) {
  std::vector<int64_t> V = Rec->getValueAsListOfInts("IsaVersion");
  OS << "amdgpu" << V[0] << '.' << V[1] << hexdigit(V[2], /*LowerCase=*/true);
}

// Emit the triple subarch name for a major-family subarch, e.g. "9" ->
// "amdgpu9", "9_4" -> "amdgpu9.4" (the enumerator suffix uses '_', the triple
// name '.').
static void emitFamilySubArchTripleName(raw_ostream &OS, StringRef Suffix) {
  OS << "amdgpu";
  for (char C : Suffix)
    OS << static_cast<char>((C == '_') ? '.' : C);
}

// A canonical GPU or a ProcessorAlias.
namespace {
struct GPUEntry {
  const Record *Rec;
  bool IsAlias;

  // 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 && isGenericTarget(Canon);
  }
};
} // namespace

// The frontend-visible features from def \p ListName, in bit order. Empty if
// the def is absent.
static std::vector<const Record *>
collectFrontendFeatures(const RecordKeeper &RK, StringRef ListName) {
  const Record *List = RK.getDef(ListName);
  if (!List)
    return {};
  return List->getValueAsListOfDefs("Features");
}

static void
emitFeatureBitset(raw_ostream &OS, StringRef BitsetType, StringRef EnumPrefix,
                  const Record *GPU,
                  const DenseMap<const Record *, unsigned> &FeatureIdx);

// The transitive closure of a GPU's SubtargetFeatures, following the Implies
// edges (a feature enables everything it implies).
static void collectFeatureClosure(const Record *GPU,
                                  SetVector<const Record *> &Closure) {
  std::vector<const Record *> Worklist = GPU->getValueAsListOfDefs("Features");
  while (!Worklist.empty()) {
    const Record *F = Worklist.back();
    Worklist.pop_back();
    if (Closure.insert(F))
      append_range(Worklist, F->getValueAsListOfDefs("Implies"));
  }
}

// Collect canonical GPUs and their aliases, in TableGen definition order. R600
// GPUs are plain Processor records; AMDGPU GPUs are ProcessorModel records (a
// Processor subclass), so \p WantR600 selects the family to emit.
static std::vector<GPUEntry> collectGPUs(const RecordKeeper &RK,
                                         bool WantR600) {
  ArrayRef<const Record *> GPUs = RK.getAllDerivedDefinitions("AMDGPUGPUInfo");
  std::vector<GPUEntry> Entries;
  Entries.reserve(GPUs.size());
  for (const Record *Rec : GPUs) {
    if (Rec->isSubClassOf("ProcessorModel") == WantR600)
      continue;
    Entries.push_back({Rec, /*IsAlias=*/false});
  }

  // Aliases only make sense when their canonical is present, so only gather
  // them for the family being emitted.
  if (!Entries.empty()) {
    for (const Record *Rec :
         RK.getAllDerivedDefinitionsIfDefined("ProcessorAlias"))
      Entries.push_back({Rec, /*IsAlias=*/true});
  }

  // Sort to preserve declaration order instead of name order.
  sort(Entries, [](const GPUEntry &A, const GPUEntry &B) {
    return A.Rec->getID() < B.Rec->getID();
  });

  return Entries;
}

// Check that every alias resolves to a canonical GPU and no name repeats.
static void validate(ArrayRef<GPUEntry> Entries) {
  StringMap<const Record *> Canonicals;
  for (const GPUEntry &E : Entries)
    if (!E.IsAlias)
      Canonicals[E.Rec->getValueAsString("Name")] = E.Rec;

  StringMap<const Record *> Seen;
  for (const GPUEntry &E : Entries) {
    StringRef Name = E.Rec->getValueAsString("Name");
    if (!Seen.insert({Name, E.Rec}).second) {
      PrintFatalError(E.Rec->getLoc(),
                      "duplicate AMDGPU processor name '" + Name + "'");
    }

    if (E.IsAlias) {
      StringRef Alias = E.Rec->getValueAsString("Alias");
      if (!Canonicals.count(Alias)) {
        PrintFatalError(E.Rec->getLoc(),
                        "ProcessorAlias '" + Name + "' aliases '" + Alias +
                            "' which is not a canonical AMDGPU GPU");
      }
    }
  }
}

// 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,
              const DenseMap<const Record *, unsigned> &FeatureIdx) {
  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"))
       << ", ";
    emitFeatureBitset(OS, "R600FeatureBitset", "R600_FEAT_", R, FeatureIdx);
    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 << "#ifdef GET_R600_GPU_ALIAS_TABLE\n"
        "#undef GET_R600_GPU_ALIAS_TABLE\n"
        "static constexpr GPUNameAlias R600GPUAliases[] = {\n";
  for (const GPUEntry &E : Entries) {
    if (!E.IsAlias)
      continue;
    OS << "  {" << Names.GetOrAddStringOffset(E.Rec->getValueAsString("Name"))
       << ", ";
    emitGPUKindEnum(OS, E.Rec->getValueAsString("Alias"));
    OS << "},\n";
  }
  OS << "};\n"
        "#endif // GET_R600_GPU_ALIAS_TABLE\n\n";
}

// 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.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);
  }

  return Canon;
}

// 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";
}

// 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;

  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)
      continue;
    OS << "  {" << Names.GetOrAddStringOffset(E.Rec->getValueAsString("Name"))
       << ", ";
    emitGPUKindEnum(OS, E.Rec->getValueAsString("Alias"));
    OS << "},\n";
  }
  OS << "};\n"
        "#endif // GET_AMDGPU_GPU_ALIAS_TABLE\n\n";
}

// Per-family spellings for the generated feature enum and name table. R600 and
// AMDGCN each get their own so the two headers coexist.
struct FeatureNaming {
  StringRef EnumGuard;
  StringRef EnumPrefix;
  StringRef CountEnumerator;
  StringRef NameTableGuard;
  StringRef NameTableSymbol;
};

static constexpr FeatureNaming AMDGPUFeatureNaming = {
    "GET_AMDGPU_FEATURE_ENUM", "FEAT_", "NUM_FEATURES",
    "GET_AMDGPU_FEATURE_NAME_TABLE", "AMDGPUFeatureNames"};

static constexpr FeatureNaming R600FeatureNaming = {
    "GET_R600_FEATURE_ENUM", "R600_FEAT_", "R600_NUM_FEATURES",
    "GET_R600_FEATURE_NAME_TABLE", "R600FeatureNames"};

// Emit the frontend feature enum for a family, interning each feature name into
// \p Names. Returns the name offsets indexed by feature bit.
static std::vector<unsigned> emitFeatureEnum(raw_ostream &OS,
                                             const FeatureNaming &Naming,
                                             ArrayRef<const Record *> Features,
                                             StringToOffsetTable &Names) {
  std::vector<unsigned> Offsets;
  if (Features.empty())
    return Offsets;
  Offsets.reserve(Features.size());

  OS << "#ifdef " << Naming.EnumGuard << "\n"
     << "#undef " << Naming.EnumGuard << "\n";
  for (const Record *F : Features) {
    StringRef Name = F->getValueAsString("Name");
    OS << "  ";
    emitFeatureEnum(OS, Naming.EnumPrefix, Name);
    OS << ",\n";
    Offsets.push_back(Names.GetOrAddStringOffset(Name));
  }
  OS << "  " << Naming.CountEnumerator << "\n"
     << "#endif // " << Naming.EnumGuard << "\n\n";
  return Offsets;
}

// Emit a family's feature-name table (bit -> name offset).
static void emitFeatureNames(raw_ostream &OS, const FeatureNaming &Naming,
                             ArrayRef<unsigned> Offsets) {
  if (Offsets.empty())
    return;
  OS << "#ifdef " << Naming.NameTableGuard << "\n"
     << "#undef " << Naming.NameTableGuard << "\n"
     << "static constexpr StringTable::Offset " << Naming.NameTableSymbol
     << "[] = {\n";
  for (unsigned O : Offsets)
    OS << "  " << O << ",\n";
  OS << "};\n"
     << "#endif // " << Naming.NameTableGuard << "\n\n";
}

// Features checked for generic-target compatibility: frontend-visible features
// and features explicitly opting into the any-covered-GPU rule.
static SetVector<const Record *>
collectGenericFeatures(const Record *GPU,
                       const DenseMap<const Record *, unsigned> &FeatureIdx) {
  SetVector<const Record *> Closure;
  collectFeatureClosure(GPU, Closure);
  SetVector<const Record *> Features;
  for (const Record *F : Closure) {
    if (FeatureIdx.contains(F) || F->isSubClassOf("AMDGPUGenericAnyFeature"))
      Features.insert(F);
  }

  return Features;
}

// Ordinary frontend-visible features must be present on every covered GPU.
// AMDGPUGenericAnyFeature features need only be present on one covered GPU.
static void
validateGenericFeatures(const Record *GPU,
                        const DenseMap<const Record *, unsigned> &FeatureIdx) {
  StringRef Name = GPU->getValueAsString("Name");
  std::vector<const Record *> Covered =
      GPU->getValueAsListOfDefs("CoveredGPUs");
  if (Covered.empty()) {
    if (Name.starts_with("gfx") && Name.ends_with("-generic")) {
      PrintFatalError(GPU->getLoc(), "generic target '" + Name +
                                         "' must cover at least one GPU");
    }
    return;
  }

  SetVector<const Record *> GenericFeatures =
      collectGenericFeatures(GPU, FeatureIdx);
  SetVector<const Record *> CoveredFeatures;
  for (const Record *Member : Covered) {
    if (!Member->isSubClassOf("AMDGPUGPUInfo") ||
        !Member->isSubClassOf("ProcessorModel") ||
        Member->getValueAsBit("IsPseudoTarget") || isGenericTarget(Member)) {
      PrintFatalError(GPU->getLoc(),
                      "generic target '" + Name + "' covers '" +
                          Member->getValueAsString("Name") +
                          "', which is not a concrete AMDGPU GPU");
    }

    SetVector<const Record *> MemberFeatures =
        collectGenericFeatures(Member, FeatureIdx);
    CoveredFeatures.insert_range(MemberFeatures);
    for (const Record *F : GenericFeatures) {
      if (!F->isSubClassOf("AMDGPUGenericAnyFeature") &&
          !MemberFeatures.contains(F)) {
        PrintFatalError(GPU->getLoc(),
                        "generic target '" + GPU->getValueAsString("Name") +
                            "' exposes feature '" +
                            F->getValueAsString("Name") +
                            "' not supported by covered GPU '" +
                            Member->getValueAsString("Name") + "'");
      }
    }
  }

  for (const Record *F : GenericFeatures) {
    if (!CoveredFeatures.contains(F)) {
      PrintFatalError(GPU->getLoc(),
                      "generic target '" + GPU->getValueAsString("Name") +
                          "' exposes feature '" + F->getValueAsString("Name") +
                          "' not supported by any covered GPU");
    }
  }
}

static void validateAMDGPU(const RecordKeeper &RK) {
  DenseMap<const Record *, unsigned> FeatureIdx;
  for (const auto &[Idx, F] :
       enumerate(collectFrontendFeatures(RK, "AMDGPUFrontendVisibleFeatures")))
    FeatureIdx[F] = Idx;

  for (const Record *GPU : RK.getAllDerivedDefinitions("AMDGPUGPUInfo"))
    validateGenericFeatures(GPU, FeatureIdx);
}

// Emit a GPU's feature bitset initializer: its feature closure intersected with
// the frontend-visible set \p FeatureIdx, e.g.
// "AMDGPUFeatureBitset({FEAT_DPP, FEAT_CI_INSTS})".
static void
emitFeatureBitset(raw_ostream &OS, StringRef BitsetType, StringRef EnumPrefix,
                  const Record *GPU,
                  const DenseMap<const Record *, unsigned> &FeatureIdx) {
  SetVector<const Record *> Closure;
  collectFeatureClosure(GPU, Closure);

  // Sort by bit index for stable output.
  SmallVector<std::pair<unsigned, StringRef>> Bits;
  for (const Record *F : Closure) {
    auto It = FeatureIdx.find(F);
    if (It != FeatureIdx.end())
      Bits.emplace_back(It->second, F->getValueAsString("Name"));
  }
  sort(Bits);

  OS << BitsetType << "({";
  ListSeparator LS(", ");
  for (const auto &[Idx, Name] : Bits) {
    OS << LS;
    emitFeatureEnum(OS, EnumPrefix, Name);
  }
  OS << "})";
}

// The value of the SubtargetFeature in \p GPU's closure that sets \p FieldName,
// or \p Default if it has none. Two features setting the same field to
// different values is an error: SubtargetFeature silently takes the larger.
static int64_t getFeatureValue(const Record *GPU, StringRef FieldName,
                               int64_t Default) {
  SetVector<const Record *> Closure;
  collectFeatureClosure(GPU, Closure);

  const Record *Found = nullptr;
  int64_t Value = Default;
  for (const Record *F : Closure) {
    if (F->getValueAsString("FieldName") != FieldName)
      continue;

    int64_t V;
    if (!to_integer(F->getValueAsString("Value"), V)) {
      PrintFatalError(F->getLoc(), "feature '" + F->getValueAsString("Name") +
                                       "' must have an integer value");
    }
    if (Found && V != Value) {
      PrintFatalError(GPU->getLoc(),
                      "GPU '" + GPU->getValueAsString("Name") +
                          "' gets conflicting '" + FieldName +
                          "' values from '" + Found->getValueAsString("Name") +
                          "' and '" + F->getValueAsString("Name") + "'");
    }
    Found = F;
    Value = V;
  }
  return Value;
}

/// 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,
                const DenseMap<const Record *, unsigned> &FeatureIdx) {
  std::vector<const Record *> Canon = collectAMDGPUCanonicals(RK);
  if (Canon.empty())
    return;

  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 << "  {" << Names.GetOrAddStringOffset(Name) << ", ";
    emitSubArch(OS, R);
    OS << ", ";
    emitFeatureBitset(OS, "AMDGPUFeatureBitset", "FEAT_", R, FeatureIdx);
    OS << ", ";
    emitIsaVersion(OS, R, '{', '}');
    SmallString<16> Family;
    raw_svector_ostream FamilyOS(Family);
    emitArchFamily(FamilyOS, R);
    OS << ", " << Names.GetOrAddStringOffset(Family) << ", "
       << getFeatureValue(R, "MaxWavesPerEU", 10) << ", "
       << getFeatureValue(R, "AddressableLocalMemorySize", 32768) << ", "
       << getFeatureValue(R, "LDSBankCount", 32) << ", "
       << getFeatureValue(R, "BufferResourceNumRecordsWidth", 0) << "},\n";
  }
  OS << "};\n"
        "#endif // GET_AMDGPU_GPU_TABLE\n\n";
}

// 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 =
      RK.getAllDerivedDefinitionsIfDefined("AMDGPUGPUInfo");
  ArrayRef<const Record *> Families =
      RK.getAllDerivedDefinitionsIfDefined("AMDGPUFamily");

  // The overrides come from generic targets' CoveredGPUs and AMDGPUFamily
  // members. std::array makes the R600 case (zero entries) well-formed.
  size_t NumEntries = 0;
  for (const Record *G : GPUs)
    NumEntries += G->getValueAsListOfDefs("CoveredGPUs").size();
  for (const Record *F : Families)
    NumEntries += F->getValueAsListOfDefs("Members").size();

  OS << "#ifdef GET_AMDGPU_MAJOR_SUBARCH\n"
        "#undef GET_AMDGPU_MAJOR_SUBARCH\n"
        "struct AMDGPUMajorSubArchEntry {\n"
        "  Triple::SubArchType SubArch;\n"
        "  Triple::SubArchType Major;\n"
        "};\n"
        "static constexpr std::array<AMDGPUMajorSubArchEntry, "
     << NumEntries << "> AMDGPUMajorSubArch = {{\n";

  // A "gfxN-generic" target's subarch is the major for every GPU it covers.
  for (const Record *G : GPUs) {
    for (const Record *Member : G->getValueAsListOfDefs("CoveredGPUs")) {
      OS << "  {";
      emitSubArchForName(OS, Member->getValueAsString("Name"));
      OS << ", ";
      emitSubArch(OS, G);
      OS << "},\n";
    }
  }

  // The gfx6/gfx7/gfx8 families have no generic target, so their major comes
  // from AMDGPUFamily::MajorSubArch.
  for (const Record *F : Families) {
    StringRef Major = F->getValueAsString("MajorSubArch");
    for (const Record *Member : F->getValueAsListOfDefs("Members")) {
      OS << "  {";
      emitSubArchForName(OS, Member->getValueAsString("Name"));
      OS << ", Triple::AMDGPUSubArch" << Major << "},\n";
    }
  }

  OS << "}};\n"
        "#endif // GET_AMDGPU_MAJOR_SUBARCH\n\n";
}

/// Emit the canonical GPU name for each AMDGPU subarch ("gfx900"), and it's
/// corresponding subarch ("amdgpu9.00")
static void emitAMDGPUSubArchNames(raw_ostream &OS, const RecordKeeper &RK,
                                   StringToOffsetTable &Names) {
  // A row of the generated table. \p Suffix is emitted verbatim after
  // "Triple::AMDGPUSubArch"; the two name offsets index the shared string pool.
  struct SubArchEntry {
    SmallString<16> Suffix;
    StringRef GPUName; // e.g. "gfx900".
    unsigned TripleNameOffset;
  };
  std::vector<SubArchEntry> Entries;

  for (const GPUEntry &E : collectGPUs(RK, /*WantR600=*/false)) {
    if (E.IsAlias || E.Rec->getValueAsBit("IsPseudoTarget"))
      continue;
    SubArchEntry Entry;
    Entry.GPUName = E.Rec->getValueAsString("Name");

    SmallString<16> TripleName;
    raw_svector_ostream TripleOS(TripleName);

    // An explicit subarch spelling supplies the enumerator suffix and triple
    // name, rather than the name/ISA version.
    if (std::optional<StringRef> Spelling = getSubArchSpelling(E.Rec)) {
      raw_svector_ostream SubArchOS(Entry.Suffix);
      emitSpellingSuffix(SubArchOS, *Spelling);
      TripleOS << "amdgpu" << *Spelling;
    } else {
      {
        raw_svector_ostream SubArchOS(Entry.Suffix);
        emitSubArchSuffix(SubArchOS, Entry.GPUName);
      }

      // A "gfxN-generic" target maps to the major-family subarch, so it takes
      // the family triple name; a concrete GPU derives it from the ISA version.
      if (isGenericTarget(E.Rec))
        emitFamilySubArchTripleName(TripleOS, Entry.Suffix);
      else
        emitConcreteSubArchTripleName(TripleOS, E.Rec);
    }
    Entry.TripleNameOffset = Names.GetOrAddStringOffset(TripleName);

    Entries.push_back(std::move(Entry));
  }

  for (const Record *F : RK.getAllDerivedDefinitionsIfDefined("AMDGPUFamily")) {
    std::vector<const Record *> Members = F->getValueAsListOfDefs("Members");
    StringRef Major = F->getValueAsString("MajorSubArch");
    SubArchEntry Entry;
    Entry.Suffix = Major;
    Entry.GPUName = Members.front()->getValueAsString("Name");

    SmallString<16> TripleName;
    raw_svector_ostream TripleOS(TripleName);
    emitFamilySubArchTripleName(TripleOS, Major);
    Entry.TripleNameOffset = Names.GetOrAddStringOffset(TripleName);

    Entries.push_back(std::move(Entry));
  }

  if (Entries.empty())
    return;

  unsigned NoSubArchOffset = Names.GetOrAddStringOffset("amdgpu");

  OS << "#ifdef GET_AMDGPU_SUBARCH_NAME\n"
        "#undef GET_AMDGPU_SUBARCH_NAME\n";
  OS << "static constexpr StringTable::Offset AMDGPUNoSubArchNameOffset = "
     << NoSubArchOffset << ";\n";
  OS << "struct AMDGPUSubArchNameEntry {\n"
        "  Triple::SubArchType SubArch;\n"
        "  StringTable::Offset NameOffset;\n"
        "  StringTable::Offset TripleNameOffset;\n"
        "};\n"
        "static constexpr AMDGPUSubArchNameEntry AMDGPUSubArchNames[] = {\n";
  for (const SubArchEntry &E : Entries)
    OS << "  {Triple::AMDGPUSubArch" << E.Suffix << ", "
       << Names.GetOrAddStringOffset(E.GPUName) << ", " << E.TripleNameOffset
       << "},\n";
  OS << "};\n"
        "#endif // GET_AMDGPU_SUBARCH_NAME\n\n";
}

static void emitAMDGPUTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
  validateAMDGPU(RK);

  OS << "// Autogenerated by AMDGPUTargetDefEmitter.cpp\n\n";
  // 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);

  // 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);

    // The R600 frontend feature enum and per-GPU bitsets share the R600 string
    // pool (feature names live alongside GPU names).
    std::vector<const Record *> Features =
        collectFrontendFeatures(RK, "R600FrontendVisibleFeatures");
    DenseMap<const Record *, unsigned> FeatureIdx;
    for (const auto &[Idx, F] : enumerate(Features))
      FeatureIdx[F] = Idx;

    std::vector<unsigned> FeatureOffsets =
        emitFeatureEnum(TablesOS, R600FeatureNaming, Features, Names);
    emitR600Table(TablesOS, RK, Names, FeatureIdx);
    emitFeatureNames(TablesOS, R600FeatureNaming, FeatureOffsets);
    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);

    // The frontend feature enum and per-GPU bitsets share the AMDGPU string
    // pool (feature names live alongside GPU names).
    std::vector<const Record *> Features =
        collectFrontendFeatures(RK, "AMDGPUFrontendVisibleFeatures");
    DenseMap<const Record *, unsigned> FeatureIdx;
    for (const auto &[Idx, F] : enumerate(Features))
      FeatureIdx[F] = Idx;

    std::vector<unsigned> FeatureOffsets =
        emitFeatureEnum(TablesOS, AMDGPUFeatureNaming, Features, Names);
    emitAMDGPUTable(TablesOS, RK, Names, FeatureIdx);
    emitFeatureNames(TablesOS, AMDGPUFeatureNaming, FeatureOffsets);
    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,
                                "Generate the list of AMDGPU GPUs");
