[llvm] [MC][NFC] Use EnumStrings for AtSpecifiers (PR #211827)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 24 08:17:42 PDT 2026


https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/211827

Store at specifiers without relocations using EnumStrings, reducing
.data.rel.ro by 4-5kiB. This also saves the more compactly at now 6B per
entry instead of 24B.


>From dd78a67446cf2c1ba3772983712632884134c36e Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Fri, 24 Jul 2026 15:17:00 +0000
Subject: [PATCH] [spr] initial version

Created using spr 1.3.8-wip
---
 llvm/include/llvm/MC/MCAsmInfo.h              |  17 +-
 llvm/lib/MC/MCAsmInfo.cpp                     |   9 +-
 .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp |  34 ++--
 .../AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp   |  22 ++-
 .../Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp  |  52 +++---
 .../CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp       |  10 +-
 .../Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp |  22 ++-
 .../M68k/MCTargetDesc/M68kMCAsmInfo.cpp       |  13 +-
 .../PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp     | 171 +++++++++---------
 .../SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp |  14 +-
 .../Target/VE/MCTargetDesc/VEMCAsmInfo.cpp    |  32 ++--
 .../MCTargetDesc/WebAssemblyMCAsmInfo.cpp     |  18 +-
 .../Target/X86/MCTargetDesc/X86MCAsmInfo.cpp  |  60 +++---
 .../Xtensa/MCTargetDesc/XtensaMCAsmInfo.cpp   |   6 +-
 14 files changed, 257 insertions(+), 223 deletions(-)

diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h
index 6b2922593600f..31490172c9295 100644
--- a/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/llvm/include/llvm/MC/MCAsmInfo.h
@@ -27,6 +27,7 @@
 
 namespace llvm {
 
+template <typename, unsigned> class EnumStrings;
 class MCAssembler;
 class MCContext;
 class MCCFIInstruction;
@@ -73,12 +74,8 @@ class LLVM_ABI MCAsmInfo {
                             /// quote, e.g., `'A`.
   };
 
-  // This describes a @ style relocation specifier (expr at specifier) supported by
-  // AsmParser::parsePrimaryExpr.
-  struct AtSpecifier {
-    uint32_t Kind;
-    StringRef Name;
-  };
+  /// Type for at specifiers. Currently, 16 bits is enough.
+  using AtSpecifierKind = uint16_t;
 
 protected:
   //===------------------------------------------------------------------===//
@@ -428,9 +425,11 @@ class LLVM_ABI MCAsmInfo {
   // If true, use Motorola-style integers in Assembly (ex. $0ac).
   bool UseMotorolaIntegers = false;
 
-  llvm::DenseMap<uint32_t, StringRef> AtSpecifierToName;
-  llvm::StringMap<uint32_t> NameToAtSpecifier;
-  void initializeAtSpecifiers(ArrayRef<AtSpecifier>);
+  // This describes a @ style relocation specifier (expr at specifier) supported by
+  // AsmParser::parsePrimaryExpr.
+  llvm::DenseMap<AtSpecifierKind, StringRef> AtSpecifierToName;
+  llvm::StringMap<AtSpecifierKind> NameToAtSpecifier;
+  void initializeAtSpecifiers(EnumStrings<AtSpecifierKind, 1>);
 
   // Lowercase identifiers (e.g. register names, dialect keywords) that must be
   // quoted when used as a symbol name.
diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp
index ff71de2b42866..5085eccdc8179 100644
--- a/llvm/lib/MC/MCAsmInfo.cpp
+++ b/llvm/lib/MC/MCAsmInfo.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/MCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/MC/MCContext.h"
@@ -103,15 +104,15 @@ bool MCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {
         (SectionName == ".bss" && !usesELFSectionDirectiveForBSS());
 }
 
-void MCAsmInfo::initializeAtSpecifiers(ArrayRef<AtSpecifier> Descs) {
+void MCAsmInfo::initializeAtSpecifiers(EnumStrings<AtSpecifierKind, 1> Descs) {
   assert(AtSpecifierToName.empty() && "cannot initialize twice");
   UseAtForSpecifier = true;
-  for (auto Desc : Descs) {
+  for (const auto &Desc : Descs) {
     [[maybe_unused]] auto It =
-        AtSpecifierToName.try_emplace(Desc.Kind, Desc.Name);
+        AtSpecifierToName.try_emplace(Desc.value(), Desc.name());
     assert(It.second && "duplicate Kind");
     [[maybe_unused]] auto It2 =
-        NameToAtSpecifier.try_emplace(Desc.Name.lower(), Desc.Kind);
+        NameToAtSpecifier.try_emplace(Desc.name().lower(), Desc.value());
     assert(It2.second);
   }
 }
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
index eecde72f9b861..deff9f2eae321 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AArch64MCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCStreamer.h"
@@ -31,25 +32,28 @@ static cl::opt<AsmWriterVariantTy> AsmWriterVariant(
     cl::values(clEnumValN(Generic, "generic", "Emit generic NEON assembly"),
                clEnumValN(Apple, "apple", "Emit Apple-style NEON assembly")));
 
-const MCAsmInfo::AtSpecifier COFFAtSpecifiers[] = {
-    {MCSymbolRefExpr::VK_COFF_IMGREL32, "IMGREL"},
-    {AArch64::S_MACHO_PAGEOFF, "PAGEOFF"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> COFFAtSpecifierDefs[] = {
+    {{"IMGREL"}, MCSymbolRefExpr::VK_COFF_IMGREL32},
+    {{"PAGEOFF"}, AArch64::S_MACHO_PAGEOFF},
 };
+constexpr auto COFFAtSpecifiers = BUILD_ENUM_STRINGS(COFFAtSpecifierDefs);
 
-const MCAsmInfo::AtSpecifier ELFAtSpecifiers[] = {
-    {AArch64::S_GOT, "GOT"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> ELFAtSpecifierDefs[] = {
+    {{"GOT"}, AArch64::S_GOT},
 };
-
-const MCAsmInfo::AtSpecifier MachOAtSpecifiers[] = {
-    {AArch64::S_MACHO_GOT, "GOT"},
-    {AArch64::S_MACHO_GOTPAGE, "GOTPAGE"},
-    {AArch64::S_MACHO_GOTPAGEOFF, "GOTPAGEOFF"},
-    {AArch64::S_MACHO_PAGE, "PAGE"},
-    {AArch64::S_MACHO_PAGEOFF, "PAGEOFF"},
-    {AArch64::S_MACHO_TLVP, "TLVP"},
-    {AArch64::S_MACHO_TLVPPAGE, "TLVPPAGE"},
-    {AArch64::S_MACHO_TLVPPAGEOFF, "TLVPPAGEOFF"},
+constexpr auto ELFAtSpecifiers = BUILD_ENUM_STRINGS(ELFAtSpecifierDefs);
+
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> MachOAtSpecifierDefs[] = {
+    {{"GOT"}, AArch64::S_MACHO_GOT},
+    {{"GOTPAGE"}, AArch64::S_MACHO_GOTPAGE},
+    {{"GOTPAGEOFF"}, AArch64::S_MACHO_GOTPAGEOFF},
+    {{"PAGE"}, AArch64::S_MACHO_PAGE},
+    {{"PAGEOFF"}, AArch64::S_MACHO_PAGEOFF},
+    {{"TLVP"}, AArch64::S_MACHO_TLVP},
+    {{"TLVPPAGE"}, AArch64::S_MACHO_TLVPPAGE},
+    {{"TLVPPAGEOFF"}, AArch64::S_MACHO_TLVPPAGEOFF},
 };
+constexpr auto MachOAtSpecifiers = BUILD_ENUM_STRINGS(MachOAtSpecifierDefs);
 
 StringRef AArch64::getSpecifierName(AArch64::Specifier S) {
   // clang-format off
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
index f5e6941b8691f..6da163637d99a 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
@@ -10,23 +10,25 @@
 #include "AMDGPUMCAsmInfo.h"
 #include "MCTargetDesc/AMDGPUMCExpr.h"
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {AMDGPUMCExpr::S_GOTPCREL, "gotpcrel"},
-    {AMDGPUMCExpr::S_GOTPCREL32_LO, "gotpcrel32 at lo"},
-    {AMDGPUMCExpr::S_GOTPCREL32_HI, "gotpcrel32 at hi"},
-    {AMDGPUMCExpr::S_REL32_LO, "rel32 at lo"},
-    {AMDGPUMCExpr::S_REL32_HI, "rel32 at hi"},
-    {AMDGPUMCExpr::S_REL64, "rel64"},
-    {AMDGPUMCExpr::S_ABS32_LO, "abs32 at lo"},
-    {AMDGPUMCExpr::S_ABS32_HI, "abs32 at hi"},
-    {AMDGPUMCExpr::S_ABS64, "abs64"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"gotpcrel"}, AMDGPUMCExpr::S_GOTPCREL},
+    {{"gotpcrel32 at lo"}, AMDGPUMCExpr::S_GOTPCREL32_LO},
+    {{"gotpcrel32 at hi"}, AMDGPUMCExpr::S_GOTPCREL32_HI},
+    {{"rel32 at lo"}, AMDGPUMCExpr::S_REL32_LO},
+    {{"rel32 at hi"}, AMDGPUMCExpr::S_REL32_HI},
+    {{"rel64"}, AMDGPUMCExpr::S_REL64},
+    {{"abs32 at lo"}, AMDGPUMCExpr::S_ABS32_LO},
+    {{"abs32 at hi"}, AMDGPUMCExpr::S_ABS32_HI},
+    {{"abs64"}, AMDGPUMCExpr::S_ABS64},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 AMDGPUMCAsmInfo::AMDGPUMCAsmInfo(const Triple &TT,
                                  const MCTargetOptions &Options)
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
index d6abb2485a003..c2fd9e98d168c 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
@@ -11,38 +11,40 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARMMCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {ARM::S_GOT_PREL, "GOT_PREL"},
-    {ARM::S_ARM_NONE, "none"},
-    {ARM::S_PREL31, "prel31"},
-    {ARM::S_SBREL, "sbrel"},
-    {ARM::S_TARGET1, "target1"},
-    {ARM::S_TARGET2, "target2"},
-    {ARM::S_TLSLDO, "TLSLDO"},
-    {MCSymbolRefExpr::VK_COFF_IMGREL32, "imgrel"},
-    {ARM::S_FUNCDESC, "FUNCDESC"},
-    {ARM::S_GOT, "GOT"},
-    {ARM::S_GOTFUNCDESC, "GOTFUNCDESC"},
-    {ARM::S_GOTOFF, "GOTOFF"},
-    {ARM::S_GOTOFFFUNCDESC, "GOTOFFFUNCDESC"},
-    {ARM::S_GOTTPOFF, "GOTTPOFF"},
-    {ARM::S_GOTTPOFF_FDPIC, "gottpoff_fdpic"},
-    {ARM::S_PLT, "PLT"},
-    {ARM::S_COFF_SECREL, "SECREL32"},
-    {ARM::S_TLSCALL, "tlscall"},
-    {ARM::S_TLSDESC, "tlsdesc"},
-    {ARM::S_TLSGD, "TLSGD"},
-    {ARM::S_TLSGD_FDPIC, "tlsgd_fdpic"},
-    {ARM::S_TLSLDM, "TLSLDM"},
-    {ARM::S_TLSLDM_FDPIC, "tlsldm_fdpic"},
-    {ARM::S_TPOFF, "TPOFF"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"GOT_PREL"}, ARM::S_GOT_PREL},
+    {{"none"}, ARM::S_ARM_NONE},
+    {{"prel31"}, ARM::S_PREL31},
+    {{"sbrel"}, ARM::S_SBREL},
+    {{"target1"}, ARM::S_TARGET1},
+    {{"target2"}, ARM::S_TARGET2},
+    {{"TLSLDO"}, ARM::S_TLSLDO},
+    {{"imgrel"}, MCSymbolRefExpr::VK_COFF_IMGREL32},
+    {{"FUNCDESC"}, ARM::S_FUNCDESC},
+    {{"GOT"}, ARM::S_GOT},
+    {{"GOTFUNCDESC"}, ARM::S_GOTFUNCDESC},
+    {{"GOTOFF"}, ARM::S_GOTOFF},
+    {{"GOTOFFFUNCDESC"}, ARM::S_GOTOFFFUNCDESC},
+    {{"GOTTPOFF"}, ARM::S_GOTTPOFF},
+    {{"gottpoff_fdpic"}, ARM::S_GOTTPOFF_FDPIC},
+    {{"PLT"}, ARM::S_PLT},
+    {{"SECREL32"}, ARM::S_COFF_SECREL},
+    {{"tlscall"}, ARM::S_TLSCALL},
+    {{"tlsdesc"}, ARM::S_TLSDESC},
+    {{"TLSGD"}, ARM::S_TLSGD},
+    {{"tlsgd_fdpic"}, ARM::S_TLSGD_FDPIC},
+    {{"TLSLDM"}, ARM::S_TLSLDM},
+    {{"tlsldm_fdpic"}, ARM::S_TLSLDM_FDPIC},
+    {{"TPOFF"}, ARM::S_TPOFF},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 void ARMMCAsmInfoDarwin::anchor() { }
 
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp
index b7b1999d243c8..f055d7bf9d5d7 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp
@@ -12,17 +12,19 @@
 
 #include "CSKYMCAsmInfo.h"
 #include "MCTargetDesc/CSKYMCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCStreamer.h"
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {CSKY::S_GOT, "GOT"},       {CSKY::S_GOTOFF, "GOTOFF"},
-    {CSKY::S_PLT, "PLT"},       {CSKY::S_TLSGD, "TLSGD"},
-    {CSKY::S_TLSLDM, "TLSLDM"}, {CSKY::S_TPOFF, "TPOFF"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"GOT"}, CSKY::S_GOT},       {{"GOTOFF"}, CSKY::S_GOTOFF},
+    {{"PLT"}, CSKY::S_PLT},       {{"TLSGD"}, CSKY::S_TLSGD},
+    {{"TLSLDM"}, CSKY::S_TLSLDM}, {{"TPOFF"}, CSKY::S_TPOFF},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 void CSKYMCAsmInfo::anchor() {}
 
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
index 02726e977f5a4..8c91fad24dbf0 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
@@ -12,18 +12,26 @@
 
 #include "HexagonMCAsmInfo.h"
 #include "MCTargetDesc/HexagonMCExpr.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {HexagonMCExpr::VK_DTPREL, "DTPREL"}, {HexagonMCExpr::VK_GD_GOT, "GDGOT"},
-    {HexagonMCExpr::VK_GD_PLT, "GDPLT"},  {HexagonMCExpr::VK_GOT, "GOT"},
-    {HexagonMCExpr::VK_GOTREL, "GOTREL"}, {HexagonMCExpr::VK_IE, "IE"},
-    {HexagonMCExpr::VK_IE_GOT, "IEGOT"},  {HexagonMCExpr::VK_LD_GOT, "LDGOT"},
-    {HexagonMCExpr::VK_LD_PLT, "LDPLT"},  {HexagonMCExpr::VK_PCREL, "PCREL"},
-    {HexagonMCExpr::VK_PLT, "PLT"},       {HexagonMCExpr::VK_TPREL, "TPREL"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"DTPREL"}, HexagonMCExpr::VK_DTPREL},
+    {{"GDGOT"}, HexagonMCExpr::VK_GD_GOT},
+    {{"GDPLT"}, HexagonMCExpr::VK_GD_PLT},
+    {{"GOT"}, HexagonMCExpr::VK_GOT},
+    {{"GOTREL"}, HexagonMCExpr::VK_GOTREL},
+    {{"IE"}, HexagonMCExpr::VK_IE},
+    {{"IEGOT"}, HexagonMCExpr::VK_IE_GOT},
+    {{"LDGOT"}, HexagonMCExpr::VK_LD_GOT},
+    {{"LDPLT"}, HexagonMCExpr::VK_LD_PLT},
+    {{"PCREL"}, HexagonMCExpr::VK_PCREL},
+    {{"PLT"}, HexagonMCExpr::VK_PLT},
+    {{"TPREL"}, HexagonMCExpr::VK_TPREL},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 // Pin the vtable to this file.
 void HexagonMCAsmInfo::anchor() {}
diff --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kMCAsmInfo.cpp b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCAsmInfo.cpp
index 095732a4da602..a0c119e5a3f30 100644
--- a/llvm/lib/Target/M68k/MCTargetDesc/M68kMCAsmInfo.cpp
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCAsmInfo.cpp
@@ -12,18 +12,19 @@
 //===----------------------------------------------------------------------===//
 
 #include "M68kMCAsmInfo.h"
-
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {M68k::S_GOTOFF, "GOTOFF"},     {M68k::S_GOTPCREL, "GOTPCREL"},
-    {M68k::S_GOTTPOFF, "GOTTPOFF"}, {M68k::S_PLT, "PLT"},
-    {M68k::S_TLSGD, "TLSGD"},       {M68k::S_TLSLD, "TLSLD"},
-    {M68k::S_TLSLDM, "TLSLDM"},     {M68k::S_TPOFF, "TPOFF"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"GOTOFF"}, M68k::S_GOTOFF},     {{"GOTPCREL"}, M68k::S_GOTPCREL},
+    {{"GOTTPOFF"}, M68k::S_GOTTPOFF}, {{"PLT"}, M68k::S_PLT},
+    {{"TLSGD"}, M68k::S_TLSGD},       {{"TLSLD"}, M68k::S_TLSLD},
+    {{"TLSLDM"}, M68k::S_TLSLDM},     {{"TPOFF"}, M68k::S_TPOFF},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 void M68kELFMCAsmInfo::anchor() {}
 
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
index 4665448edb303..63a8142f1885f 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/PPCMCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
@@ -19,95 +20,97 @@ using namespace llvm;
 
 void PPCELFMCAsmInfo::anchor() { }
 
-const MCAsmInfo::AtSpecifier elfAtSpecifiers[] = {
-    {PPC::S_DTPREL, "DTPREL"},
-    {PPC::S_GOT, "GOT"},
-    {PPC::S_GOT_HA, "got at ha"},
-    {PPC::S_GOT_HI, "got at h"},
-    {PPC::S_GOT_LO, "got at l"},
-    {PPC::S_HA, "ha"},
-    {PPC::S_HI, "h"},
-    {PPC::S_HIGH, "high"},
-    {PPC::S_HIGHA, "higha"},
-    {PPC::S_HIGHER, "higher"},
-    {PPC::S_HIGHERA, "highera"},
-    {PPC::S_HIGHEST, "highest"},
-    {PPC::S_HIGHESTA, "highesta"},
-    {PPC::S_LO, "l"},
-    {PPC::S_PCREL, "PCREL"},
-    {PPC::S_PLT, "PLT"},
-    {PPC::S_TLSGD, "tlsgd"},
-    {PPC::S_TLSLD, "tlsld"},
-    {PPC::S_TOC, "toc"},
-    {PPC::S_TOCBASE, "tocbase"},
-    {PPC::S_TOC_HA, "toc at ha"},
-    {PPC::S_TOC_HI, "toc at h"},
-    {PPC::S_TOC_LO, "toc at l"},
-    {PPC::S_TPREL, "TPREL"},
-    {PPC::S_AIX_TLSGD, "gd"},
-    {PPC::S_AIX_TLSGDM, "m"},
-    {PPC::S_AIX_TLSIE, "ie"},
-    {PPC::S_AIX_TLSLD, "ld"},
-    {PPC::S_AIX_TLSLE, "le"},
-    {PPC::S_AIX_TLSML, "ml"},
-    {PPC::S_DTPMOD, "dtpmod"},
-    {PPC::S_DTPREL_HA, "dtprel at ha"},
-    {PPC::S_DTPREL_HI, "dtprel at h"},
-    {PPC::S_DTPREL_HIGH, "dtprel at high"},
-    {PPC::S_DTPREL_HIGHA, "dtprel at higha"},
-    {PPC::S_DTPREL_HIGHER, "dtprel at higher"},
-    {PPC::S_DTPREL_HIGHERA, "dtprel at highera"},
-    {PPC::S_DTPREL_HIGHEST, "dtprel at highest"},
-    {PPC::S_DTPREL_HIGHESTA, "dtprel at highesta"},
-    {PPC::S_DTPREL_LO, "dtprel at l"},
-    {PPC::S_GOT_DTPREL, "got at dtprel"},
-    {PPC::S_GOT_DTPREL_HA, "got at dtprel@ha"},
-    {PPC::S_GOT_DTPREL_HI, "got at dtprel@h"},
-    {PPC::S_GOT_DTPREL_LO, "got at dtprel@l"},
-    {PPC::S_GOT_PCREL, "got at pcrel"},
-    {PPC::S_GOT_TLSGD, "got at tlsgd"},
-    {PPC::S_GOT_TLSGD_HA, "got at tlsgd@ha"},
-    {PPC::S_GOT_TLSGD_HI, "got at tlsgd@h"},
-    {PPC::S_GOT_TLSGD_LO, "got at tlsgd@l"},
-    {PPC::S_GOT_TLSGD_PCREL, "got at tlsgd@pcrel"},
-    {PPC::S_GOT_TLSLD, "got at tlsld"},
-    {PPC::S_GOT_TLSLD_HA, "got at tlsld@ha"},
-    {PPC::S_GOT_TLSLD_HI, "got at tlsld@h"},
-    {PPC::S_GOT_TLSLD_LO, "got at tlsld@l"},
-    {PPC::S_GOT_TLSLD_PCREL, "got at tlsld@pcrel"},
-    {PPC::S_GOT_TPREL, "got at tprel"},
-    {PPC::S_GOT_TPREL_HA, "got at tprel@ha"},
-    {PPC::S_GOT_TPREL_HI, "got at tprel@h"},
-    {PPC::S_GOT_TPREL_LO, "got at tprel@l"},
-    {PPC::S_GOT_TPREL_PCREL, "got at tprel@pcrel"},
-    {PPC::S_LOCAL, "local"},
-    {PPC::S_NOTOC, "notoc"},
-    {PPC::S_PCREL_OPT, "<<invalid>>"},
-    {PPC::S_TLS, "tls"},
-    {PPC::S_TLS_PCREL, "tls at pcrel"},
-    {PPC::S_TPREL_HA, "tprel at ha"},
-    {PPC::S_TPREL_HI, "tprel at h"},
-    {PPC::S_TPREL_HIGH, "tprel at high"},
-    {PPC::S_TPREL_HIGHA, "tprel at higha"},
-    {PPC::S_TPREL_HIGHER, "tprel at higher"},
-    {PPC::S_TPREL_HIGHERA, "tprel at highera"},
-    {PPC::S_TPREL_HIGHEST, "tprel at highest"},
-    {PPC::S_TPREL_HIGHESTA, "tprel at highesta"},
-    {PPC::S_TPREL_LO, "tprel at l"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> ELFAtSpecifierDefs[] = {
+    {{"DTPREL"}, PPC::S_DTPREL},
+    {{"GOT"}, PPC::S_GOT},
+    {{"got at ha"}, PPC::S_GOT_HA},
+    {{"got at h"}, PPC::S_GOT_HI},
+    {{"got at l"}, PPC::S_GOT_LO},
+    {{"ha"}, PPC::S_HA},
+    {{"h"}, PPC::S_HI},
+    {{"high"}, PPC::S_HIGH},
+    {{"higha"}, PPC::S_HIGHA},
+    {{"higher"}, PPC::S_HIGHER},
+    {{"highera"}, PPC::S_HIGHERA},
+    {{"highest"}, PPC::S_HIGHEST},
+    {{"highesta"}, PPC::S_HIGHESTA},
+    {{"l"}, PPC::S_LO},
+    {{"PCREL"}, PPC::S_PCREL},
+    {{"PLT"}, PPC::S_PLT},
+    {{"tlsgd"}, PPC::S_TLSGD},
+    {{"tlsld"}, PPC::S_TLSLD},
+    {{"toc"}, PPC::S_TOC},
+    {{"tocbase"}, PPC::S_TOCBASE},
+    {{"toc at ha"}, PPC::S_TOC_HA},
+    {{"toc at h"}, PPC::S_TOC_HI},
+    {{"toc at l"}, PPC::S_TOC_LO},
+    {{"TPREL"}, PPC::S_TPREL},
+    {{"gd"}, PPC::S_AIX_TLSGD},
+    {{"m"}, PPC::S_AIX_TLSGDM},
+    {{"ie"}, PPC::S_AIX_TLSIE},
+    {{"ld"}, PPC::S_AIX_TLSLD},
+    {{"le"}, PPC::S_AIX_TLSLE},
+    {{"ml"}, PPC::S_AIX_TLSML},
+    {{"dtpmod"}, PPC::S_DTPMOD},
+    {{"dtprel at ha"}, PPC::S_DTPREL_HA},
+    {{"dtprel at h"}, PPC::S_DTPREL_HI},
+    {{"dtprel at high"}, PPC::S_DTPREL_HIGH},
+    {{"dtprel at higha"}, PPC::S_DTPREL_HIGHA},
+    {{"dtprel at higher"}, PPC::S_DTPREL_HIGHER},
+    {{"dtprel at highera"}, PPC::S_DTPREL_HIGHERA},
+    {{"dtprel at highest"}, PPC::S_DTPREL_HIGHEST},
+    {{"dtprel at highesta"}, PPC::S_DTPREL_HIGHESTA},
+    {{"dtprel at l"}, PPC::S_DTPREL_LO},
+    {{"got at dtprel"}, PPC::S_GOT_DTPREL},
+    {{"got at dtprel@ha"}, PPC::S_GOT_DTPREL_HA},
+    {{"got at dtprel@h"}, PPC::S_GOT_DTPREL_HI},
+    {{"got at dtprel@l"}, PPC::S_GOT_DTPREL_LO},
+    {{"got at pcrel"}, PPC::S_GOT_PCREL},
+    {{"got at tlsgd"}, PPC::S_GOT_TLSGD},
+    {{"got at tlsgd@ha"}, PPC::S_GOT_TLSGD_HA},
+    {{"got at tlsgd@h"}, PPC::S_GOT_TLSGD_HI},
+    {{"got at tlsgd@l"}, PPC::S_GOT_TLSGD_LO},
+    {{"got at tlsgd@pcrel"}, PPC::S_GOT_TLSGD_PCREL},
+    {{"got at tlsld"}, PPC::S_GOT_TLSLD},
+    {{"got at tlsld@ha"}, PPC::S_GOT_TLSLD_HA},
+    {{"got at tlsld@h"}, PPC::S_GOT_TLSLD_HI},
+    {{"got at tlsld@l"}, PPC::S_GOT_TLSLD_LO},
+    {{"got at tlsld@pcrel"}, PPC::S_GOT_TLSLD_PCREL},
+    {{"got at tprel"}, PPC::S_GOT_TPREL},
+    {{"got at tprel@ha"}, PPC::S_GOT_TPREL_HA},
+    {{"got at tprel@h"}, PPC::S_GOT_TPREL_HI},
+    {{"got at tprel@l"}, PPC::S_GOT_TPREL_LO},
+    {{"got at tprel@pcrel"}, PPC::S_GOT_TPREL_PCREL},
+    {{"local"}, PPC::S_LOCAL},
+    {{"notoc"}, PPC::S_NOTOC},
+    {{"<<invalid>>"}, PPC::S_PCREL_OPT},
+    {{"tls"}, PPC::S_TLS},
+    {{"tls at pcrel"}, PPC::S_TLS_PCREL},
+    {{"tprel at ha"}, PPC::S_TPREL_HA},
+    {{"tprel at h"}, PPC::S_TPREL_HI},
+    {{"tprel at high"}, PPC::S_TPREL_HIGH},
+    {{"tprel at higha"}, PPC::S_TPREL_HIGHA},
+    {{"tprel at higher"}, PPC::S_TPREL_HIGHER},
+    {{"tprel at highera"}, PPC::S_TPREL_HIGHERA},
+    {{"tprel at highest"}, PPC::S_TPREL_HIGHEST},
+    {{"tprel at highesta"}, PPC::S_TPREL_HIGHESTA},
+    {{"tprel at l"}, PPC::S_TPREL_LO},
 };
+constexpr auto elfAtSpecifiers = BUILD_ENUM_STRINGS(ELFAtSpecifierDefs);
 
-const MCAsmInfo::AtSpecifier xcoffAtSpecifiers[] = {
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> XCOFFAtSpecifierDefs[] = {
     // clang-format off
-    {PPC::S_AIX_TLSGD, "gd"},
-    {PPC::S_AIX_TLSGDM, "m"},
-    {PPC::S_AIX_TLSIE, "ie"},
-    {PPC::S_AIX_TLSLD, "ld"},
-    {PPC::S_AIX_TLSLE, "le"},
-    {PPC::S_AIX_TLSML, "ml"},
-    {PPC::S_L, "l"},
-    {PPC::S_U, "u"},
+    {{"gd"}, PPC::S_AIX_TLSGD},
+    {{"m"}, PPC::S_AIX_TLSGDM},
+    {{"ie"}, PPC::S_AIX_TLSIE},
+    {{"ld"}, PPC::S_AIX_TLSLD},
+    {{"le"}, PPC::S_AIX_TLSLE},
+    {{"ml"}, PPC::S_AIX_TLSML},
+    {{"l"}, PPC::S_L},
+    {{"u"}, PPC::S_U},
     // clang-format on
 };
+constexpr auto xcoffAtSpecifiers = BUILD_ENUM_STRINGS(XCOFFAtSpecifierDefs);
 
 static std::optional<int64_t> evaluateAsInt64(uint16_t specifier,
                                               int64_t Value) {
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
index 5247cff34ba01..defd86169e059 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
@@ -7,19 +7,21 @@
 //===----------------------------------------------------------------------===//
 
 #include "SystemZMCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCValue.h"
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {SystemZ::S_DTPOFF, "DTPOFF"}, {SystemZ::S_GOT, "GOT"},
-    {SystemZ::S_GOTENT, "GOTENT"}, {SystemZ::S_INDNTPOFF, "INDNTPOFF"},
-    {SystemZ::S_NTPOFF, "NTPOFF"}, {SystemZ::S_PLT, "PLT"},
-    {SystemZ::S_TLSGD, "TLSGD"},   {SystemZ::S_TLSLD, "TLSLD"},
-    {SystemZ::S_TLSLDM, "TLSLDM"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"DTPOFF"}, SystemZ::S_DTPOFF}, {{"GOT"}, SystemZ::S_GOT},
+    {{"GOTENT"}, SystemZ::S_GOTENT}, {{"INDNTPOFF"}, SystemZ::S_INDNTPOFF},
+    {{"NTPOFF"}, SystemZ::S_NTPOFF}, {{"PLT"}, SystemZ::S_PLT},
+    {{"TLSGD"}, SystemZ::S_TLSGD},   {{"TLSLD"}, SystemZ::S_TLSLD},
+    {{"TLSLDM"}, SystemZ::S_TLSLDM},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 SystemZMCAsmInfoELF::SystemZMCAsmInfoELF(const Triple &TT,
                                          const MCTargetOptions &Options)
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
index af907d46a10d0..aef303835ac8c 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "VEMCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCValue.h"
@@ -18,22 +19,23 @@
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {VE::S_HI32, "hi"},
-    {VE::S_LO32, "lo"},
-    {VE::S_PC_HI32, "pc_hi"},
-    {VE::S_PC_LO32, "pc_lo"},
-    {VE::S_GOT_HI32, "got_hi"},
-    {VE::S_GOT_LO32, "got_lo"},
-    {VE::S_GOTOFF_HI32, "gotoff_hi"},
-    {VE::S_GOTOFF_LO32, "gotoff_lo"},
-    {VE::S_PLT_HI32, "plt_hi"},
-    {VE::S_PLT_LO32, "plt_lo"},
-    {VE::S_TLS_GD_HI32, "tls_gd_hi"},
-    {VE::S_TLS_GD_LO32, "tls_gd_lo"},
-    {VE::S_TPOFF_HI32, "tpoff_hi"},
-    {VE::S_TPOFF_LO32, "tpoff_lo"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"hi"}, VE::S_HI32},
+    {{"lo"}, VE::S_LO32},
+    {{"pc_hi"}, VE::S_PC_HI32},
+    {{"pc_lo"}, VE::S_PC_LO32},
+    {{"got_hi"}, VE::S_GOT_HI32},
+    {{"got_lo"}, VE::S_GOT_LO32},
+    {{"gotoff_hi"}, VE::S_GOTOFF_HI32},
+    {{"gotoff_lo"}, VE::S_GOTOFF_LO32},
+    {{"plt_hi"}, VE::S_PLT_HI32},
+    {{"plt_lo"}, VE::S_PLT_LO32},
+    {{"tls_gd_hi"}, VE::S_TLS_GD_HI32},
+    {{"tls_gd_lo"}, VE::S_TLS_GD_LO32},
+    {{"tpoff_hi"}, VE::S_TPOFF_HI32},
+    {{"tpoff_lo"}, VE::S_TPOFF_LO32},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 VE::Fixups VE::getFixupKind(uint8_t S) {
   switch (S) {
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
index 2a2545ff93cc9..1746c1a2719ab 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
@@ -14,6 +14,7 @@
 
 #include "WebAssemblyMCAsmInfo.h"
 #include "WebAssemblyMCTargetDesc.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/TargetParser/Triple.h"
 
@@ -21,15 +22,16 @@ using namespace llvm;
 
 #define DEBUG_TYPE "wasm-mc-asm-info"
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {WebAssembly::S_TYPEINDEX, "TYPEINDEX"},
-    {WebAssembly::S_TBREL, "TBREL"},
-    {WebAssembly::S_MBREL, "MBREL"},
-    {WebAssembly::S_TLSREL, "TLSREL"},
-    {WebAssembly::S_GOT, "GOT"},
-    {WebAssembly::S_GOT_TLS, "GOT at TLS"},
-    {WebAssembly::S_FUNCINDEX, "FUNCINDEX"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"TYPEINDEX"}, WebAssembly::S_TYPEINDEX},
+    {{"TBREL"}, WebAssembly::S_TBREL},
+    {{"MBREL"}, WebAssembly::S_MBREL},
+    {{"TLSREL"}, WebAssembly::S_TLSREL},
+    {{"GOT"}, WebAssembly::S_GOT},
+    {{"GOT at TLS"}, WebAssembly::S_GOT_TLS},
+    {{"FUNCINDEX"}, WebAssembly::S_FUNCINDEX},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 WebAssemblyMCAsmInfo::~WebAssemblyMCAsmInfo() = default; // anchor.
 
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
index adb7bd2e58f96..ccf394b3a4870 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86MCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/Support/CommandLine.h"
@@ -34,36 +35,37 @@ MarkedJTDataRegions("mark-data-regions", cl::init(true),
   cl::desc("Mark code section jump table data regions."),
   cl::Hidden);
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {
-    {X86::S_ABS8, "ABS8"},
-    {X86::S_DTPOFF, "DTPOFF"},
-    {X86::S_DTPREL, "DTPREL"},
-    {X86::S_GOT, "GOT"},
-    {X86::S_GOTENT, "GOTENT"},
-    {X86::S_GOTNTPOFF, "GOTNTPOFF"},
-    {X86::S_GOTOFF, "GOTOFF"},
-    {X86::S_GOTPCREL, "GOTPCREL"},
-    {X86::S_GOTPCREL_NORELAX, "GOTPCREL_NORELAX"},
-    {X86::S_GOTREL, "GOTREL"},
-    {X86::S_GOTTPOFF, "GOTTPOFF"},
-    {X86::S_INDNTPOFF, "INDNTPOFF"},
-    {MCSymbolRefExpr::VK_COFF_IMGREL32, "IMGREL"},
-    {X86::S_NTPOFF, "NTPOFF"},
-    {X86::S_PCREL, "PCREL"},
-    {X86::S_PLT, "PLT"},
-    {X86::S_PLTOFF, "PLTOFF"},
-    {X86::S_COFF_SECREL, "SECREL32"},
-    {X86::S_SIZE, "SIZE"},
-    {X86::S_TLSCALL, "tlscall"},
-    {X86::S_TLSDESC, "tlsdesc"},
-    {X86::S_TLSGD, "TLSGD"},
-    {X86::S_TLSLD, "TLSLD"},
-    {X86::S_TLSLDM, "TLSLDM"},
-    {X86::S_TLVP, "TLVP"},
-    {X86::S_TLVPPAGE, "TLVPPAGE"},
-    {X86::S_TLVPPAGEOFF, "TLVPPAGEOFF"},
-    {X86::S_TPOFF, "TPOFF"},
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"ABS8"}, X86::S_ABS8},
+    {{"DTPOFF"}, X86::S_DTPOFF},
+    {{"DTPREL"}, X86::S_DTPREL},
+    {{"GOT"}, X86::S_GOT},
+    {{"GOTENT"}, X86::S_GOTENT},
+    {{"GOTNTPOFF"}, X86::S_GOTNTPOFF},
+    {{"GOTOFF"}, X86::S_GOTOFF},
+    {{"GOTPCREL"}, X86::S_GOTPCREL},
+    {{"GOTPCREL_NORELAX"}, X86::S_GOTPCREL_NORELAX},
+    {{"GOTREL"}, X86::S_GOTREL},
+    {{"GOTTPOFF"}, X86::S_GOTTPOFF},
+    {{"INDNTPOFF"}, X86::S_INDNTPOFF},
+    {{"IMGREL"}, MCSymbolRefExpr::VK_COFF_IMGREL32},
+    {{"NTPOFF"}, X86::S_NTPOFF},
+    {{"PCREL"}, X86::S_PCREL},
+    {{"PLT"}, X86::S_PLT},
+    {{"PLTOFF"}, X86::S_PLTOFF},
+    {{"SECREL32"}, X86::S_COFF_SECREL},
+    {{"SIZE"}, X86::S_SIZE},
+    {{"tlscall"}, X86::S_TLSCALL},
+    {{"tlsdesc"}, X86::S_TLSDESC},
+    {{"TLSGD"}, X86::S_TLSGD},
+    {{"TLSLD"}, X86::S_TLSLD},
+    {{"TLSLDM"}, X86::S_TLSLDM},
+    {{"TLVP"}, X86::S_TLVP},
+    {{"TLVPPAGE"}, X86::S_TLVPPAGE},
+    {{"TLVPPAGEOFF"}, X86::S_TLVPPAGEOFF},
+    {{"TPOFF"}, X86::S_TPOFF},
 };
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 void X86MCAsmInfoDarwin::anchor() { }
 
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCAsmInfo.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCAsmInfo.cpp
index de15486337343..4fd924bfcf943 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCAsmInfo.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCAsmInfo.cpp
@@ -13,12 +13,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "XtensaMCAsmInfo.h"
+#include "llvm/ADT/Enum.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 
-const MCAsmInfo::AtSpecifier atSpecifiers[] = {{Xtensa::S_TPOFF, "TPOFF"}};
+constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
+    {{"TPOFF"}, Xtensa::S_TPOFF},
+};
+constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
 
 XtensaMCAsmInfo::XtensaMCAsmInfo(const Triple &TT,
                                  const MCTargetOptions &Options)



More information about the llvm-commits mailing list