ilinpv created this revision.
ilinpv added reviewers: tmatheson, danielkiss.
Herald added a subscriber: kristof.beyls.
Herald added a reviewer: aaron.ballman.
Herald added a project: All.
ilinpv requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D145538
Files:
clang/include/clang/Basic/TargetInfo.h
clang/lib/AST/ASTContext.cpp
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/Basic/Targets/AArch64.h
clang/lib/Sema/SemaDeclAttr.cpp
llvm/include/llvm/TargetParser/AArch64TargetParser.h
Index: llvm/include/llvm/TargetParser/AArch64TargetParser.h
===================================================================
--- llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -25,6 +25,9 @@
class Triple;
namespace AArch64 {
+// Function Multi Versioning CPU features. They must be kept in sync with
+// compiler-rt enum CPUFeatures in lib/builtins/cpu_model.c with FEAT_MAX as
+// sentinel.
enum CPUFeatures {
FEAT_RNG,
FEAT_FLAGM,
@@ -155,17 +158,18 @@
// SubtargetFeature which may represent either an actual extension or some
// internal LLVM property.
struct ExtensionInfo {
- StringRef Name; // Human readable name, e.g. "profile".
- ArchExtKind ID; // Corresponding to the ArchExtKind, this extensions
- // representation in the bitfield.
- StringRef Feature; // -mattr enable string, e.g. "+spe"
- StringRef NegFeature; // -mattr disable string, e.g. "-spe"
-
- // FIXME These were added by D127812 FMV support and need documenting:
- CPUFeatures CPUFeature; // Bitfield value set in __aarch64_cpu_features
- StringRef DependentFeatures;
- unsigned FmvPriority;
- static constexpr unsigned MaxFMVPriority = 1000;
+ StringRef Name; // Human readable name, e.g. "profile".
+ ArchExtKind ID; // Corresponding to the ArchExtKind, this
+ // extensions representation in the bitfield.
+ StringRef Feature; // -mattr enable string, e.g. "+spe"
+ StringRef NegFeature; // -mattr disable string, e.g. "-spe"
+ CPUFeatures CPUFeature; // Function Multi Versioning (FMV) bitfield value
+ // set in __aarch64_cpu_features
+ StringRef DependentFeatures; // FMV enabled features string,
+ // e.g. "+dotprod,+fp-armv8,+neon"
+ unsigned FmvPriority; // FMV feature priority
+ static constexpr unsigned MaxFMVPriority =
+ 1000; // Maximum priority for FMV feature
};
// clang-format off
@@ -559,6 +563,9 @@
void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
bool isX18ReservedByDefault(const Triple &TT);
+
+// For given features returns a mask to check if CPU support them. The mask is
+// used in Function Multi Versioning resolver conditions code generation.
uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs);
} // namespace AArch64
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -3508,6 +3508,7 @@
enum SecondParam { None, CPU, Tune };
enum ThirdParam { Target, TargetClones };
HasCommas = HasCommas || Str.contains(',');
+ const TargetInfo &TInfo = Context.getTargetInfo();
// Warn on empty at the beginning of a string.
if (Str.size() == 0)
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
@@ -3517,9 +3518,9 @@
while (!Parts.second.empty()) {
Parts = Parts.second.split(',');
StringRef Cur = Parts.first.trim();
- SourceLocation CurLoc = Literal->getLocationOfByte(
- Cur.data() - Literal->getString().data(), getSourceManager(),
- getLangOpts(), Context.getTargetInfo());
+ SourceLocation CurLoc =
+ Literal->getLocationOfByte(Cur.data() - Literal->getString().data(),
+ getSourceManager(), getLangOpts(), TInfo);
bool DefaultIsDupe = false;
bool HasCodeGenImpact = false;
@@ -3527,7 +3528,7 @@
return Diag(CurLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << "" << TargetClones;
- if (Context.getTargetInfo().getTriple().isAArch64()) {
+ if (TInfo.getTriple().isAArch64()) {
// AArch64 target clones specific
if (Cur == "default") {
DefaultIsDupe = HasDefault;
@@ -3542,13 +3543,12 @@
while (!CurParts.second.empty()) {
CurParts = CurParts.second.split('+');
StringRef CurFeature = CurParts.first.trim();
- if (!Context.getTargetInfo().validateCpuSupports(CurFeature)) {
+ if (!TInfo.validateCpuSupports(CurFeature)) {
Diag(CurLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << CurFeature << TargetClones;
continue;
}
- std::string Options;
- if (Context.getTargetInfo().getFeatureDepOptions(CurFeature, Options))
+ if (TInfo.doesFeatureAffectCodeGen(CurFeature))
HasCodeGenImpact = true;
CurFeatures.push_back(CurFeature);
}
Index: clang/lib/Basic/Targets/AArch64.h
===================================================================
--- clang/lib/Basic/Targets/AArch64.h
+++ clang/lib/Basic/Targets/AArch64.h
@@ -143,9 +143,8 @@
std::optional<std::pair<unsigned, unsigned>>
getVScaleRange(const LangOptions &LangOpts) const override;
-
- bool getFeatureDepOptions(StringRef Feature,
- std::string &Options) const override;
+ bool doesFeatureAffectCodeGen(StringRef Name) const override;
+ StringRef getFeatureDependencies(StringRef Name) const override;
bool validateCpuSupports(StringRef FeatureStr) const override;
bool hasFeature(StringRef Feature) const override;
void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
Index: clang/lib/Basic/Targets/AArch64.cpp
===================================================================
--- clang/lib/Basic/Targets/AArch64.cpp
+++ clang/lib/Basic/Targets/AArch64.cpp
@@ -606,16 +606,18 @@
return llvm::AArch64::ExtensionInfo::MaxFMVPriority;
}
-bool AArch64TargetInfo::getFeatureDepOptions(StringRef Name,
- std::string &FeatureVec) const {
- FeatureVec = "";
- for (const auto &E : llvm::AArch64::Extensions) {
- if (Name == E.Name) {
- FeatureVec = E.DependentFeatures;
- break;
- }
- }
- return FeatureVec != "";
+bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
+ for (const auto &E : llvm::AArch64::Extensions)
+ if (Name == E.Name)
+ return !E.DependentFeatures.empty();
+ return false;
+}
+
+StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const {
+ for (const auto &E : llvm::AArch64::Extensions)
+ if (Name == E.Name)
+ return E.DependentFeatures;
+ return StringRef();
}
bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
@@ -962,18 +964,18 @@
}
// Process target and dependent features. This is done in two loops collecting
- // them into UpdatedFeaturesVec: first to add dependent '+'features,
- // second to add target '+/-'features that can later disable some of
- // features added on the first loop.
+ // them into UpdatedFeaturesVec: first to add dependent '+'features, second to
+ // add target '+/-'features that can later disable some of features added on
+ // the first loop. Function Multi Versioning features begin with '?'.
for (const auto &Feature : FeaturesVec)
- if ((Feature[0] == '?' || Feature[0] == '+')) {
- std::string Options;
- if (AArch64TargetInfo::getFeatureDepOptions(Feature.substr(1), Options)) {
- SmallVector<StringRef, 1> AttrFeatures;
- StringRef(Options).split(AttrFeatures, ",");
- for (auto F : AttrFeatures)
- UpdatedFeaturesVec.push_back(F.str());
- }
+ if (((Feature[0] == '?' || Feature[0] == '+')) &&
+ AArch64TargetInfo::doesFeatureAffectCodeGen(Feature.substr(1))) {
+ StringRef DepFeatures =
+ AArch64TargetInfo::getFeatureDependencies(Feature.substr(1));
+ SmallVector<StringRef, 1> AttrFeatures;
+ DepFeatures.split(AttrFeatures, ",");
+ for (auto F : AttrFeatures)
+ UpdatedFeaturesVec.push_back(F.str());
}
for (const auto &Feature : FeaturesVec)
if (Feature[0] != '?') {
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -13456,6 +13456,7 @@
TV->getFeatures(Feats);
for (auto &Feature : Feats)
if (Target->validateCpuSupports(Feature.str()))
+ // Use '?' to mark features that came from TargetVersion
ResFeats.push_back("?" + Feature.str());
return ResFeats;
}
@@ -13525,6 +13526,7 @@
VersionStr.split(VersionFeatures, "+");
for (auto &VFeature : VersionFeatures) {
VFeature = VFeature.trim();
+ // Use '?' to mark features that came from AArch64 TargetClones
Features.push_back((StringRef{"?"} + VFeature).str());
}
}
Index: clang/include/clang/Basic/TargetInfo.h
===================================================================
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -1333,12 +1333,16 @@
}
/// Returns true if feature has an impact on target code
- /// generation and get its dependent options in second argument.
- virtual bool getFeatureDepOptions(StringRef Feature,
- std::string &Options) const {
+ /// generation
+ virtual bool doesFeatureAffectCodeGen(StringRef Feature) const {
return true;
}
+ /// For given feature return dependent ones.
+ virtual StringRef getFeatureDependencies(StringRef Feature) const {
+ return StringRef();
+ }
+
struct BranchProtectionInfo {
LangOptions::SignReturnAddressScopeKind SignReturnAddr =
LangOptions::SignReturnAddressScopeKind::None;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits