Author: Pavel Iliin Date: 2023-03-08T23:22:46Z New Revision: 124b46a897a7044be3cb49b9e0097d8cca47ba6b
URL: https://github.com/llvm/llvm-project/commit/124b46a897a7044be3cb49b9e0097d8cca47ba6b DIFF: https://github.com/llvm/llvm-project/commit/124b46a897a7044be3cb49b9e0097d8cca47ba6b.diff LOG: [NFC][AArch64] Document and improve FMV code. Differential Revision: https://reviews.llvm.org/D145538 Added: Modified: 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 Removed: ################################################################################ diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 1bdee3f416a90..6de5d90b12634 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1333,12 +1333,16 @@ class TargetInfo : public virtual TransferrableTargetInfo, } /// 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; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1995030eec25f..90448c378458b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13456,6 +13456,7 @@ std::vector<std::string> ASTContext::filterFunctionTargetVersionAttrs( 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 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap, 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()); } } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 9b67becff9e75..7f331004348f1 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -606,16 +606,18 @@ unsigned AArch64TargetInfo::multiVersionFeatureCost() const { 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 { + auto F = llvm::find_if(llvm::AArch64::Extensions, [&](const auto &E) { + return Name == E.Name && !E.DependentFeatures.empty(); + }); + return F != std::end(llvm::AArch64::Extensions); +} + +StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const { + auto F = llvm::find_if(llvm::AArch64::Extensions, + [&](const auto &E) { return Name == E.Name; }); + return F != std::end(llvm::AArch64::Extensions) ? F->DependentFeatures + : StringRef(); } bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const { @@ -962,18 +964,18 @@ bool AArch64TargetInfo::initFeatureMap( } // 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] != '?') { diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 46bfb70a0d953..ee2c179d7c3df 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -143,9 +143,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { 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, diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 5a6e07c81041b..229e73618c53c 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3508,6 +3508,7 @@ bool Sema::checkTargetClonesAttrString( 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 @@ bool Sema::checkTargetClonesAttrString( 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 @@ bool Sema::checkTargetClonesAttrString( 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 @@ bool Sema::checkTargetClonesAttrString( 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); } diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index 3e800bdfc61f4..133d10c11e57b 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -25,6 +25,9 @@ namespace llvm { 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, @@ -87,6 +90,9 @@ enum CPUFeatures { FEAT_MAX }; +static_assert(FEAT_MAX <= 64, + "CPUFeatures enum must not have more than 64 entries"); + // Arch extension modifiers for CPUs. These are labelled with their Arm ARM // feature name (though the canonical reference for those is AArch64.td) // clang-format off @@ -155,17 +161,18 @@ enum ArchExtKind : uint64_t { // 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 +566,10 @@ std::optional<CpuInfo> parseCpu(StringRef Name); void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values); bool isX18ReservedByDefault(const Triple &TT); + +// For given feature names, return a bitmask corresponding to the entries of +// AArch64::CPUFeatures. The values in CPUFeatures are not bitmasks +// themselves, they are sequential (0, 1, 2, 3, ...). uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs); } // namespace AArch64 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits