[clang] [llvm] [TargetParser][ARM][NFC] Make string tables reloc-free (PR #206937)
Alexis Engelke via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 1 04:12:08 PDT 2026
https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/206937
>From a99b803017af3bca32f1dc6ed1f42dccaa0f7f26 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 1 Jul 2026 10:12:48 +0000
Subject: [PATCH 1/2] [spr] initial version
Created using spr 1.3.8-wip
---
clang/lib/Driver/ToolChain.cpp | 17 +-
clang/lib/Driver/ToolChains/Arch/ARM.cpp | 7 +-
clang/lib/Driver/ToolChains/CommonArgs.cpp | 3 +-
.../llvm/TargetParser/ARMTargetParser.h | 91 +------
llvm/lib/TargetParser/ARMTargetParser.cpp | 229 ++++++++++++------
.../TargetParser/TargetParserTest.cpp | 23 +-
6 files changed, 185 insertions(+), 185 deletions(-)
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 21d2fbef59fc6..317263d581732 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -25,6 +25,7 @@
#include "clang/Driver/SanitizerArgs.h"
#include "clang/Driver/XRayArgs.h"
#include "clang/Options/Options.h"
+#include "llvm/ADT/Enum.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -351,14 +352,14 @@ static void getARMMultilibFlags(const Driver &D, const llvm::Triple &Triple,
llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
UnifiedFeatures.end());
std::vector<std::string> MArch;
- for (const auto &Ext : ARM::ARCHExtNames)
- if (!Ext.Name.empty())
- if (FeatureSet.contains(Ext.Feature))
- MArch.push_back(Ext.Name.str());
- for (const auto &Ext : ARM::ARCHExtNames)
- if (!Ext.Name.empty())
- if (FeatureSet.contains(Ext.NegFeature))
- MArch.push_back(("no" + Ext.Name).str());
+ for (const auto &Ext : ARM::getArchExts())
+ if (!Ext.name().empty())
+ if (FeatureSet.contains(Ext.name(1)))
+ MArch.push_back(Ext.name().str());
+ for (const auto &Ext : ARM::getArchExts())
+ if (!Ext.name().empty())
+ if (FeatureSet.contains(Ext.name(2)))
+ MArch.push_back(("no" + Ext.name()).str());
MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
Result.push_back(llvm::join(MArch, "+"));
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index 7d9c1f0bd3d40..a8f7f81726080 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -792,10 +792,9 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D,
const auto ItSimd =
llvm::find_if(llvm::reverse(Features),
[](const StringRef F) { return F.contains("neon"); });
- const bool FPUSupportsNeon = (llvm::ARM::FPUNames[FPUKind].NeonSupport ==
- llvm::ARM::NeonSupportLevel::Neon) ||
- (llvm::ARM::FPUNames[FPUKind].NeonSupport ==
- llvm::ARM::NeonSupportLevel::Crypto);
+ auto NeonSupport = llvm::ARM::getFPUNeonSupportLevel(FPUKind);
+ bool FPUSupportsNeon = NeonSupport == llvm::ARM::NeonSupportLevel::Neon ||
+ NeonSupport == llvm::ARM::NeonSupportLevel::Crypto;
if (ItSimd != Features.rend())
HasSimd = ItSimd->starts_with("+");
if (!HasSimd && FPUSupportsNeon)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index dfd13fbe8a4eb..ac90b8335c3ea 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -927,7 +927,8 @@ void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
for (auto Feature : unifyTargetFeatures(Features)) {
CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature");
- CmdArgs.push_back(Feature.data());
+ // Feature strings may not be null-terminated.
+ CmdArgs.push_back(Args.MakeArgString(Feature));
}
}
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.h b/llvm/include/llvm/TargetParser/ARMTargetParser.h
index 919598c894cd5..50bf76f14ac0e 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParser.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParser.h
@@ -23,6 +23,7 @@
namespace llvm {
+template <typename, unsigned> class EnumStrings;
class Triple;
namespace ARM {
@@ -78,30 +79,6 @@ enum ArchExtKind : uint64_t {
AEK_XSCALE = 1ULL << 63,
};
-// List of Arch Extension names.
-struct ExtName {
- StringRef Name;
- uint64_t ID;
- StringRef Feature;
- StringRef NegFeature;
-};
-
-constexpr ExtName ARCHExtNames[] = {
-#define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
- {NAME, ID, FEATURE, NEGFEATURE},
-#include "ARMTargetParser.def"
-};
-
-// List of HWDiv names (use getHWDivSynonym) and which architectural
-// features they correspond to (use getHWDivFeatures).
-constexpr struct {
- StringRef Name;
- uint64_t ID;
-} HWDivNames[] = {
-#define ARM_HW_DIV_NAME(NAME, ID) {NAME, ID},
-#include "ARMTargetParser.def"
-};
-
// Arch names.
enum class ArchKind {
#define ARM_ARCH(NAME, ID, CPU_ATTR, ARCH_FEATURE, ARCH_ATTR, ARCH_FPU, \
@@ -110,23 +87,6 @@ enum class ArchKind {
#include "ARMTargetParser.def"
};
-// List of CPU names and their arches.
-// The same CPU can have multiple arches and can be default on multiple arches.
-// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
-// When this becomes table-generated, we'd probably need two tables.
-struct CpuNames {
- StringRef Name;
- ArchKind ArchID;
- bool Default; // is $Name the default CPU for $ArchID ?
- uint64_t DefaultExtensions;
-};
-
-constexpr CpuNames CPUNames[] = {
-#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
- {NAME, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT},
-#include "ARMTargetParser.def"
-};
-
// FPU names.
enum FPUKind {
#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND,
@@ -170,52 +130,6 @@ enum class NeonSupportLevel {
// v6/v7/v8 Profile
enum class ProfileKind { INVALID = 0, A, R, M };
-// List of canonical FPU names (use getFPUSynonym) and which architectural
-// features they correspond to (use getFPUFeatures).
-// The entries must appear in the order listed in ARM::FPUKind for correct
-// indexing
-struct FPUName {
- StringRef Name;
- FPUKind ID;
- FPUVersion FPUVer;
- NeonSupportLevel NeonSupport;
- FPURestriction Restriction;
-};
-
-static constexpr FPUName FPUNames[] = {
-#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
- {NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION},
-#include "llvm/TargetParser/ARMTargetParser.def"
-};
-
-// List of canonical arch names (use getArchSynonym).
-// This table also provides the build attribute fields for CPU arch
-// and Arch ID, according to the Addenda to the ARM ABI, chapters
-// 2.4 and 2.3.5.2 respectively.
-// FIXME: SubArch values were simplified to fit into the expectations
-// of the triples and are not conforming with their official names.
-// Check to see if the expectation should be changed.
-struct ArchNames {
- StringRef Name;
- StringRef CPUAttr; // CPU class in build attributes.
- StringRef ArchFeature;
- FPUKind DefaultFPU;
- uint64_t ArchBaseExtensions;
- ArchKind ID;
- ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
-
- // Return ArchFeature without the leading "+".
- StringRef getSubArch() const { return ArchFeature.substr(1); }
-};
-
-static constexpr ArchNames ARMArchNames[] = {
-#define ARM_ARCH(NAME, ID, CPU_ATTR, ARCH_FEATURE, ARCH_ATTR, ARCH_FPU, \
- ARCH_BASE_EXT) \
- {NAME, CPU_ATTR, ARCH_FEATURE, ARCH_FPU, \
- ARCH_BASE_EXT, ArchKind::ID, ARCH_ATTR},
-#include "llvm/TargetParser/ARMTargetParser.def"
-};
-
inline ArchKind &operator--(ArchKind &Kind) {
assert((Kind >= ArchKind::ARMV8A && Kind <= ArchKind::ARMV9_3A) &&
"We only expect operator-- to be called with ARMV8/V9");
@@ -246,6 +160,9 @@ LLVM_ABI StringRef getArchName(ArchKind AK);
LLVM_ABI unsigned getArchAttr(ArchKind AK);
LLVM_ABI StringRef getCPUAttr(ArchKind AK);
LLVM_ABI StringRef getSubArch(ArchKind AK);
+/// Get list of architecture extensions. The name strings are: 0=Name,
+/// 1=PosFeature (incl. "+"), 2=NegFeature (incl. "-").
+LLVM_ABI EnumStrings<uint64_t, 3> getArchExts();
LLVM_ABI StringRef getArchExtName(uint64_t ArchExtKind);
LLVM_ABI StringRef getArchExtFeature(StringRef ArchExt);
LLVM_ABI bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp
index 709e5f05e3bb9..391aa31a6cb25 100644
--- a/llvm/lib/TargetParser/ARMTargetParser.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParser.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/TargetParser/ARMTargetParser.h"
+#include "llvm/ADT/Enum.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -21,6 +22,79 @@
using namespace llvm;
+namespace {
+using namespace llvm::ARM;
+
+// List of Arch Extension names.
+constexpr EnumStringDef<uint64_t, 3> ExtNameDefs[] = {
+#define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
+ {{NAME, FEATURE, NEGFEATURE}, ID},
+#include "llvm/TargetParser/ARMTargetParser.def"
+};
+static constexpr auto ExtNames = BUILD_ENUM_STRINGS(ExtNameDefs);
+
+// List of CPU names and their arches.
+// The same CPU can have multiple arches and can be default on multiple arches.
+// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
+// When this becomes table-generated, we'd probably need two tables.
+struct CpuName {
+ ArchKind ArchID;
+ FPUKind DefaultFPU;
+ bool Default; // is $Name the default CPU for $ArchID ?
+ uint64_t DefaultExtensions;
+};
+
+constexpr EnumStringDef<CpuName> CPUNameDefs[] = {
+#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
+ {{NAME}, {ARM::ArchKind::ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT}},
+#include "llvm/TargetParser/ARMTargetParser.def"
+};
+static constexpr auto CPUNames = BUILD_ENUM_STRINGS(CPUNameDefs);
+
+// List of canonical FPU names (use getFPUSynonym) and which architectural
+// features they correspond to (use getFPUFeatures).
+// The entries must appear in the order listed in ARM::FPUKind for correct
+// indexing.
+struct FPUName {
+ FPUKind ID;
+ FPUVersion FPUVer;
+ NeonSupportLevel NeonSupport;
+ FPURestriction Restriction;
+};
+
+constexpr EnumStringDef<FPUName> FPUNameDefs[] = {
+#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
+ {{NAME}, {KIND, VERSION, NEON_SUPPORT, RESTRICTION}},
+#include "llvm/TargetParser/ARMTargetParser.def"
+};
+static constexpr auto FPUNames = BUILD_ENUM_STRINGS(FPUNameDefs);
+
+// List of canonical arch names (use getArchSynonym).
+// This table also provides the build attribute fields for CPU arch
+// and Arch ID, according to the Addenda to the ARM ABI, chapters
+// 2.4 and 2.3.5.2 respectively.
+// FIXME: SubArch values were simplified to fit into the expectations
+// of the triples and are not conforming with their official names.
+// Check to see if the expectation should be changed.
+struct ArchName {
+ FPUKind DefaultFPU;
+ uint64_t ArchBaseExtensions;
+ ArchKind ID;
+ ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
+};
+
+// Enum string indices: 0 = Name, 1 = CPUAttr, 2 = ArchFeature (incl. "+").
+constexpr EnumStringDef<ArchName, 3> ArchNameDefs[] = {
+#define ARM_ARCH(NAME, ID, CPU_ATTR, ARCH_FEATURE, ARCH_ATTR, ARCH_FPU, \
+ ARCH_BASE_EXT) \
+ {{NAME, CPU_ATTR, ARCH_FEATURE}, \
+ {ARCH_FPU, ARCH_BASE_EXT, ArchKind::ID, ARCH_ATTR}},
+#include "llvm/TargetParser/ARMTargetParser.def"
+};
+static constexpr auto ArchNames = BUILD_ENUM_STRINGS(ArchNameDefs);
+
+} // end anonymous namespace
+
static StringRef getHWDivSynonym(StringRef HWDiv) {
return StringSwitch<StringRef>(HWDiv)
.Case("thumb,arm", "arm,thumb")
@@ -31,9 +105,9 @@ static StringRef getHWDivSynonym(StringRef HWDiv) {
ARM::ArchKind ARM::parseArch(StringRef Arch) {
Arch = getCanonicalArchName(Arch);
StringRef Syn = getArchSynonym(Arch);
- for (const auto &A : ARMArchNames) {
- if (A.Name.ends_with(Syn))
- return A.ID;
+ for (const auto &A : ArchNames) {
+ if (A.name(0).ends_with(Syn))
+ return A.value().ID;
}
return ArchKind::INVALID;
}
@@ -194,8 +268,8 @@ bool ARM::getFPUFeatures(ARM::FPUKind FPUKind,
};
for (const auto &Info: FPUFeatureInfoList) {
- if (FPUNames[FPUKind].FPUVer >= Info.MinVersion &&
- FPUNames[FPUKind].Restriction <= Info.MaxRestriction)
+ if (FPUNames[FPUKind].value().FPUVer >= Info.MinVersion &&
+ FPUNames[FPUKind].value().Restriction <= Info.MaxRestriction)
Features.push_back(Info.PlusName);
else
Features.push_back(Info.MinusName);
@@ -211,7 +285,7 @@ bool ARM::getFPUFeatures(ARM::FPUKind FPUKind,
};
for (const auto &Info: NeonFeatureInfoList) {
- if (FPUNames[FPUKind].NeonSupport >= Info.MinSupportLevel)
+ if (FPUNames[FPUKind].value().NeonSupport >= Info.MinSupportLevel)
Features.push_back(Info.PlusName);
else
Features.push_back(Info.MinusName);
@@ -223,8 +297,8 @@ bool ARM::getFPUFeatures(ARM::FPUKind FPUKind,
ARM::FPUKind ARM::parseFPU(StringRef FPU) {
StringRef Syn = getFPUSynonym(FPU);
for (const auto &F : FPUNames) {
- if (Syn == F.Name)
- return F.ID;
+ if (Syn == F.name())
+ return F.value().ID;
}
return FK_INVALID;
}
@@ -232,7 +306,7 @@ ARM::FPUKind ARM::parseFPU(StringRef FPU) {
ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(ARM::FPUKind FPUKind) {
if (FPUKind >= FK_LAST)
return NeonSupportLevel::None;
- return FPUNames[FPUKind].NeonSupport;
+ return FPUNames[FPUKind].value().NeonSupport;
}
StringRef ARM::getFPUSynonym(StringRef FPU) {
@@ -255,43 +329,42 @@ StringRef ARM::getFPUSynonym(StringRef FPU) {
StringRef ARM::getFPUName(ARM::FPUKind FPUKind) {
if (FPUKind >= FK_LAST)
return StringRef();
- return FPUNames[FPUKind].Name;
+ return FPUNames[FPUKind].name();
}
ARM::FPUVersion ARM::getFPUVersion(ARM::FPUKind FPUKind) {
if (FPUKind >= FK_LAST)
return FPUVersion::NONE;
- return FPUNames[FPUKind].FPUVer;
+ return FPUNames[FPUKind].value().FPUVer;
}
ARM::FPURestriction ARM::getFPURestriction(ARM::FPUKind FPUKind) {
if (FPUKind >= FK_LAST)
return FPURestriction::None;
- return FPUNames[FPUKind].Restriction;
+ return FPUNames[FPUKind].value().Restriction;
}
ARM::FPUKind ARM::getDefaultFPU(StringRef CPU, ARM::ArchKind AK) {
if (CPU == "generic")
- return ARM::ARMArchNames[static_cast<unsigned>(AK)].DefaultFPU;
-
- return StringSwitch<ARM::FPUKind>(CPU)
-#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
- .Case(NAME, DEFAULT_FPU)
-#include "llvm/TargetParser/ARMTargetParser.def"
- .Default(ARM::FK_INVALID);
+ return ArchNames[static_cast<unsigned>(AK)].value().DefaultFPU;
+ for (const auto &C : CPUNames) {
+ if (C.name() == CPU)
+ return C.value().DefaultFPU;
+ }
+ return ARM::FK_INVALID;
}
uint64_t ARM::getDefaultExtensions(StringRef CPU, ARM::ArchKind AK) {
if (CPU == "generic")
- return ARM::ARMArchNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
-
- return StringSwitch<uint64_t>(CPU)
-#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
- .Case(NAME, \
- ARMArchNames[static_cast<unsigned>(ArchKind::ID)].ArchBaseExtensions | \
- DEFAULT_EXT)
-#include "llvm/TargetParser/ARMTargetParser.def"
- .Default(ARM::AEK_INVALID);
+ return ArchNames[static_cast<unsigned>(AK)].value().ArchBaseExtensions;
+ for (const auto &C : CPUNames) {
+ if (C.name() == CPU)
+ return ArchNames[static_cast<unsigned>(C.value().ArchID)]
+ .value()
+ .ArchBaseExtensions |
+ C.value().DefaultExtensions;
+ }
+ return ARM::AEK_INVALID;
}
bool ARM::getHWDivFeatures(uint64_t HWDivKind,
@@ -319,38 +392,37 @@ bool ARM::getExtensionFeatures(uint64_t Extensions,
if (Extensions == AEK_INVALID)
return false;
- for (const auto &AE : ARCHExtNames) {
- if ((Extensions & AE.ID) == AE.ID && !AE.Feature.empty())
- Features.push_back(AE.Feature);
- else if (!AE.NegFeature.empty())
- Features.push_back(AE.NegFeature);
+ for (const auto &AE : ExtNames) {
+ if ((Extensions & AE.value()) == AE.value() && !AE.name(1).empty())
+ Features.push_back(AE.name(1));
+ else if (!AE.name(2).empty())
+ Features.push_back(AE.name(2));
}
return getHWDivFeatures(Extensions, Features);
}
StringRef ARM::getArchName(ARM::ArchKind AK) {
- return ARMArchNames[static_cast<unsigned>(AK)].Name;
+ return ArchNames[static_cast<unsigned>(AK)].name(0);
}
StringRef ARM::getCPUAttr(ARM::ArchKind AK) {
- return ARMArchNames[static_cast<unsigned>(AK)].CPUAttr;
+ return ArchNames[static_cast<unsigned>(AK)].name(1);
}
StringRef ARM::getSubArch(ARM::ArchKind AK) {
- return ARMArchNames[static_cast<unsigned>(AK)].getSubArch();
+ // Return ArchFeature without the leading "+".
+ return ArchNames[static_cast<unsigned>(AK)].name(2).substr(1);
}
unsigned ARM::getArchAttr(ARM::ArchKind AK) {
- return ARMArchNames[static_cast<unsigned>(AK)].ArchAttr;
+ return ArchNames[static_cast<unsigned>(AK)].value().ArchAttr;
}
+EnumStrings<uint64_t, 3> ARM::getArchExts() { return EnumStrings(ExtNames); }
+
StringRef ARM::getArchExtName(uint64_t ArchExtKind) {
- for (const auto &AE : ARCHExtNames) {
- if (ArchExtKind == AE.ID)
- return AE.Name;
- }
- return StringRef();
+ return EnumStrings(ExtNames).toString(ArchExtKind);
}
static bool stripNegationPrefix(StringRef &Name) {
@@ -359,9 +431,9 @@ static bool stripNegationPrefix(StringRef &Name) {
StringRef ARM::getArchExtFeature(StringRef ArchExt) {
bool Negated = stripNegationPrefix(ArchExt);
- for (const auto &AE : ARCHExtNames) {
- if (!AE.Feature.empty() && ArchExt == AE.Name)
- return StringRef(Negated ? AE.NegFeature : AE.Feature);
+ for (const auto &AE : ExtNames) {
+ if (!AE.name(1).empty() && ArchExt == AE.name())
+ return AE.name(Negated ? 2 : 1);
}
return StringRef();
@@ -371,7 +443,7 @@ static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind) {
if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
return ARM::FK_INVALID;
- const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
+ const FPUName &InputFPU = FPUNames[InputFPUKind].value();
// If the input FPU already supports double-precision, then there
// isn't any different FPU we can return here.
@@ -380,7 +452,8 @@ static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind) {
// Otherwise, look for an FPU entry with all the same fields, except
// that it supports double precision.
- for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
+ for (const auto &CandidateFPUEntry : FPUNames) {
+ const FPUName &CandidateFPU = CandidateFPUEntry.value();
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
ARM::has32Regs(CandidateFPU.Restriction) ==
@@ -398,7 +471,7 @@ static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) {
if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
return ARM::FK_INVALID;
- const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
+ const FPUName &InputFPU = FPUNames[InputFPUKind].value();
// If the input FPU already is single-precision only, then there
// isn't any different FPU we can return here.
@@ -409,10 +482,10 @@ static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) {
// and is not Double Precision. We want to allow for changing of
// NEON Support and Restrictions so CPU's such as Cortex-R52 can
// select between SP Only and Full DP modes.
- for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
- if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
- !ARM::isDoublePrecision(CandidateFPU.Restriction)) {
- return CandidateFPU.ID;
+ for (const auto &CandidateFPU : FPUNames) {
+ if (CandidateFPU.value().FPUVer == InputFPU.FPUVer &&
+ !ARM::isDoublePrecision(CandidateFPU.value().Restriction)) {
+ return CandidateFPU.value().ID;
}
}
@@ -432,13 +505,13 @@ bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
if (ID == AEK_INVALID)
return false;
- for (const auto &AE : ARCHExtNames) {
+ for (const auto &AE : ExtNames) {
if (Negated) {
- if ((AE.ID & ID) == ID && !AE.NegFeature.empty())
- Features.push_back(AE.NegFeature);
+ if ((AE.value() & ID) == ID && !AE.name(2).empty())
+ Features.push_back(AE.name(2));
} else {
- if ((AE.ID & ID) == AE.ID && !AE.Feature.empty())
- Features.push_back(AE.Feature);
+ if ((AE.value() & ID) == AE.value() && !AE.name(1).empty())
+ Features.push_back(AE.name(1));
}
}
@@ -497,8 +570,8 @@ StringRef ARM::getDefaultCPU(StringRef Arch) {
// Look for multiple AKs to find the default for pair AK+Name.
for (const auto &CPU : CPUNames) {
- if (CPU.ArchID == AK && CPU.Default)
- return CPU.Name;
+ if (CPU.value().ArchID == AK && CPU.value().Default)
+ return CPU.name();
}
// If we can't find a default then target the architecture instead
@@ -506,34 +579,42 @@ StringRef ARM::getDefaultCPU(StringRef Arch) {
}
uint64_t ARM::parseHWDiv(StringRef HWDiv) {
+ // List of HWDiv names (use getHWDivSynonym) and which architectural
+ // features they correspond to (use getHWDivFeatures).
+ constexpr EnumStringDef<uint64_t> HWDivNameDefs[] = {
+#define ARM_HW_DIV_NAME(NAME, ID) {{NAME}, ID},
+#include "llvm/TargetParser/ARMTargetParser.def"
+ };
+ static constexpr auto HWDivNames = BUILD_ENUM_STRINGS(HWDivNameDefs);
+
StringRef Syn = getHWDivSynonym(HWDiv);
for (const auto &D : HWDivNames) {
- if (Syn == D.Name)
- return D.ID;
+ if (Syn == D.name())
+ return D.value();
}
return AEK_INVALID;
}
uint64_t ARM::parseArchExt(StringRef ArchExt) {
- for (const auto &A : ARCHExtNames) {
- if (ArchExt == A.Name)
- return A.ID;
+ for (const auto &A : ExtNames) {
+ if (ArchExt == A.name(0))
+ return A.value();
}
return AEK_INVALID;
}
ARM::ArchKind ARM::parseCPUArch(StringRef CPU) {
for (const auto &C : CPUNames) {
- if (CPU == C.Name)
- return C.ArchID;
+ if (CPU == C.name())
+ return C.value().ArchID;
}
return ArchKind::INVALID;
}
void ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
- for (const auto &Arch : CPUNames) {
- if (Arch.ArchID != ArchKind::INVALID)
- Values.push_back(Arch.Name);
+ for (const auto &CPU : CPUNames) {
+ if (CPU.value().ArchID != ArchKind::INVALID)
+ Values.push_back(CPU.name());
}
}
@@ -671,17 +752,17 @@ void ARM::PrintSupportedExtensions(StringMap<StringRef> DescMap) {
outs() << "All available -march extensions for ARM\n\n"
<< " " << left_justify("Name", 20)
<< (DescMap.empty() ? "\n" : "Description\n");
- for (const auto &Ext : ARCHExtNames) {
+ for (const auto &Ext : ExtNames) {
// Extensions without a feature cannot be used with -march.
- if (!Ext.Feature.empty()) {
- std::string Description = DescMap[Ext.Name].str();
+ if (!Ext.name(1).empty()) {
+ std::string Description = DescMap[Ext.name(0)].str();
// With SIMD, this links to the NEON feature, so the description should be
// taken from here, as SIMD does not exist in TableGen.
- if (Ext.Name == "simd")
+ if (Ext.name(0) == "simd")
Description = DescMap["neon"].str();
outs() << " "
<< format(Description.empty() ? "%s\n" : "%-20s%s\n",
- Ext.Name.str().c_str(), Description.c_str());
+ Ext.name().str().c_str(), Description.c_str());
}
}
}
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index c91b6b3ac08d8..e019c6eb85c44 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/TargetParser/TargetParser.h"
+#include "llvm/ADT/Enum.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
@@ -787,31 +788,31 @@ TEST(TargetParserTest, ARMFPURestriction) {
}
TEST(TargetParserTest, ARMExtensionFeatures) {
- std::map<uint64_t, std::vector<StringRef>> Extensions;
+ std::vector<std::tuple<ARM::ArchExtKind, StringRef, StringRef>> Extensions;
- for (auto &Ext : ARM::ARCHExtNames) {
- if (!Ext.Feature.empty() && !Ext.NegFeature.empty())
- Extensions[Ext.ID] = {Ext.Feature, Ext.NegFeature};
+ for (auto &Ext : ARM::getArchExts()) {
+ if (!Ext.name(1).empty() && !Ext.name(2).empty())
+ Extensions.emplace_back(Ext.value(), Ext.name(1), Ext.name(2));
}
- Extensions[ARM::AEK_HWDIVARM] = {"+hwdiv-arm", "-hwdiv-arm"};
- Extensions[ARM::AEK_HWDIVTHUMB] = {"+hwdiv", "-hwdiv"};
+ Extensions.emplace_back(ARM::AEK_HWDIVARM, "+hwdiv-arm", "-hwdiv-arm");
+ Extensions.emplace_back(ARM::AEK_HWDIVTHUMB, "+hwdiv", "-hwdiv");
std::vector<StringRef> Features;
EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features));
- for (auto &E : Extensions) {
+ for (auto &[ExtID, PosFeature, NegFeature] : Extensions) {
// test +extension
Features.clear();
- ARM::getExtensionFeatures(E.first, Features);
- EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0)));
+ ARM::getExtensionFeatures(ExtID, Features);
+ EXPECT_TRUE(llvm::is_contained(Features, PosFeature));
EXPECT_EQ(Extensions.size(), Features.size());
// test -extension
Features.clear();
- ARM::getExtensionFeatures(~E.first, Features);
- EXPECT_TRUE(llvm::is_contained(Features, E.second.at(1)));
+ ARM::getExtensionFeatures(~ExtID, Features);
+ EXPECT_TRUE(llvm::is_contained(Features, NegFeature));
EXPECT_EQ(Extensions.size(), Features.size());
}
}
>From b74bbcf91a7bf35f9e1b3bb4abe9cc1df798124f Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 1 Jul 2026 11:11:31 +0000
Subject: [PATCH 2/2] use enum type for enum
Created using spr 1.3.8-wip
---
llvm/include/llvm/TargetParser/ARMTargetParser.h | 2 +-
llvm/lib/TargetParser/ARMTargetParser.cpp | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.h b/llvm/include/llvm/TargetParser/ARMTargetParser.h
index 50bf76f14ac0e..2a42bf6a5ca6f 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParser.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParser.h
@@ -162,7 +162,7 @@ LLVM_ABI StringRef getCPUAttr(ArchKind AK);
LLVM_ABI StringRef getSubArch(ArchKind AK);
/// Get list of architecture extensions. The name strings are: 0=Name,
/// 1=PosFeature (incl. "+"), 2=NegFeature (incl. "-").
-LLVM_ABI EnumStrings<uint64_t, 3> getArchExts();
+LLVM_ABI EnumStrings<ArchExtKind, 3> getArchExts();
LLVM_ABI StringRef getArchExtName(uint64_t ArchExtKind);
LLVM_ABI StringRef getArchExtFeature(StringRef ArchExt);
LLVM_ABI bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp
index 391aa31a6cb25..ffd1410dc66d9 100644
--- a/llvm/lib/TargetParser/ARMTargetParser.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParser.cpp
@@ -26,9 +26,9 @@ namespace {
using namespace llvm::ARM;
// List of Arch Extension names.
-constexpr EnumStringDef<uint64_t, 3> ExtNameDefs[] = {
+constexpr EnumStringDef<ArchExtKind, 3> ExtNameDefs[] = {
#define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
- {{NAME, FEATURE, NEGFEATURE}, ID},
+ {{NAME, FEATURE, NEGFEATURE}, ArchExtKind(ID)},
#include "llvm/TargetParser/ARMTargetParser.def"
};
static constexpr auto ExtNames = BUILD_ENUM_STRINGS(ExtNameDefs);
@@ -419,7 +419,7 @@ unsigned ARM::getArchAttr(ARM::ArchKind AK) {
return ArchNames[static_cast<unsigned>(AK)].value().ArchAttr;
}
-EnumStrings<uint64_t, 3> ARM::getArchExts() { return EnumStrings(ExtNames); }
+EnumStrings<ArchExtKind, 3> ARM::getArchExts() { return EnumStrings(ExtNames); }
StringRef ARM::getArchExtName(uint64_t ArchExtKind) {
return EnumStrings(ExtNames).toString(ArchExtKind);
More information about the cfe-commits
mailing list