https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/206937
Make the tables that contain strings relocation-free and move them to the .cpp file. This reduces the size of .data.rel.ro of libLLVM.so by ~9kiB. >From a99b803017af3bca32f1dc6ed1f42dccaa0f7f26 Mon Sep 17 00:00:00 2001 From: Alexis Engelke <[email protected]> Date: Wed, 1 Jul 2026 10:12:48 +0000 Subject: [PATCH] [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()); } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
