Skip to content

Commit 9ea00fc

Browse files
committed
[NFC][AArch64] Use optional returns in target parser instead of 'invalid' objects
This updates the parsing methods in AArch64's Target Parser to make use of optional returns instead of "invalid" enum values, making the API's behaviour clearer. Reviewed By: lenary, tmatheson Differential Revision: https://reviews.llvm.org/D142539
1 parent 0a51bc7 commit 9ea00fc

File tree

6 files changed

+156
-158
lines changed

6 files changed

+156
-158
lines changed

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/StringSwitch.h"
2020
#include "llvm/Support/AArch64TargetParser.h"
2121
#include "llvm/Support/ARMTargetParserCommon.h"
22+
#include "llvm/TargetParser/AArch64TargetParser.h"
2223
#include <optional>
2324

2425
using namespace clang;
@@ -223,8 +224,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
223224
}
224225

225226
bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
226-
return Name == "generic" ||
227-
llvm::AArch64::parseCpu(Name).Arch != llvm::AArch64::INVALID;
227+
return Name == "generic" || llvm::AArch64::parseCpu(Name);
228228
}
229229

230230
bool AArch64TargetInfo::setCPU(const std::string &Name) {
@@ -681,19 +681,19 @@ void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
681681
Features[Name] = Enabled;
682682
// If the feature is an architecture feature (like v8.2a), add all previous
683683
// architecture versions and any dependant target features.
684-
const llvm::AArch64::ArchInfo &ArchInfo =
684+
const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
685685
llvm::AArch64::ArchInfo::findBySubArch(Name);
686686

687-
if (ArchInfo == llvm::AArch64::INVALID)
687+
if (!ArchInfo)
688688
return; // Not an architecure, nothing more to do.
689689

690690
for (const auto *OtherArch : llvm::AArch64::ArchInfos)
691-
if (ArchInfo.implies(*OtherArch))
691+
if (ArchInfo->implies(*OtherArch))
692692
Features[OtherArch->getSubArch()] = Enabled;
693693

694694
// Set any features implied by the architecture
695695
uint64_t Extensions =
696-
llvm::AArch64::getDefaultExtensions("generic", ArchInfo);
696+
llvm::AArch64::getDefaultExtensions("generic", *ArchInfo);
697697
std::vector<StringRef> CPUFeats;
698698
if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) {
699699
for (auto F : CPUFeats) {
@@ -949,9 +949,9 @@ bool AArch64TargetInfo::initFeatureMap(
949949
const std::vector<std::string> &FeaturesVec) const {
950950
std::vector<std::string> UpdatedFeaturesVec;
951951
// Parse the CPU and add any implied features.
952-
const llvm::AArch64::ArchInfo &Arch = llvm::AArch64::parseCpu(CPU).Arch;
953-
if (Arch != llvm::AArch64::INVALID) {
954-
uint64_t Exts = llvm::AArch64::getDefaultExtensions(CPU, Arch);
952+
std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU);
953+
if (CpuInfo) {
954+
uint64_t Exts = llvm::AArch64::getDefaultExtensions(CPU, CpuInfo->Arch);
955955
std::vector<StringRef> CPUFeats;
956956
llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
957957
for (auto F : CPUFeats) {
@@ -1033,13 +1033,14 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
10331033
FoundArch = true;
10341034
std::pair<StringRef, StringRef> Split =
10351035
Feature.split("=").second.trim().split("+");
1036-
const llvm::AArch64::ArchInfo &AI = llvm::AArch64::parseArch(Split.first);
1036+
const std::optional<llvm::AArch64::ArchInfo> AI =
1037+
llvm::AArch64::parseArch(Split.first);
10371038

10381039
// Parse the architecture version, adding the required features to
10391040
// Ret.Features.
1040-
if (AI == llvm::AArch64::INVALID)
1041+
if (!AI)
10411042
continue;
1042-
Ret.Features.push_back(AI.ArchFeature.str());
1043+
Ret.Features.push_back(AI->ArchFeature.str());
10431044
// Add any extra features, after the +
10441045
SplitAndAddFeatures(Split.second, Ret.Features);
10451046
} else if (Feature.startswith("cpu=")) {

clang/lib/Driver/ToolChains/Arch/AArch64.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,21 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text,
123123
static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
124124
std::vector<StringRef> &Features) {
125125
std::pair<StringRef, StringRef> Split = Mcpu.split("+");
126+
CPU = Split.first;
126127
const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
127-
CPU = llvm::AArch64::resolveCPUAlias(Split.first);
128128

129129
if (CPU == "native")
130130
CPU = llvm::sys::getHostCPUName();
131131

132132
if (CPU == "generic") {
133133
Features.push_back("+neon");
134134
} else {
135-
ArchInfo = &llvm::AArch64::parseCpu(CPU).Arch;
136-
if (*ArchInfo == llvm::AArch64::INVALID)
135+
const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
136+
llvm::AArch64::parseCpu(CPU);
137+
if (!CpuInfo)
137138
return false;
139+
ArchInfo = &CpuInfo->Arch;
140+
138141
Features.push_back(ArchInfo->ArchFeature);
139142

140143
uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, *ArchInfo);
@@ -156,11 +159,11 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
156159
std::string MarchLowerCase = March.lower();
157160
std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
158161

159-
const llvm::AArch64::ArchInfo *ArchInfo =
160-
&llvm::AArch64::parseArch(Split.first);
162+
std::optional <llvm::AArch64::ArchInfo> ArchInfo =
163+
llvm::AArch64::parseArch(Split.first);
161164
if (Split.first == "native")
162-
ArchInfo = &llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str());
163-
if (*ArchInfo == llvm::AArch64::INVALID)
165+
ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str());
166+
if (!ArchInfo)
164167
return false;
165168
Features.push_back(ArchInfo->ArchFeature);
166169

llvm/include/llvm/TargetParser/AArch64TargetParser.h

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ enum CPUFeatures {
9191
// feature name (though the canonical reference for those is AArch64.td)
9292
// clang-format off
9393
enum ArchExtKind : uint64_t {
94-
AEK_INVALID = 0,
9594
AEK_NONE = 1,
9695
AEK_CRC = 1 << 1, // FEAT_CRC32
9796
AEK_CRYPTO = 1 << 2,
@@ -252,7 +251,6 @@ inline constexpr ExtensionInfo Extensions[] = {
252251
{"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550},
253252
// Special cases
254253
{"none", AArch64::AEK_NONE, {}, {}, FEAT_MAX, "", ExtensionInfo::MaxFMVPriority},
255-
{"invalid", AArch64::AEK_INVALID, {}, {}, FEAT_MAX, "", 0},
256254
};
257255
// clang-format on
258256

@@ -280,12 +278,12 @@ struct ArchInfo {
280278
// v v v v v
281279
// v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a;
282280
//
283-
// v8r and INVALID have no relation to anything. This is used to
284-
// determine which features to enable for a given architecture. See
281+
// v8r has no relation to anything. This is used to determine which
282+
// features to enable for a given architecture. See
285283
// AArch64TargetInfo::setFeatureEnabled.
286284
bool implies(const ArchInfo &Other) const {
287285
if (this->Profile != Other.Profile)
288-
return false; // ARMV8R and INVALID
286+
return false; // ARMV8R
289287
if (this->Version.getMajor() == Other.Version.getMajor()) {
290288
return this->Version > Other.Version;
291289
}
@@ -300,11 +298,10 @@ struct ArchInfo {
300298
StringRef getSubArch() const { return ArchFeature.substr(1); }
301299

302300
// Search for ArchInfo by SubArch name
303-
static const ArchInfo &findBySubArch(StringRef SubArch);
301+
static std::optional<ArchInfo> findBySubArch(StringRef SubArch);
304302
};
305303

306304
// clang-format off
307-
inline constexpr ArchInfo INVALID = { VersionTuple{0, 0}, AProfile, "invalid", "+", (AArch64::AEK_NONE)};
308305
inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (AArch64::AEK_FP | AArch64::AEK_SIMD), };
309306
inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | AArch64::AEK_CRC | AArch64::AEK_LSE | AArch64::AEK_RDM)};
310307
inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | AArch64::AEK_RAS)};
@@ -325,10 +322,10 @@ inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r",
325322
// clang-format on
326323

327324
// The set of all architectures
328-
static constexpr std::array<const ArchInfo *, 17> ArchInfos = {
329-
&INVALID, &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A,
330-
&ARMV8_5A, &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A,
331-
&ARMV9_1A, &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R,
325+
static constexpr std::array<const ArchInfo *, 16> ArchInfos = {
326+
&ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, &ARMV8_5A,
327+
&ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, &ARMV9_1A,
328+
&ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R,
332329
};
333330

334331
// Details of a specific CPU.
@@ -495,8 +492,6 @@ inline constexpr CpuInfo CpuInfos[] = {
495492
(AArch64::AEK_FP16 | AArch64::AEK_RAND | AArch64::AEK_SM4 |
496493
AArch64::AEK_SHA3 | AArch64::AEK_SHA2 | AArch64::AEK_AES |
497494
AArch64::AEK_MTE | AArch64::AEK_SB | AArch64::AEK_SSBS)},
498-
// Invalid CPU
499-
{"invalid", INVALID, (AArch64::AEK_INVALID)},
500495
};
501496

502497
// An alias for a CPU.
@@ -516,13 +511,13 @@ StringRef resolveCPUAlias(StringRef CPU);
516511
// Information by Name
517512
uint64_t getDefaultExtensions(StringRef CPU, const ArchInfo &AI);
518513
void getFeatureOption(StringRef Name, std::string &Feature);
519-
const ArchInfo &getArchForCpu(StringRef CPU);
514+
std::optional<ArchInfo> getArchForCpu(StringRef CPU);
520515

521516
// Parser
522-
const ArchInfo &parseArch(StringRef Arch);
523-
ArchExtKind parseArchExt(StringRef ArchExt);
517+
std::optional<ArchInfo> parseArch(StringRef Arch);
518+
std::optional<ExtensionInfo> parseArchExtension(StringRef Extension);
524519
// Given the name of a CPU or alias, return the correponding CpuInfo.
525-
const CpuInfo &parseCpu(StringRef Name);
520+
std::optional<CpuInfo> parseCpu(StringRef Name);
526521
// Used by target parser tests
527522
void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
528523

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "llvm/Support/AArch64TargetParser.h"
5252
#include "llvm/Support/TargetParser.h"
5353
#include "llvm/Support/raw_ostream.h"
54+
#include "llvm/TargetParser/AArch64TargetParser.h"
5455
#include <cassert>
5556
#include <cctype>
5657
#include <cstdint>
@@ -6880,18 +6881,18 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
68806881
std::tie(Arch, ExtensionString) =
68816882
getParser().parseStringToEndOfStatement().trim().split('+');
68826883

6883-
const AArch64::ArchInfo &ArchInfo = AArch64::parseArch(Arch);
6884-
if (ArchInfo == AArch64::INVALID)
6884+
std::optional<AArch64::ArchInfo> ArchInfo = AArch64::parseArch(Arch);
6885+
if (!ArchInfo)
68856886
return Error(ArchLoc, "unknown arch name");
68866887

68876888
if (parseToken(AsmToken::EndOfStatement))
68886889
return true;
68896890

68906891
// Get the architecture and extension features.
68916892
std::vector<StringRef> AArch64Features;
6892-
AArch64Features.push_back(ArchInfo.ArchFeature);
6893+
AArch64Features.push_back(ArchInfo->ArchFeature);
68936894
AArch64::getExtensionFeatures(
6894-
AArch64::getDefaultExtensions("generic", ArchInfo), AArch64Features);
6895+
AArch64::getDefaultExtensions("generic", *ArchInfo), AArch64Features);
68956896

68966897
MCSubtargetInfo &STI = copySTI();
68976898
std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
@@ -6902,7 +6903,7 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
69026903
if (!ExtensionString.empty())
69036904
ExtensionString.split(RequestedExtensions, '+');
69046905

6905-
ExpandCryptoAEK(ArchInfo, RequestedExtensions);
6906+
ExpandCryptoAEK(*ArchInfo, RequestedExtensions);
69066907

69076908
FeatureBitset Features = STI.getFeatureBits();
69086909
for (auto Name : RequestedExtensions) {
@@ -6987,19 +6988,17 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
69876988
if (!ExtensionString.empty())
69886989
ExtensionString.split(RequestedExtensions, '+');
69896990

6990-
// FIXME This is using tablegen data, but should be moved to ARMTargetParser
6991-
// once that is tablegen'ed
6992-
if (!getSTI().isCPUStringValid(CPU)) {
6991+
const std::optional<llvm::AArch64::ArchInfo> CpuArch = llvm::AArch64::getArchForCpu(CPU);
6992+
if (!CpuArch) {
69936993
Error(CurLoc, "unknown CPU name");
69946994
return false;
69956995
}
6996+
ExpandCryptoAEK(*CpuArch, RequestedExtensions);
69966997

69976998
MCSubtargetInfo &STI = copySTI();
69986999
STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
69997000
CurLoc = incrementLoc(CurLoc, CPU.size());
70007001

7001-
ExpandCryptoAEK(llvm::AArch64::getArchForCpu(CPU), RequestedExtensions);
7002-
70037002
for (auto Name : RequestedExtensions) {
70047003
// Advance source location past '+'.
70057004
CurLoc = incrementLoc(CurLoc, 1);

llvm/lib/TargetParser/AArch64TargetParser.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ uint64_t AArch64::getDefaultExtensions(StringRef CPU,
3131
return AI.DefaultExts;
3232

3333
// Note: this now takes cpu aliases into account
34-
const CpuInfo &Cpu = parseCpu(CPU);
35-
return Cpu.Arch.DefaultExts | Cpu.DefaultExtensions;
34+
std::optional<CpuInfo> Cpu = parseCpu(CPU);
35+
if (!Cpu)
36+
return AI.DefaultExts;
37+
38+
return Cpu->Arch.DefaultExts | Cpu->DefaultExtensions;
3639
}
3740

3841
void AArch64::getFeatureOption(StringRef Name, std::string &Feature) {
@@ -45,20 +48,22 @@ void AArch64::getFeatureOption(StringRef Name, std::string &Feature) {
4548
Feature = Name.str();
4649
}
4750

48-
const AArch64::ArchInfo &AArch64::getArchForCpu(StringRef CPU) {
51+
std::optional<AArch64::ArchInfo> AArch64::getArchForCpu(StringRef CPU) {
4952
if (CPU == "generic")
5053
return ARMV8A;
5154

5255
// Note: this now takes cpu aliases into account
53-
const CpuInfo &Cpu = parseCpu(CPU);
54-
return Cpu.Arch;
56+
std::optional<CpuInfo> Cpu = parseCpu(CPU);
57+
if (!Cpu)
58+
return {};
59+
return Cpu->Arch;
5560
}
5661

57-
const AArch64::ArchInfo &AArch64::ArchInfo::findBySubArch(StringRef SubArch) {
62+
std::optional<AArch64::ArchInfo> AArch64::ArchInfo::findBySubArch(StringRef SubArch) {
5863
for (const auto *A : AArch64::ArchInfos)
5964
if (A->getSubArch() == SubArch)
6065
return *A;
61-
return AArch64::INVALID;
66+
return {};
6267
}
6368

6469
uint64_t AArch64::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) {
@@ -75,9 +80,6 @@ uint64_t AArch64::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) {
7580

7681
bool AArch64::getExtensionFeatures(uint64_t InputExts,
7782
std::vector<StringRef> &Features) {
78-
if (InputExts == AArch64::AEK_INVALID)
79-
return false;
80-
8183
for (const auto &E : Extensions)
8284
/* INVALID and NONE have no feature name. */
8385
if ((InputExts & E.ID) && !E.Feature.empty())
@@ -110,7 +112,6 @@ StringRef AArch64::getArchExtFeature(StringRef ArchExt) {
110112

111113
void AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
112114
for (const auto &C : CpuInfos)
113-
if (C.Arch != INVALID)
114115
Values.push_back(C.Name);
115116

116117
for (const auto &Alias : CpuAliases)
@@ -123,28 +124,28 @@ bool AArch64::isX18ReservedByDefault(const Triple &TT) {
123124
}
124125

125126
// Allows partial match, ex. "v8a" matches "armv8a".
126-
const AArch64::ArchInfo &AArch64::parseArch(StringRef Arch) {
127+
std::optional<AArch64::ArchInfo> AArch64::parseArch(StringRef Arch) {
127128
Arch = llvm::ARM::getCanonicalArchName(Arch);
128129
if (checkArchVersion(Arch) < 8)
129-
return AArch64::INVALID;
130+
return {};
130131

131132
StringRef Syn = llvm::ARM::getArchSynonym(Arch);
132133
for (const auto *A : ArchInfos) {
133134
if (A->Name.endswith(Syn))
134135
return *A;
135136
}
136-
return AArch64::INVALID;
137+
return {};
137138
}
138139

139-
AArch64::ArchExtKind AArch64::parseArchExt(StringRef ArchExt) {
140+
std::optional<AArch64::ExtensionInfo> AArch64::parseArchExtension(StringRef ArchExt) {
140141
for (const auto &A : Extensions) {
141142
if (ArchExt == A.Name)
142-
return static_cast<ArchExtKind>(A.ID);
143+
return A;
143144
}
144-
return AArch64::AEK_INVALID;
145+
return {};
145146
}
146147

147-
const AArch64::CpuInfo &AArch64::parseCpu(StringRef Name) {
148+
std::optional<AArch64::CpuInfo> AArch64::parseCpu(StringRef Name) {
148149
// Resolve aliases first.
149150
Name = resolveCPUAlias(Name);
150151

@@ -153,7 +154,5 @@ const AArch64::CpuInfo &AArch64::parseCpu(StringRef Name) {
153154
if (Name == C.Name)
154155
return C;
155156

156-
// "generic" returns invalid.
157-
assert(Name != "invalid" && "Unexpected recursion.");
158-
return parseCpu("invalid");
157+
return {};
159158
}

0 commit comments

Comments
 (0)