[clang] [llvm] [TargetParser][AArch64][NFC] Use StringTable (PR #206698)
Alexis Engelke via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 30 03:15:02 PDT 2026
https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/206698
Store strings in a StringTable instead of referencing them via pointers.
This permits some data structures to be stored in .rodata instead of
.data.rel.ro, as they no longer require relocations. In particular this
affects the 16 kiB AArch64::Extensions.
>From a100e293fa7335fee9d0fe829302b2385244666d Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Tue, 30 Jun 2026 10:14:22 +0000
Subject: [PATCH] [spr] initial version
Created using spr 1.3.8-wip
---
clang/lib/Driver/ToolChain.cpp | 16 ++---
clang/lib/Driver/ToolChains/Clang.cpp | 3 +-
.../llvm/TargetParser/AArch64TargetParser.h | 47 +++++++------
.../AArch64/AsmParser/AArch64AsmParser.cpp | 2 +-
llvm/lib/TargetParser/AArch64TargetParser.cpp | 67 ++++++++++---------
.../TargetParser/TargetParserTest.cpp | 40 +++++------
.../TableGen/Basic/ARMTargetDefEmitter.cpp | 58 +++++++++++-----
7 files changed, 133 insertions(+), 100 deletions(-)
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 726c8a6ad229a..54cd534f8c5fc 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -289,17 +289,17 @@ static void getAArch64MultilibFlags(const Driver &D,
UnifiedFeatures.end());
std::vector<std::string> MArch;
for (const auto &Ext : AArch64::Extensions)
- if (!Ext.UserVisibleName.empty())
- if (FeatureSet.contains(Ext.PosTargetFeature))
- MArch.push_back(Ext.UserVisibleName.str());
+ if (Ext.UserVisibleName.value())
+ if (FeatureSet.contains(AArch64::StrTab[Ext.PosTargetFeature]))
+ MArch.push_back(AArch64::StrTab[Ext.UserVisibleName].str());
for (const auto &Ext : AArch64::Extensions)
- if (!Ext.UserVisibleName.empty())
- if (FeatureSet.contains(Ext.NegTargetFeature))
- MArch.push_back(("no" + Ext.UserVisibleName).str());
+ if (Ext.UserVisibleName.value())
+ if (FeatureSet.contains(AArch64::StrTab[Ext.NegTargetFeature]))
+ MArch.push_back(("no" + AArch64::StrTab[Ext.UserVisibleName]).str());
StringRef ArchName;
for (const auto &ArchInfo : AArch64::ArchInfos)
- if (FeatureSet.contains(ArchInfo->ArchFeature))
- ArchName = ArchInfo->Name;
+ if (FeatureSet.contains(AArch64::StrTab[ArchInfo->ArchFeature]))
+ ArchName = AArch64::StrTab[ArchInfo->Name];
if (!ArchName.empty()) {
MArch.insert(MArch.begin(), ("-march=" + ArchName).str());
Result.push_back(llvm::join(MArch, "+"));
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a3a3954bc464e..158d9aeaeb785 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1438,7 +1438,8 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
auto isPAuthLR = [](const char *member) {
llvm::AArch64::ExtensionInfo pauthlr_extension =
llvm::AArch64::getExtensionByID(llvm::AArch64::AEK_PAUTHLR);
- return pauthlr_extension.PosTargetFeature == member;
+ return llvm::AArch64::StrTab[pauthlr_extension.PosTargetFeature] ==
+ member;
};
if (llvm::any_of(CmdArgs, isPAuthLR))
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 224bcaf79412d..ec217ca33726f 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringTable.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
@@ -43,6 +44,10 @@ static_assert(FEAT_MAX < 62,
static_assert(PRIOR_MAX < 120, "FeatPriorities is limited to 120 entries");
+// Emit the StringTable StrTab to which all offsets refer.
+#define EMIT_STRTAB
+#include "llvm/TargetParser/AArch64TargetParserDef.inc"
+
// Each ArchExtKind correponds directly to a possible -target-feature.
#define EMIT_ARCHEXTKIND_ENUM
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
@@ -54,18 +59,19 @@ using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
// SubtargetFeature which may represent either an actual extension or some
// internal LLVM property.
struct ExtensionInfo {
- StringRef UserVisibleName; // Human readable name used in -march, -cpu
+ StringTable::Offset
+ UserVisibleName; // Human readable name used in -march, -cpu
// and target func attribute, e.g. "profile".
- std::optional<StringRef> Alias; // An alias for this extension, if one exists.
+ StringTable::Offset Alias; // An alias for this extension, if one exists.
ArchExtKind ID; // Corresponding to the ArchExtKind, this
// extensions representation in the bitfield.
- StringRef ArchFeatureName; // The feature name defined by the
- // Architecture, e.g. FEAT_AdvSIMD.
- StringRef Description; // The textual description of the extension.
- StringRef PosTargetFeature; // -target-feature/-mattr enable string,
- // e.g. "+spe".
- StringRef NegTargetFeature; // -target-feature/-mattr disable string,
- // e.g. "-spe".
+ StringTable::Offset ArchFeatureName; // The feature name defined by the
+ // Architecture, e.g. FEAT_AdvSIMD.
+ StringTable::Offset Description; // The textual description of the extension.
+ StringTable::Offset PosTargetFeature; // -target-feature/-mattr enable string,
+ // e.g. "+spe".
+ StringTable::Offset NegTargetFeature; // -target-feature/-mattr disable
+ // string, e.g. "-spe".
};
#define EMIT_EXTENSIONS
@@ -102,8 +108,9 @@ enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
struct ArchInfo {
VersionTuple Version; // Architecture version, major + minor.
ArchProfile Profile; // Architecuture profile
- StringRef Name; // Name as supplied to -march e.g. "armv8.1-a"
- StringRef ArchFeature; // Name as supplied to -target-feature, e.g. "+v8a"
+ StringTable::Offset Name; // Name as supplied to -march e.g. "armv8.1-a"
+ StringTable::Offset
+ ArchFeature; // Name as supplied to -target-feature, e.g. "+v8a"
AArch64::ExtensionBitset
DefaultExts; // bitfield of default extensions ArchExtKind
@@ -146,7 +153,7 @@ struct ArchInfo {
}
// Return ArchFeature without the leading "+".
- StringRef getSubArch() const { return ArchFeature.substr(1); }
+ StringRef getSubArch() const { return StrTab[ArchFeature].substr(1); }
// Search for ArchInfo by SubArch name
LLVM_ABI static std::optional<ArchInfo> findBySubArch(StringRef SubArch);
@@ -157,7 +164,7 @@ struct ArchInfo {
// Details of a specific CPU.
struct CpuInfo {
- StringRef Name; // Name, as written for -mcpu.
+ StringTable::Offset Name; // Name, as written for -mcpu.
const ArchInfo &Arch;
AArch64::ExtensionBitset
DefaultExtensions; // Default extensions for this CPU.
@@ -219,16 +226,16 @@ struct ExtensionSet {
// Convert the set of enabled extension to an LLVM feature list, appending
// them to Features.
template <typename T> void toLLVMFeatureList(std::vector<T> &Features) const {
- if (BaseArch && !BaseArch->ArchFeature.empty())
- Features.emplace_back(T(BaseArch->ArchFeature));
+ if (BaseArch && !StrTab[BaseArch->ArchFeature].empty())
+ Features.emplace_back(T(StrTab[BaseArch->ArchFeature]));
for (const auto &E : Extensions) {
- if (E.PosTargetFeature.empty() || !Touched.test(E.ID))
+ if (!Touched.test(E.ID))
continue;
if (Enabled.test(E.ID))
- Features.emplace_back(T(E.PosTargetFeature));
+ Features.emplace_back(T(StrTab[E.PosTargetFeature]));
else
- Features.emplace_back(T(E.NegTargetFeature));
+ Features.emplace_back(T(StrTab[E.NegTargetFeature]));
}
}
@@ -237,8 +244,8 @@ struct ExtensionSet {
// Name alias.
struct Alias {
- StringRef AltName;
- StringRef Name;
+ StringTable::Offset AltName;
+ StringTable::Offset Name;
};
#define EMIT_CPU_ALIAS
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index b3fda2fe849fa..61ab1ba2bd47e 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -7457,7 +7457,7 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
// Get the architecture and extension features.
std::vector<StringRef> AArch64Features;
- AArch64Features.push_back(ArchInfo->ArchFeature);
+ AArch64Features.push_back(AArch64::StrTab[ArchInfo->ArchFeature]);
AArch64::getExtensionFeatures(ArchInfo->DefaultExts, AArch64Features);
MCSubtargetInfo &STI = copySTI();
diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp
index 2c0211b3a2919..679d59383f536 100644
--- a/llvm/lib/TargetParser/AArch64TargetParser.cpp
+++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp
@@ -108,16 +108,16 @@ bool AArch64::getExtensionFeatures(
std::vector<StringRef> &Features) {
for (const auto &E : Extensions)
/* INVALID and NONE have no feature name. */
- if (InputExts.test(E.ID) && !E.PosTargetFeature.empty())
- Features.push_back(E.PosTargetFeature);
+ if (InputExts.test(E.ID))
+ Features.push_back(StrTab[E.PosTargetFeature]);
return true;
}
StringRef AArch64::resolveCPUAlias(StringRef Name) {
for (const auto &A : CpuAliases)
- if (A.AltName == Name)
- return A.Name;
+ if (StrTab[A.AltName] == Name)
+ return StrTab[A.Name];
return Name;
}
@@ -125,22 +125,19 @@ StringRef AArch64::getArchExtFeature(StringRef ArchExt) {
bool IsNegated = ArchExt.starts_with("no");
StringRef ArchExtBase = IsNegated ? ArchExt.drop_front(2) : ArchExt;
- if (auto AE = parseArchExtension(ArchExtBase)) {
- assert(!(AE.has_value() && AE->NegTargetFeature.empty()));
- return IsNegated ? AE->NegTargetFeature : AE->PosTargetFeature;
- }
-
+ if (auto AE = parseArchExtension(ArchExtBase))
+ return StrTab[IsNegated ? AE->NegTargetFeature : AE->PosTargetFeature];
return StringRef();
}
void AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
for (const auto &C : CpuInfos)
- Values.push_back(C.Name);
+ Values.push_back(StrTab[C.Name]);
for (const auto &Alias : CpuAliases)
// The apple-latest alias is backend only, do not expose it to clang's -mcpu.
- if (Alias.AltName != "apple-latest")
- Values.push_back(Alias.AltName);
+ if (StrTab[Alias.AltName] != "apple-latest")
+ Values.push_back(StrTab[Alias.AltName]);
llvm::sort(Values);
}
@@ -158,7 +155,7 @@ const AArch64::ArchInfo *AArch64::parseArch(StringRef Arch) {
StringRef Syn = llvm::ARM::getArchSynonym(Arch);
for (const auto *A : ArchInfos) {
- if (A->Name.ends_with(Syn))
+ if (StrTab[A->Name].ends_with(Syn))
return A;
}
return {};
@@ -169,7 +166,7 @@ AArch64::parseArchExtension(StringRef ArchExt) {
if (ArchExt.empty())
return {};
for (const auto &A : Extensions) {
- if (ArchExt == A.UserVisibleName || ArchExt == A.Alias)
+ if (ArchExt == StrTab[A.UserVisibleName] || ArchExt == StrTab[A.Alias])
return A;
}
return {};
@@ -190,8 +187,8 @@ std::optional<AArch64::FMVInfo> AArch64::parseFMVExtension(StringRef FMVExt) {
std::optional<AArch64::ExtensionInfo>
AArch64::targetFeatureToExtension(StringRef TargetFeature) {
for (const auto &E : Extensions)
- if (TargetFeature == E.PosTargetFeature ||
- TargetFeature == E.NegTargetFeature)
+ if (TargetFeature == StrTab[E.PosTargetFeature] ||
+ TargetFeature == StrTab[E.NegTargetFeature])
return E;
return {};
}
@@ -202,7 +199,7 @@ std::optional<AArch64::CpuInfo> AArch64::parseCpu(StringRef Name) {
// Then find the CPU name.
for (const auto &C : CpuInfos)
- if (Name == C.Name)
+ if (Name == StrTab[C.Name])
return C;
return {};
@@ -215,12 +212,15 @@ void AArch64::PrintSupportedExtensions() {
<< "Description\n";
for (const auto &Ext : Extensions) {
// Extensions without a feature cannot be used with -march.
- if (!Ext.UserVisibleName.empty() && !Ext.PosTargetFeature.empty()) {
+ if (Ext.UserVisibleName.value() && Ext.PosTargetFeature.value()) {
+ // NB: StringTable strings are null-terminated, so the StringRef can be
+ // used as C string without further conversion.
outs() << " "
- << format(Ext.Description.empty() ? "%-20s%s\n" : "%-20s%-55s%s\n",
- Ext.UserVisibleName.str().c_str(),
- Ext.ArchFeatureName.str().c_str(),
- Ext.Description.str().c_str());
+ << format(!Ext.Description.value() ? "%-20s%s\n"
+ : "%-20s%-55s%s\n",
+ StrTab[Ext.UserVisibleName].data(),
+ StrTab[Ext.ArchFeatureName].data(),
+ StrTab[Ext.Description].data());
}
}
}
@@ -239,14 +239,15 @@ AArch64::printEnabledExtensions(const std::set<StringRef> &EnabledFeatureNames)
std::sort(EnabledExtensionsInfo.begin(), EnabledExtensionsInfo.end(),
[](const ExtensionInfo &Lhs, const ExtensionInfo &Rhs) {
- return Lhs.ArchFeatureName < Rhs.ArchFeatureName;
+ return StrTab[Lhs.ArchFeatureName] < StrTab[Rhs.ArchFeatureName];
});
for (const auto &Ext : EnabledExtensionsInfo) {
+ // NB: StringTable strings are null-terminated, so the StringRef can be used
+ // as C string without further conversion.
outs() << " "
- << format("%-55s%s\n",
- Ext.ArchFeatureName.str().c_str(),
- Ext.Description.str().c_str());
+ << format("%-55s%s\n", StrTab[Ext.ArchFeatureName].data(),
+ StrTab[Ext.Description].data());
}
}
@@ -262,7 +263,9 @@ void AArch64::ExtensionSet::enable(ArchExtKind E) {
if (Enabled.test(E))
return;
- LLVM_DEBUG(llvm::dbgs() << "Enable " << lookupExtensionByID(E).UserVisibleName << "\n");
+ LLVM_DEBUG(llvm::dbgs() << "Enable "
+ << StrTab[lookupExtensionByID(E).UserVisibleName]
+ << "\n");
Touched.set(E);
Enabled.set(E);
@@ -329,7 +332,9 @@ void AArch64::ExtensionSet::disable(ArchExtKind E) {
if (!Enabled.test(E))
return;
- LLVM_DEBUG(llvm::dbgs() << "Disable " << lookupExtensionByID(E).UserVisibleName << "\n");
+ LLVM_DEBUG(llvm::dbgs() << "Disable "
+ << StrTab[lookupExtensionByID(E).UserVisibleName]
+ << "\n");
Touched.set(E);
Enabled.reset(E);
@@ -341,7 +346,7 @@ void AArch64::ExtensionSet::disable(ArchExtKind E) {
}
void AArch64::ExtensionSet::addCPUDefaults(const CpuInfo &CPU) {
- LLVM_DEBUG(llvm::dbgs() << "addCPUDefaults(" << CPU.Name << ")\n");
+ LLVM_DEBUG(llvm::dbgs() << "addCPUDefaults(" << StrTab[CPU.Name] << ")\n");
BaseArch = &CPU.Arch;
AArch64::ExtensionBitset CPUExtensions = CPU.getImpliedExtensions();
@@ -351,7 +356,7 @@ void AArch64::ExtensionSet::addCPUDefaults(const CpuInfo &CPU) {
}
void AArch64::ExtensionSet::addArchDefaults(const ArchInfo &Arch) {
- LLVM_DEBUG(llvm::dbgs() << "addArchDefaults(" << Arch.Name << ")\n");
+ LLVM_DEBUG(llvm::dbgs() << "addArchDefaults(" << StrTab[Arch.Name] << ")\n");
BaseArch = &Arch;
for (const auto &E : Extensions)
@@ -373,8 +378,6 @@ bool AArch64::ExtensionSet::parseModifier(StringRef Modifier,
StringRef ArchExt = Modifier.drop_front(NChars);
if (auto AE = parseArchExtension(ArchExt)) {
- if (AE->PosTargetFeature.empty() || AE->NegTargetFeature.empty())
- return false;
if (IsNegated)
disable(AE->ID);
else
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 61da68940d9a1..45d584ac3d071 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -1078,7 +1078,7 @@ TEST_P(AArch64CPUTestFixture, testAArch64CPU) {
const std::optional<AArch64::CpuInfo> Cpu = AArch64::parseCpu(params.CPUName);
EXPECT_TRUE(Cpu);
- EXPECT_EQ(params.ExpectedArch, Cpu->Arch.Name);
+ EXPECT_EQ(params.ExpectedArch, AArch64::StrTab[Cpu->Arch.Name]);
}
INSTANTIATE_TEST_SUITE_P(
@@ -1594,25 +1594,25 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
}
TEST(TargetParserTest, AArch64ArchFeatures) {
- EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a");
- EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a");
- EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a");
- EXPECT_EQ(AArch64::ARMV8_3A.ArchFeature, "+v8.3a");
- EXPECT_EQ(AArch64::ARMV8_4A.ArchFeature, "+v8.4a");
- EXPECT_EQ(AArch64::ARMV8_5A.ArchFeature, "+v8.5a");
- EXPECT_EQ(AArch64::ARMV8_6A.ArchFeature, "+v8.6a");
- EXPECT_EQ(AArch64::ARMV8_7A.ArchFeature, "+v8.7a");
- EXPECT_EQ(AArch64::ARMV8_8A.ArchFeature, "+v8.8a");
- EXPECT_EQ(AArch64::ARMV8_9A.ArchFeature, "+v8.9a");
- EXPECT_EQ(AArch64::ARMV9A.ArchFeature, "+v9a");
- EXPECT_EQ(AArch64::ARMV9_1A.ArchFeature, "+v9.1a");
- EXPECT_EQ(AArch64::ARMV9_2A.ArchFeature, "+v9.2a");
- EXPECT_EQ(AArch64::ARMV9_3A.ArchFeature, "+v9.3a");
- EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a");
- EXPECT_EQ(AArch64::ARMV9_5A.ArchFeature, "+v9.5a");
- EXPECT_EQ(AArch64::ARMV9_6A.ArchFeature, "+v9.6a");
- EXPECT_EQ(AArch64::ARMV9_7A.ArchFeature, "+v9.7a");
- EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8A.ArchFeature], "+v8a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_1A.ArchFeature], "+v8.1a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_2A.ArchFeature], "+v8.2a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_3A.ArchFeature], "+v8.3a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_4A.ArchFeature], "+v8.4a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_5A.ArchFeature], "+v8.5a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_6A.ArchFeature], "+v8.6a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_7A.ArchFeature], "+v8.7a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_8A.ArchFeature], "+v8.8a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8_9A.ArchFeature], "+v8.9a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9A.ArchFeature], "+v9a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9_1A.ArchFeature], "+v9.1a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9_2A.ArchFeature], "+v9.2a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9_3A.ArchFeature], "+v9.3a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9_4A.ArchFeature], "+v9.4a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9_5A.ArchFeature], "+v9.5a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9_6A.ArchFeature], "+v9.6a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV9_7A.ArchFeature], "+v9.7a");
+ EXPECT_EQ(AArch64::StrTab[AArch64::ARMV8R.ArchFeature], "+v8r");
}
TEST(TargetParserTest, AArch64ArchPartialOrder) {
diff --git a/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp
index a18fed082207f..934ea67c4d982 100644
--- a/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp
@@ -18,6 +18,7 @@
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/StringToOffsetTable.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <set>
#include <string>
@@ -115,6 +116,8 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
if (!RK.getClass("Architecture64"))
return;
+ StringToOffsetTable StrTab;
+
// Emit the ArchExtKind enum
OS << "#ifdef EMIT_ARCHEXTKIND_ENUM\n"
<< "enum ArchExtKind : unsigned {\n";
@@ -133,20 +136,28 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
for (const Record *Rec : SortedExtensions) {
auto AEK = Rec->getValueAsString("ArchExtKindSpelling").upper();
OS << " ";
- OS << "{\"" << Rec->getValueAsString("UserVisibleName") << "\"";
- if (auto Alias = Rec->getValueAsString("UserVisibleAlias"); Alias.empty())
- OS << ", {}";
- else
- OS << ", \"" << Alias << "\"";
+ OS << "{"
+ << StrTab.GetOrAddStringOffset(Rec->getValueAsString("UserVisibleName"));
+ // Empty string implies no alias.
+ OS << ", "
+ << StrTab.GetOrAddStringOffset(
+ Rec->getValueAsString("UserVisibleAlias"));
OS << ", AArch64::" << AEK;
- OS << ", \"" << Rec->getValueAsString("ArchFeatureName") << "\"";
- OS << ", \"" << Rec->getValueAsString("Desc") << "\"";
- OS << ", \"+" << Rec->getValueAsString("Name") << "\""; // posfeature
- OS << ", \"-" << Rec->getValueAsString("Name") << "\""; // negfeature
+ OS << ", "
+ << StrTab.GetOrAddStringOffset(Rec->getValueAsString("ArchFeatureName"));
+ OS << ", " << StrTab.GetOrAddStringOffset(Rec->getValueAsString("Desc"));
+ OS << ", "
+ << StrTab.GetOrAddStringOffset(
+ std::string("+") +
+ Rec->getValueAsString("Name").str()); // posfeature
+ OS << ", "
+ << StrTab.GetOrAddStringOffset(
+ std::string("-") +
+ Rec->getValueAsString("Name").str()); // negfeature
OS << "},\n";
};
- OS << "};\n"
- << "#undef EMIT_EXTENSIONS\n"
+ OS << "};\n";
+ OS << "#undef EMIT_EXTENSIONS\n"
<< "#endif // EMIT_EXTENSIONS\n"
<< "\n";
@@ -231,15 +242,18 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
OS << llvm::format(" %sProfile,\n", ProfileUpper.c_str());
// Name as spelled for -march.
+ std::string ArchStr;
+ llvm::raw_string_ostream AS(ArchStr);
if (Minor == 0)
- OS << llvm::format(" \"armv%d-%s\",\n", Major, ProfileLower.c_str());
+ AS << llvm::format("armv%d-%s", Major, ProfileLower.c_str());
else
- OS << llvm::format(" \"armv%d.%d-%s\",\n", Major, Minor,
- ProfileLower.c_str());
+ AS << llvm::format("armv%d.%d-%s", Major, Minor, ProfileLower.c_str());
+ OS << " " << StrTab.GetOrAddStringOffset(ArchStr) << ",\n";
// SubtargetFeature::Name, used for -target-feature. Here the "+" is added.
- const auto TargetFeatureName = Rec->getValueAsString("Name");
- OS << " \"+" << TargetFeatureName << "\",\n";
+ std::string TargetFeatureName =
+ (Twine("+") + Rec->getValueAsString("Name")).str();
+ OS << " " << StrTab.GetOrAddStringOffset(TargetFeatureName) << ",\n";
// Construct the list of default extensions
OS << " (AArch64::ExtensionBitset({";
@@ -286,7 +300,8 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
PrintFatalError(
Rec, "Alias '" + Name + "' duplicates an existing ProcessorAlias");
- OS << llvm::formatv(R"( { "{0}", "{1}" },)", Name, Alias) << '\n';
+ OS << " {" << StrTab.GetOrAddStringOffset(Name) << ", "
+ << StrTab.GetOrAddStringOffset(Alias) << "},\n";
}
OS << "};\n"
@@ -335,7 +350,7 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
checkFeatureTree(Arch);
OS << " {\n"
- << " \"" << Name << "\",\n"
+ << " " << StrTab.GetOrAddStringOffset(Name) << ",\n"
<< " " << ArchInfo << ",\n"
<< " AArch64::ExtensionBitset({\n";
@@ -357,6 +372,13 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
OS << "#undef EMIT_CPU_INFO\n"
<< "#endif // EMIT_CPU_INFO\n"
<< "\n";
+
+ // Emit string table.
+ OS << "#ifdef EMIT_STRTAB\n";
+ StrTab.EmitStringTableDef(OS, "StrTab");
+ OS << "#undef EMIT_STRTAB\n"
+ << "#endif // EMIT_STRTAB\n"
+ << "\n";
}
static TableGen::Emitter::Opt
More information about the cfe-commits
mailing list