https://github.com/tmatheson-arm updated https://github.com/llvm/llvm-project/pull/92882
>From b3e9e2f313d3c3a51b7b6690a5cca67a3ec87dd6 Mon Sep 17 00:00:00 2001 From: Tomas Matheson <tomas.mathe...@arm.com> Date: Tue, 18 Jun 2024 22:23:11 +0100 Subject: [PATCH 1/2] [AArch64][TargetParser] Split FMV and extensions --- clang/include/clang/Basic/TargetInfo.h | 5 - clang/lib/AST/ASTContext.cpp | 4 +- clang/lib/Basic/Targets/AArch64.cpp | 20 +- clang/lib/Basic/Targets/AArch64.h | 1 - clang/lib/CodeGen/CGBuiltin.cpp | 2 +- clang/lib/CodeGen/Targets/AArch64.cpp | 2 +- clang/test/CodeGen/aarch64-fmv-dependencies.c | 92 ++++---- .../llvm/TargetParser/AArch64TargetParser.h | 32 ++- llvm/lib/Target/AArch64/AArch64.td | 1 + llvm/lib/Target/AArch64/AArch64FMV.td | 99 +++++++++ llvm/lib/Target/AArch64/AArch64Features.td | 206 ++++-------------- llvm/lib/TargetParser/AArch64TargetParser.cpp | 30 ++- llvm/utils/TableGen/ARMTargetDefEmitter.cpp | 36 ++- 13 files changed, 281 insertions(+), 249 deletions(-) create mode 100644 llvm/lib/Target/AArch64/AArch64FMV.td diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 8a6511b9ced83..9b0ae2102e098 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1400,11 +1400,6 @@ class TargetInfo : public TransferrableTargetInfo, return true; } - /// For given feature return dependent ones. - virtual StringRef getFeatureDependencies(StringRef Feature) const { - return StringRef(); - } - struct BranchProtectionInfo { LangOptions::SignReturnAddressScopeKind SignReturnAddr; LangOptions::SignReturnAddressKeyKind SignKey; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index aa22825602a40..5329fb6bf22f5 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13683,9 +13683,9 @@ static std::vector<std::string> getFMVBackendFeaturesFor( const llvm::SmallVectorImpl<StringRef> &FMVFeatStrings) { std::vector<std::string> BackendFeats; for (StringRef F : FMVFeatStrings) { - if (auto FMVExt = llvm::AArch64::parseArchExtension(F)) { + if (auto FMVExt = llvm::AArch64::parseFMVExtension(F)) { SmallVector<StringRef, 8> Feats; - FMVExt->DependentFeatures.split(Feats, ',', -1, false); + FMVExt->Features.split(Feats, ',', -1, false); for (StringRef F : Feats) BackendFeats.push_back(F.str()); } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index fba2ad00df96d..31d8121b91d10 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -673,34 +673,30 @@ AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const { if (Name == "default") return 0; - if (auto Ext = llvm::AArch64::parseArchExtension(Name)) - return Ext->FmvPriority; + if (auto Ext = llvm::AArch64::parseFMVExtension(Name)) + return Ext->Priority; return 0; } unsigned AArch64TargetInfo::multiVersionFeatureCost() const { // Take the maximum priority as per feature cost, so more features win. - return llvm::AArch64::ExtensionInfo::MaxFMVPriority; + constexpr unsigned MaxFMVPriority = 1000; + return MaxFMVPriority; } bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const { - if (auto Ext = llvm::AArch64::parseArchExtension(Name)) - return !Ext->DependentFeatures.empty(); + // FMV extensions which imply no backend features do not affect codegen. + if (auto Ext = llvm::AArch64::parseFMVExtension(Name)) + return !Ext->Features.empty(); return false; } -StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const { - if (auto Ext = llvm::AArch64::parseArchExtension(Name)) - return Ext->DependentFeatures; - return StringRef(); -} - bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const { // CPU features might be separated by '+', extract them and check llvm::SmallVector<StringRef, 8> Features; FeatureStr.split(Features, "+"); for (auto &Feature : Features) - if (!llvm::AArch64::parseArchExtension(Feature.trim()).has_value()) + if (!llvm::AArch64::parseFMVExtension(Feature.trim()).has_value()) return false; return true; } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index c0a6bd2de6b04..71510fe289510 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -151,7 +151,6 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { std::optional<std::pair<unsigned, unsigned>> getVScaleRange(const LangOptions &LangOpts) 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/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 08a89bd123d03..3524e660cd7eb 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -14192,7 +14192,7 @@ Value *CodeGenFunction::EmitAArch64CpuSupports(const CallExpr *E) { ArgStr.split(Features, "+"); for (auto &Feature : Features) { Feature = Feature.trim(); - if (!llvm::AArch64::parseArchExtension(Feature)) + if (!llvm::AArch64::parseFMVExtension(Feature)) return Builder.getFalse(); if (Feature != "default") Features.push_back(Feature); diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index cfb4b5f58ef72..8ebf3d9a51b50 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -965,7 +965,7 @@ void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr, llvm::SmallDenseSet<StringRef, 8> UniqueFeats; for (auto &Feat : Features) - if (auto Ext = llvm::AArch64::parseArchExtension(Feat)) + if (auto Ext = llvm::AArch64::parseFMVExtension(Feat)) if (UniqueFeats.insert(Ext->Name).second) Out << 'M' << Ext->Name; } diff --git a/clang/test/CodeGen/aarch64-fmv-dependencies.c b/clang/test/CodeGen/aarch64-fmv-dependencies.c index ec599e1b3fa76..e39c7adbe4a9b 100644 --- a/clang/test/CodeGen/aarch64-fmv-dependencies.c +++ b/clang/test/CodeGen/aarch64-fmv-dependencies.c @@ -192,49 +192,49 @@ int caller() { return fmv(); } -// CHECK: attributes #[[ATTR0:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[bf16_ebf16:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[bti:[0-9]+]] = { {{.*}} "target-features"="+bti,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[crc:[0-9]+]] = { {{.*}} "target-features"="+crc,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[dit:[0-9]+]] = { {{.*}} "target-features"="+dit,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[dotprod:[0-9]+]] = { {{.*}} "target-features"="+dotprod,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[dpb:[0-9]+]] = { {{.*}} "target-features"="+ccpp,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[dpb2:[0-9]+]] = { {{.*}} "target-features"="+ccdp,+ccpp,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[f32mm:[0-9]+]] = { {{.*}} "target-features"="+f32mm,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" -// CHECK: attributes #[[f64mm:[0-9]+]] = { {{.*}} "target-features"="+f64mm,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" -// CHECK: attributes #[[fcma:[0-9]+]] = { {{.*}} "target-features"="+complxnum,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[flagm:[0-9]+]] = { {{.*}} "target-features"="+flagm,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[flagm2:[0-9]+]] = { {{.*}} "target-features"="+altnzcv,+flagm,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[fp16:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[fp16fml:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fp16fml,+fullfp16,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[frintts:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fptoint,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[i8mm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+i8mm,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[jscvt:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+jsconv,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[ls64_accdata:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+ls64,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[lse:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+lse,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[memtag2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+mte,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[mops:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+mops,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[pmull:[0-9]+]] = { {{.*}} "target-features"="+aes,+fp-armv8,+neon,+outline-atomics,+v8a" -// CHECK: attributes #[[predres:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+predres,+v8a" -// CHECK: attributes #[[rcpc:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rcpc,+v8a" -// CHECK: attributes #[[rcpc3:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rcpc,+rcpc3,+v8a" -// CHECK: attributes #[[rdm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rdm,+v8a" -// CHECK: attributes #[[rng:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rand,+v8a" -// CHECK: attributes #[[sb:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sb,+v8a" -// CHECK: attributes #[[sha2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sha2,+v8a" -// CHECK: attributes #[[sha3:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sha2,+sha3,+v8a" -// CHECK: attributes #[[sm4:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sm4,+v8a" -// CHECK: attributes #[[sme:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+v8a" -// CHECK: attributes #[[sme_f64f64:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme-f64f64,+v8a" -// CHECK: attributes #[[sme_i16i64:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme-i16i64,+v8a" -// CHECK: attributes #[[sme2:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme2,+v8a" -// CHECK: attributes #[[ssbs2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+ssbs,+v8a" -// CHECK: attributes #[[sve:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" -// CHECK: attributes #[[sve_bf16_ebf16:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" -// CHECK: attributes #[[sve_i8mm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+i8mm,+neon,+outline-atomics,+sve,+v8a" -// CHECK: attributes #[[sve2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+v8a" -// CHECK: attributes #[[sve2_aes_sve2_pmull128:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-aes,+v8a" -// CHECK: attributes #[[sve2_bitperm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-bitperm,+v8a" -// CHECK: attributes #[[sve2_sha3:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-sha3,+v8a" -// CHECK: attributes #[[sve2_sm4:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-sm4,+v8a" -// CHECK: attributes #[[wfxt:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,+wfxt" +// CHECK: attributes #[[ATTR0]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[bf16_ebf16]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[bti]] = { {{.*}} "target-features"="+bti,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[crc]] = { {{.*}} "target-features"="+crc,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[dit]] = { {{.*}} "target-features"="+dit,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[dotprod]] = { {{.*}} "target-features"="+dotprod,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[dpb]] = { {{.*}} "target-features"="+ccpp,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[dpb2]] = { {{.*}} "target-features"="+ccdp,+ccpp,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[f32mm]] = { {{.*}} "target-features"="+f32mm,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" +// CHECK: attributes #[[f64mm]] = { {{.*}} "target-features"="+f64mm,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" +// CHECK: attributes #[[fcma]] = { {{.*}} "target-features"="+complxnum,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[flagm]] = { {{.*}} "target-features"="+flagm,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[flagm2]] = { {{.*}} "target-features"="+altnzcv,+flagm,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[fp16]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[fp16fml]] = { {{.*}} "target-features"="+fp-armv8,+fp16fml,+fullfp16,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[frintts]] = { {{.*}} "target-features"="+fp-armv8,+fptoint,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[i8mm]] = { {{.*}} "target-features"="+fp-armv8,+i8mm,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[jscvt]] = { {{.*}} "target-features"="+fp-armv8,+jsconv,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[ls64_accdata]] = { {{.*}} "target-features"="+fp-armv8,+ls64,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[lse]] = { {{.*}} "target-features"="+fp-armv8,+lse,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[memtag2]] = { {{.*}} "target-features"="+fp-armv8,+mte,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[mops]] = { {{.*}} "target-features"="+fp-armv8,+mops,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[pmull]] = { {{.*}} "target-features"="+aes,+fp-armv8,+neon,+outline-atomics,+v8a" +// CHECK: attributes #[[predres]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+predres,+v8a" +// CHECK: attributes #[[rcpc]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rcpc,+v8a" +// CHECK: attributes #[[rcpc3]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rcpc,+rcpc3,+v8a" +// CHECK: attributes #[[rdm]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rdm,+v8a" +// CHECK: attributes #[[rng]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rand,+v8a" +// CHECK: attributes #[[sb]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sb,+v8a" +// CHECK: attributes #[[sha2]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sha2,+v8a" +// CHECK: attributes #[[sha3]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sha2,+sha3,+v8a" +// CHECK: attributes #[[sm4]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sm4,+v8a" +// CHECK: attributes #[[sme]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+v8a" +// CHECK: attributes #[[sme_f64f64]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme-f64f64,+v8a" +// CHECK: attributes #[[sme_i16i64]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme-i16i64,+v8a" +// CHECK: attributes #[[sme2]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme2,+v8a" +// CHECK: attributes #[[ssbs2]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+ssbs,+v8a" +// CHECK: attributes #[[sve]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" +// CHECK: attributes #[[sve_bf16_ebf16]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" +// CHECK: attributes #[[sve_i8mm]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+i8mm,+neon,+outline-atomics,+sve,+v8a" +// CHECK: attributes #[[sve2]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+v8a" +// CHECK: attributes #[[sve2_aes_sve2_pmull128]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-aes,+v8a" +// CHECK: attributes #[[sve2_bitperm]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-bitperm,+v8a" +// CHECK: attributes #[[sve2_sha3]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-sha3,+v8a" +// CHECK: attributes #[[sve2_sm4]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-sm4,+v8a" +// CHECK: attributes #[[wfxt]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,+wfxt" diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index b15c62b683787..f81ee1f93bfdd 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -19,6 +19,8 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/VersionTuple.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/SubtargetFeature.h" #include <array> #include <vector> @@ -120,18 +122,29 @@ struct ExtensionInfo { // 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 }; #define EMIT_EXTENSIONS #include "llvm/TargetParser/AArch64TargetParserDef.inc" +struct FMVInfo { + StringRef Name; // The target_version/target_clones spelling. + CPUFeatures Bit; // Index of the bit in the FMV feature bitset. + StringRef Features; // List of SubtargetFeatures to enable. + unsigned Priority; // FMV priority. + FMVInfo(StringRef Name, CPUFeatures Bit, StringRef Features, + unsigned Priority) + : Name(Name), Bit(Bit), Features(Features), Priority(Priority){}; + + SmallVector<StringRef, 8> getImpliedFeatures() { + SmallVector<StringRef, 8> Feats; + Features.split(Feats, ',', -1, false); // discard empty strings + return Feats; + } +}; + +const std::vector<FMVInfo>& getFMVInfo(); + // Represents a dependency between two architecture extensions. Later is the // feature which was added to the architecture after Earlier, and expands the // functionality provided by it. If Later is enabled, then Earlier will also be @@ -281,6 +294,8 @@ struct ExtensionSet { Features.emplace_back(T(E.NegFeature)); } } + + void dump() const; }; // Name alias. @@ -313,6 +328,9 @@ std::optional<ExtensionInfo> targetFeatureToExtension(StringRef TargetFeature); // Parse a name as defined by the Extension class in tablegen. std::optional<ExtensionInfo> parseArchExtension(StringRef Extension); +// Parse a name as defined by the FMVInfo class in tablegen. +std::optional<FMVInfo> parseFMVExtension(StringRef Extension); + // Given the name of a CPU or alias, return the correponding CpuInfo. std::optional<CpuInfo> parseCpu(StringRef Name); // Used by target parser tests diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index 5708b6173750a..2c1a9cfa67a67 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -19,6 +19,7 @@ include "llvm/Target/Target.td" // Subtarget features. //===----------------------------------------------------------------------===// include "AArch64Features.td" +include "AArch64FMV.td" //===----------------------------------------------------------------------===// // Register File Description diff --git a/llvm/lib/Target/AArch64/AArch64FMV.td b/llvm/lib/Target/AArch64/AArch64FMV.td new file mode 100644 index 0000000000000..7a40c83b2bb21 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64FMV.td @@ -0,0 +1,99 @@ +//=------ AArch64FMV.td - Describe AArch64 FMV Features ------*- tablegen -*-=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Function MultiVersioning (FMV) properties. FMV features are accepted by the +// attributes target_version and target_clones, and they correspond to a mapping +// from the FMV feature name to: +// - A bit in the FMV ABI, as defined by the ACLE. +// - The FMV priority, as defined by the ACLE. +// - A list of backend features. +// +// The list of backend features is not a set of dependencies; it is specific to +// LLVM and indicates how to do codegen when the FMV feature is present. +// +// Therefore FMVExtensions are separated from regular AArch64 Extensions, which +// encode dependencies between themselves and other SubtargetFeatures. +//===----------------------------------------------------------------------===// + + +// Something you can add to target_version or target_clones. +class FMVExtension<string n, string b, string f, int p> { + // Name, as spelled in target_version or target_clones. e.g. "memtag". + string Name = n; + + // A C++ expression giving the number of the bit in the FMV ABI. + // Currently this is given as a value from the enum "CPUFeatures". + string Bit = b; + + // SubtargetFeatures enabled for codegen when this FMV feature is present. + string BackendFeatures = f; + + // The FMV priority. + int Priority = p; +} + +def : FMVExtension<"aes", "FEAT_AES", "+fp-armv8,+neon", 150>; +def : FMVExtension<"bf16", "FEAT_BF16", "+bf16", 280>; +def : FMVExtension<"bti", "FEAT_BTI", "+bti", 510>; +def : FMVExtension<"crc", "FEAT_CRC", "+crc", 110>; +def : FMVExtension<"dgh", "FEAT_DGH", "", 260>; +def : FMVExtension<"dit", "FEAT_DIT", "+dit", 180>; +def : FMVExtension<"dotprod", "FEAT_DOTPROD", "+dotprod,+fp-armv8,+neon", 104>; +def : FMVExtension<"dpb", "FEAT_DPB", "+ccpp", 190>; +def : FMVExtension<"dpb2", "FEAT_DPB2", "+ccpp,+ccdp", 200>; +def : FMVExtension<"ebf16", "FEAT_EBF16", "+bf16", 290>; +def : FMVExtension<"f32mm", "FEAT_SVE_F32MM", "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350>; +def : FMVExtension<"f64mm", "FEAT_SVE_F64MM", "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360>; +def : FMVExtension<"fcma", "FEAT_FCMA", "+fp-armv8,+neon,+complxnum", 220>; +def : FMVExtension<"flagm", "FEAT_FLAGM", "+flagm", 20>; +def : FMVExtension<"flagm2", "FEAT_FLAGM2", "+flagm,+altnzcv", 30>; +def : FMVExtension<"fp", "FEAT_FP", "+fp-armv8,+neon", 90>; +def : FMVExtension<"fp16", "FEAT_FP16", "+fullfp16,+fp-armv8,+neon", 170>; +def : FMVExtension<"fp16fml", "FEAT_FP16FML", "+fp16fml,+fullfp16,+fp-armv8,+neon", 175>; +def : FMVExtension<"frintts", "FEAT_FRINTTS", "+fptoint", 250>; +def : FMVExtension<"i8mm", "FEAT_I8MM", "+i8mm", 270>; +def : FMVExtension<"jscvt", "FEAT_JSCVT", "+fp-armv8,+neon,+jsconv", 210>; +def : FMVExtension<"ls64", "FEAT_LS64", "", 520>; +def : FMVExtension<"ls64_accdata", "FEAT_LS64_ACCDATA", "+ls64", 540>; +def : FMVExtension<"ls64_v", "FEAT_LS64_V", "", 530>; +def : FMVExtension<"lse", "FEAT_LSE", "+lse", 80>; +def : FMVExtension<"memtag", "FEAT_MEMTAG", "", 440>; +def : FMVExtension<"memtag2", "FEAT_MEMTAG2", "+mte", 450>; +def : FMVExtension<"memtag3", "FEAT_MEMTAG3", "+mte", 460>; +def : FMVExtension<"mops", "FEAT_MOPS", "+mops", 650>; +def : FMVExtension<"pmull", "FEAT_PMULL", "+aes,+fp-armv8,+neon", 160>; +def : FMVExtension<"predres", "FEAT_PREDRES", "+predres", 480>; +def : FMVExtension<"rcpc", "FEAT_RCPC", "+rcpc", 230>; +def : FMVExtension<"rcpc2", "FEAT_RCPC2", "+rcpc", 240>; +def : FMVExtension<"rcpc3", "FEAT_RCPC3", "+rcpc,+rcpc3", 241>; +def : FMVExtension<"rdm", "FEAT_RDM", "+rdm,+fp-armv8,+neon", 108>; +def : FMVExtension<"rng", "FEAT_RNG", "+rand", 10>; +def : FMVExtension<"rpres", "FEAT_RPRES", "", 300>; +def : FMVExtension<"sb", "FEAT_SB", "+sb", 470>; +def : FMVExtension<"sha1", "FEAT_SHA1", "+fp-armv8,+neon", 120>; +def : FMVExtension<"sha2", "FEAT_SHA2", "+sha2,+fp-armv8,+neon", 130>; +def : FMVExtension<"sha3", "FEAT_SHA3", "+sha3,+sha2,+fp-armv8,+neon", 140>; +def : FMVExtension<"simd", "FEAT_SIMD", "+fp-armv8,+neon", 100>; +def : FMVExtension<"sm4", "FEAT_SM4", "+sm4,+fp-armv8,+neon", 106>; +def : FMVExtension<"sme", "FEAT_SME", "+sme,+bf16", 430>; +def : FMVExtension<"sme-f64f64", "FEAT_SME_F64", "+sme,+sme-f64f64,+bf16", 560>; +def : FMVExtension<"sme-i16i64", "FEAT_SME_I64", "+sme,+sme-i16i64,+bf16", 570>; +def : FMVExtension<"sme2", "FEAT_SME2", "+sme2,+sme,+bf16", 580>; +def : FMVExtension<"ssbs", "FEAT_SSBS", "", 490>; +def : FMVExtension<"ssbs2", "FEAT_SSBS2", "+ssbs", 500>; +def : FMVExtension<"sve", "FEAT_SVE", "+sve,+fullfp16,+fp-armv8,+neon", 310>; +def : FMVExtension<"sve-bf16", "FEAT_SVE_BF16", "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320>; +def : FMVExtension<"sve-ebf16", "FEAT_SVE_EBF16", "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330>; +def : FMVExtension<"sve-i8mm", "FEAT_SVE_I8MM", "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340>; +def : FMVExtension<"sve2", "FEAT_SVE2", "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370>; +def : FMVExtension<"sve2-aes", "FEAT_SVE_AES", "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380>; +def : FMVExtension<"sve2-bitperm", "FEAT_SVE_BITPERM", "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400>; +def : FMVExtension<"sve2-pmull128", "FEAT_SVE_PMULL128", "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390>; +def : FMVExtension<"sve2-sha3", "FEAT_SVE_SHA3", "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410>; +def : FMVExtension<"sve2-sm4", "FEAT_SVE_SM4", "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420>; +def : FMVExtension<"wfxt", "FEAT_WFXT", "+wfxt", 550>; diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td index ffb899a301459..76f07d3b66f04 100644 --- a/llvm/lib/Target/AArch64/AArch64Features.td +++ b/llvm/lib/Target/AArch64/AArch64Features.td @@ -11,24 +11,11 @@ // A SubtargetFeature that can be toggled from the command line, and therefore // has an AEK_* entry in ArmExtKind. -// -// If Function MultiVersioning (FMV) properties are left at their defaults -// (FEAT_INIT, no dependencies, priority 0) it indiates that this extension is -// not an FMV feature, but can be enabled via the command line (-march, -mcpu, -// etc). -// -// Conversely if the ArchExtKindSpelling is set to AEK_NONE, this indicates -// that a feature is FMV-only, and can not be selected on the command line. -// Such extensions should be added via FMVOnlyExtension. class Extension< string TargetFeatureName, // String used for -target-feature and -march, unless overridden. string Spelling, // The XYZ in HasXYZ and AEK_XYZ. string Desc, // Description. - list<SubtargetFeature> Implies = [], // List of dependent features. - // FMV properties - string _FMVBit = "FEAT_INIT", // FEAT_INIT is repurposed to indicate "not an FMV feature" - string _FMVDependencies = "", - int _FMVPriority = 0 + list<SubtargetFeature> Implies = [] // List of dependent features. > : SubtargetFeature<TargetFeatureName, "Has" # Spelling, "true", Desc, > Implies> { string ArchExtKindSpelling = "AEK_" # Spelling; // ArchExtKind enum name. @@ -42,57 +29,9 @@ class Extension< // An alias that can be used on the command line, if the extension has one. // Used for correcting historical names while remaining backwards compatible. string MArchAlias = ""; - - // Function MultiVersioning (FMV) properties - - // A C++ expression giving the number of the bit in the FMV ABI. - // Currently this is given as a value from the enum "CPUFeatures". - // If this is not set, it indicates that this is not an FMV extension. - string FMVBit = _FMVBit; - - // List of features that this feature depends on. - // FIXME generate this from Implies. - string FMVDependencies = _FMVDependencies; - - // The FMV priority - int FMVPriority = _FMVPriority; } -// Some extensions are available for FMV but can not be controlled via the -// command line. These entries: -// - are SubtargetFeatures, so they have (unused) FieldNames on the subtarget -// e.g. HasFMVOnlyFEAT_XYZ -// - have incorrect (empty) Implies fields, because the code that handles FMV -// ignores these dependencies and looks only at FMVDependencies. -// - have no description. -// -// In the generated data structures for extensions (ExtensionInfo), AEK_NONE is -// used to indicate that a feature is FMV only. Therefore ArchExtKindSpelling is -// manually overridden here. -class FMVOnlyExtension<string FMVBit, string Name, string Deps, int Priority> - : Extension<Name, "FMVOnly"#FMVBit, "", [], FMVBit, Deps, Priority> { - let ArchExtKindSpelling = "AEK_NONE"; // AEK_NONE indicates FMV-only feature -} -def : FMVOnlyExtension<"FEAT_DGH", "dgh", "", 260>; -def : FMVOnlyExtension<"FEAT_DPB", "dpb", "+ccpp", 190>; -def : FMVOnlyExtension<"FEAT_DPB2", "dpb2", "+ccpp,+ccdp", 200>; -def : FMVOnlyExtension<"FEAT_EBF16", "ebf16", "+bf16", 290>; -def : FMVOnlyExtension<"FEAT_FLAGM2", "flagm2", "+flagm,+altnzcv", 30>; -def : FMVOnlyExtension<"FEAT_FRINTTS", "frintts", "+fptoint", 250>; -def : FMVOnlyExtension<"FEAT_LS64_ACCDATA", "ls64_accdata", "+ls64", 540>; -def : FMVOnlyExtension<"FEAT_LS64_V", "ls64_v", "", 530>; -def : FMVOnlyExtension<"FEAT_MEMTAG2", "memtag2", "+mte", 450>; -def : FMVOnlyExtension<"FEAT_MEMTAG3", "memtag3", "+mte", 460>; -def : FMVOnlyExtension<"FEAT_PMULL", "pmull", "+aes,+fp-armv8,+neon", 160>; -def : FMVOnlyExtension<"FEAT_RCPC2", "rcpc2", "+rcpc", 240>; -def : FMVOnlyExtension<"FEAT_RPRES", "rpres", "", 300>; -def : FMVOnlyExtension<"FEAT_SHA1", "sha1", "+fp-armv8,+neon", 120>; -def : FMVOnlyExtension<"FEAT_SSBS2", "ssbs2", "+ssbs", 500>; -def : FMVOnlyExtension<"FEAT_SVE_BF16", "sve-bf16", "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320>; -def : FMVOnlyExtension<"FEAT_SVE_EBF16", "sve-ebf16", "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330>; -def : FMVOnlyExtension<"FEAT_SVE_I8MM", "sve-i8mm", "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340>; -def : FMVOnlyExtension<"FEAT_SVE_PMULL128", "sve2-pmull128", "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390>; // Each SubtargetFeature which corresponds to an Arm Architecture feature should @@ -103,33 +42,27 @@ def : FMVOnlyExtension<"FEAT_SVE_PMULL128", "sve2-pmull128", "+sve2,+sve,+sve2-a let ArchExtKindSpelling = "AEK_FP", MArchName = "fp" in def FeatureFPARMv8 : Extension<"fp-armv8", "FPARMv8", - "Enable ARMv8 (FEAT_FP)", [], - "FEAT_FP", "+fp-armv8,+neon", 90>; + "Enable ARMv8 (FEAT_FP)">; let ArchExtKindSpelling = "AEK_SIMD", MArchName = "simd" in def FeatureNEON : Extension<"neon", "NEON", - "Enable Advanced SIMD instructions (FEAT_AdvSIMD)", [FeatureFPARMv8], - "FEAT_SIMD", "+fp-armv8,+neon", 100>; + "Enable Advanced SIMD instructions (FEAT_AdvSIMD)", [FeatureFPARMv8]>; def FeatureSM4 : Extension< "sm4", "SM4", - "Enable SM3 and SM4 support (FEAT_SM4, FEAT_SM3)", [FeatureNEON], - "FEAT_SM4", "+sm4,+fp-armv8,+neon", 106>; + "Enable SM3 and SM4 support (FEAT_SM4, FEAT_SM3)", [FeatureNEON]>; def FeatureSHA2 : Extension< "sha2", "SHA2", - "Enable SHA1 and SHA256 support (FEAT_SHA1, FEAT_SHA256)", [FeatureNEON], - "FEAT_SHA2", "+sha2,+fp-armv8,+neon", 130>; + "Enable SHA1 and SHA256 support (FEAT_SHA1, FEAT_SHA256)", [FeatureNEON]>; def FeatureSHA3 : Extension< "sha3", "SHA3", - "Enable SHA512 and SHA3 support (FEAT_SHA3, FEAT_SHA512)", [FeatureNEON, FeatureSHA2], - "FEAT_SHA3", "+sha3,+sha2,+fp-armv8,+neon", 140>; + "Enable SHA512 and SHA3 support (FEAT_SHA3, FEAT_SHA512)", [FeatureNEON, FeatureSHA2]>; def FeatureAES : Extension< "aes", "AES", - "Enable AES support (FEAT_AES, FEAT_PMULL)", [FeatureNEON], - "FEAT_AES", "+fp-armv8,+neon", 150>; + "Enable AES support (FEAT_AES, FEAT_PMULL)", [FeatureNEON]>; // Crypto has been split up and any combination is now valid (see the // crypto definitions above). Also, crypto is now context sensitive: @@ -139,13 +72,11 @@ def FeatureAES : Extension< // meaning anymore. We kept the Crypto definition here for backward // compatibility, and now imply features SHA2 and AES, which was the // "traditional" meaning of Crypto. -let FMVDependencies = "+aes,+sha2" in def FeatureCrypto : Extension<"crypto", "Crypto", "Enable cryptographic instructions", [FeatureNEON, FeatureSHA2, FeatureAES]>; def FeatureCRC : Extension<"crc", "CRC", - "Enable ARMv8 CRC-32 checksum instructions (FEAT_CRC32)", [], - "FEAT_CRC", "+crc", 110>; + "Enable ARMv8 CRC-32 checksum instructions (FEAT_CRC32)">; def FeatureRAS : Extension<"ras", "RAS", "Enable ARMv8 Reliability, Availability and Serviceability Extensions (FEAT_RAS, FEAT_RASv1p1)">; @@ -155,8 +86,7 @@ def FeatureRASv2 : Extension<"rasv2", "RASv2", [FeatureRAS]>; def FeatureLSE : Extension<"lse", "LSE", - "Enable ARMv8.1 Large System Extension (LSE) atomic instructions (FEAT_LSE)", [], - "FEAT_LSE", "+lse", 80>; + "Enable ARMv8.1 Large System Extension (LSE) atomic instructions (FEAT_LSE)">; def FeatureLSE2 : SubtargetFeature<"lse2", "HasLSE2", "true", "Enable ARMv8.4 Large System Extension 2 (LSE2) atomicity rules (FEAT_LSE2)">; @@ -170,8 +100,7 @@ def FeatureFMV : SubtargetFeature<"fmv", "HasFMV", "true", let MArchAlias = "rdma" in def FeatureRDM : Extension<"rdm", "RDM", "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions (FEAT_RDM)", - [FeatureNEON], - "FEAT_RDM", "+rdm,+fp-armv8,+neon", 108>; + [FeatureNEON]>; def FeaturePAN : SubtargetFeature< "pan", "HasPAN", "true", @@ -196,12 +125,10 @@ def FeaturePerfMon : Extension<"perfmon", "PerfMon", let ArchExtKindSpelling = "AEK_FP16", MArchName = "fp16" in def FeatureFullFP16 : Extension<"fullfp16", "FullFP16", - "Full FP16 (FEAT_FP16)", [FeatureFPARMv8], - "FEAT_FP16", "+fullfp16,+fp-armv8,+neon", 170>; + "Full FP16 (FEAT_FP16)", [FeatureFPARMv8]>; def FeatureFP16FML : Extension<"fp16fml", "FP16FML", - "Enable FP16 FML instructions (FEAT_FHM)", [FeatureFullFP16], - "FEAT_FP16FML", "+fp16fml,+fullfp16,+fp-armv8,+neon", 175>; + "Enable FP16 FML instructions (FEAT_FHM)", [FeatureFullFP16]>; let ArchExtKindSpelling = "AEK_PROFILE", MArchName = "profile" in def FeatureSPE : Extension<"spe", "SPE", @@ -220,8 +147,7 @@ def FeatureCCPP : SubtargetFeature<"ccpp", "HasCCPP", "true", "Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)" >; def FeatureSVE : Extension<"sve", "SVE", - "Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)", [FeatureFullFP16], - "FEAT_SVE", "+sve,+fullfp16,+fp-armv8,+neon", 310>; + "Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)", [FeatureFullFP16]>; // This flag is currently still labeled as Experimental, but when fully // implemented this should tell the compiler to use the zeroing pseudos to @@ -245,35 +171,28 @@ def FeatureUseScalarIncVL : SubtargetFeature<"use-scalar-inc-vl", "UseScalarIncVL", "true", "Prefer inc/dec over add+cnt">; def FeatureBF16 : Extension<"bf16", "BF16", - "Enable BFloat16 Extension (FEAT_BF16)", [], - "FEAT_BF16", "+bf16", 280>; + "Enable BFloat16 Extension (FEAT_BF16)">; def FeatureNoSVEFPLD1R : SubtargetFeature<"no-sve-fp-ld1r", "NoSVEFPLD1R", "true", "Avoid using LD1RX instructions for FP">; def FeatureSVE2 : Extension<"sve2", "SVE2", "Enable Scalable Vector Extension 2 (SVE2) instructions (FEAT_SVE2)", - [FeatureSVE, FeatureUseScalarIncVL], - "FEAT_SVE2", "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370>; + [FeatureSVE, FeatureUseScalarIncVL]>; def FeatureSVE2AES : Extension<"sve2-aes", "SVE2AES", "Enable AES SVE2 instructions (FEAT_SVE_AES, FEAT_SVE_PMULL128)", - [FeatureSVE2, FeatureAES], - "FEAT_SVE_AES", "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380>; + [FeatureSVE2, FeatureAES]>; def FeatureSVE2SM4 : Extension<"sve2-sm4", "SVE2SM4", - "Enable SM4 SVE2 instructions (FEAT_SVE_SM4)", [FeatureSVE2, FeatureSM4], - "FEAT_SVE_SM4", "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420>; + "Enable SM4 SVE2 instructions (FEAT_SVE_SM4)", [FeatureSVE2, FeatureSM4]>; def FeatureSVE2SHA3 : Extension<"sve2-sha3", "SVE2SHA3", - "Enable SHA3 SVE2 instructions (FEAT_SVE_SHA3)", [FeatureSVE2, FeatureSHA3], - "FEAT_SVE_SHA3", "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410>; + "Enable SHA3 SVE2 instructions (FEAT_SVE_SHA3)", [FeatureSVE2, FeatureSHA3]>; def FeatureSVE2BitPerm : Extension<"sve2-bitperm", "SVE2BitPerm", - "Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)", [FeatureSVE2], - "FEAT_SVE_BITPERM", "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400>; + "Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)", [FeatureSVE2]>; -let FMVDependencies = "+sve2p1,+sve2,+sve,+fullfp16,+fp-armv8,+neon" in def FeatureSVE2p1: Extension<"sve2p1", "SVE2p1", "Enable Scalable Vector Extension 2.1 instructions", [FeatureSVE2]>; @@ -410,8 +329,7 @@ def FeatureForce32BitJumpTables "Force jump table entries to be 32-bits wide except at MinSize">; def FeatureRCPC : Extension<"rcpc", "RCPC", - "Enable support for RCPC extension (FEAT_LRCPC)", [], - "FEAT_RCPC", "+rcpc", 230>; + "Enable support for RCPC extension (FEAT_LRCPC)">; def FeatureUseRSqrt : SubtargetFeature< "use-reciprocal-square-root", "UseRSqrt", "true", @@ -419,8 +337,7 @@ def FeatureUseRSqrt : SubtargetFeature< def FeatureDotProd : Extension< "dotprod", "DotProd", - "Enable dot product support (FEAT_DotProd)", [FeatureNEON], - "FEAT_DOTPROD", "+dotprod,+fp-armv8,+neon", 104>; + "Enable dot product support (FEAT_DotProd)", [FeatureNEON]>; def FeaturePAuth : Extension< "pauth", "PAuth", @@ -430,8 +347,7 @@ let ArchExtKindSpelling = "AEK_JSCVT", MArchName = "jscvt" in def FeatureJS : Extension< "jsconv", "JS", "Enable v8.3-A JavaScript FP conversion instructions (FEAT_JSCVT)", - [FeatureFPARMv8], - "FEAT_JSCVT", "+fp-armv8,+neon,+jsconv", 210>; + [FeatureFPARMv8]>; def FeatureCCIDX : SubtargetFeature< "ccidx", "HasCCIDX", "true", @@ -441,8 +357,7 @@ let ArchExtKindSpelling = "AEK_FCMA", MArchName = "fcma" in def FeatureComplxNum : Extension< "complxnum", "ComplxNum", "Enable v8.3-A Floating-point complex number support (FEAT_FCMA)", - [FeatureNEON], - "FEAT_FCMA", "+fp-armv8,+neon,+complxnum", 220>; + [FeatureNEON]>; def FeatureNV : SubtargetFeature< "nv", "HasNV", "true", @@ -454,8 +369,7 @@ def FeatureMPAM : SubtargetFeature< def FeatureDIT : Extension< "dit", "DIT", - "Enable v8.4-A Data Independent Timing instructions (FEAT_DIT)", [], - "FEAT_DIT", "+dit", 180>; + "Enable v8.4-A Data Independent Timing instructions (FEAT_DIT)">; def FeatureTRACEV8_4 : SubtargetFeature< "tracev8.4", "HasTRACEV8_4", "true", @@ -480,8 +394,7 @@ def FeatureTLB_RMI : SubtargetFeature< def FeatureFlagM : Extension< "flagm", "FlagM", - "Enable v8.4-A Flag Manipulation Instructions (FEAT_FlagM)", [], - "FEAT_FLAGM", "+flagm", 20>; + "Enable v8.4-A Flag Manipulation Instructions (FEAT_FlagM)">; // 8.4 RCPC enchancements: LDAPR & STLR instructions with Immediate Offset def FeatureRCPC_IMMO : SubtargetFeature<"rcpc-immo", "HasRCPC_IMMO", "true", @@ -529,41 +442,34 @@ def FeatureSpecRestrict : SubtargetFeature<"specrestrict", "HasSpecRestrict", "true", "Enable architectural speculation restriction (FEAT_CSV2_2)">; def FeatureSB : Extension<"sb", "SB", - "Enable v8.5 Speculation Barrier (FEAT_SB)", [], - "FEAT_SB", "+sb", 470>; + "Enable v8.5 Speculation Barrier (FEAT_SB)">; def FeatureSSBS : Extension<"ssbs", "SSBS", - "Enable Speculative Store Bypass Safe bit (FEAT_SSBS, FEAT_SSBS2)", [], - "FEAT_SSBS", "", 490>; + "Enable Speculative Store Bypass Safe bit (FEAT_SSBS, FEAT_SSBS2)">; def FeaturePredRes : Extension<"predres", "PredRes", - "Enable v8.5a execution and data prediction invalidation instructions (FEAT_SPECRES)", [], - "FEAT_PREDRES", "+predres", 480>; + "Enable v8.5a execution and data prediction invalidation instructions (FEAT_SPECRES)">; -def FeatureCacheDeepPersist : SubtargetFeature<"ccdp", "CCDP", "true", +def FeatureCacheDeepPersist : SubtargetFeature<"ccdp", "HasCCDP", "true", "Enable v8.5 Cache Clean to Point of Deep Persistence (FEAT_DPB2)" >; -let ArchExtKindSpelling = "AEK_NONE" in -def FeatureBranchTargetId : Extension<"bti", "BTI", - "Enable Branch Target Identification (FEAT_BTI)", [], - "FEAT_BTI", "+bti", 510>; +def FeatureBranchTargetId : SubtargetFeature<"bti", "HasBTI", "true", + "Enable Branch Target Identification (FEAT_BTI)">; let ArchExtKindSpelling = "AEK_RAND", MArchName = "rng" in def FeatureRandGen : Extension<"rand", "RandGen", - "Enable Random Number generation instructions (FEAT_RNG)", [], - "FEAT_RNG", "+rand", 10>; + "Enable Random Number generation instructions (FEAT_RNG)">; // NOTE: "memtag" means FEAT_MTE + FEAT_MTE2 for -march or // __attribute((target(...))), but only FEAT_MTE for FMV. let MArchName = "memtag" in def FeatureMTE : Extension<"mte", "MTE", - "Enable Memory Tagging Extension (FEAT_MTE, FEAT_MTE2)", [], - "FEAT_MEMTAG", "", 440>; + "Enable Memory Tagging Extension (FEAT_MTE, FEAT_MTE2)">; -def FeatureTRBE : SubtargetFeature<"trbe", "TRBE", "true", +def FeatureTRBE : SubtargetFeature<"trbe", "HasTRBE", "true", "Enable Trace Buffer Extension (FEAT_TRBE)">; -def FeatureETE : SubtargetFeature<"ete", "ETE", "true", +def FeatureETE : SubtargetFeature<"ete", "HasETE", "true", "Enable Embedded Trace Extension (FEAT_ETE)", [FeatureTRBE]>; @@ -577,39 +483,33 @@ def FeatureTaggedGlobals : SubtargetFeature<"tagged-globals", let ArchExtKindSpelling = "AEK_I8MM" in def FeatureMatMulInt8 : Extension<"i8mm", "MatMulInt8", - "Enable Matrix Multiply Int8 Extension (FEAT_I8MM)", [], - "FEAT_I8MM", "+i8mm", 270>; + "Enable Matrix Multiply Int8 Extension (FEAT_I8MM)">; let ArchExtKindSpelling = "AEK_F32MM" in def FeatureMatMulFP32 : Extension<"f32mm", "MatMulFP32", - "Enable Matrix Multiply FP32 Extension (FEAT_F32MM)", [FeatureSVE], - "FEAT_SVE_F32MM", "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350>; + "Enable Matrix Multiply FP32 Extension (FEAT_F32MM)", [FeatureSVE]>; let ArchExtKindSpelling = "AEK_F64MM" in def FeatureMatMulFP64 : Extension<"f64mm", "MatMulFP64", - "Enable Matrix Multiply FP64 Extension (FEAT_F64MM)", [FeatureSVE], - "FEAT_SVE_F64MM", "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360>; + "Enable Matrix Multiply FP64 Extension (FEAT_F64MM)", [FeatureSVE]>; def FeatureXS : SubtargetFeature<"xs", "HasXS", "true", "Enable Armv8.7-A limited-TLB-maintenance instruction (FEAT_XS)">; def FeatureWFxT : Extension<"wfxt", "WFxT", - "Enable Armv8.7-A WFET and WFIT instruction (FEAT_WFxT)", [], - "FEAT_WFXT", "+wfxt", 550>; + "Enable Armv8.7-A WFET and WFIT instruction (FEAT_WFxT)", []>; def FeatureHCX : SubtargetFeature< "hcx", "HasHCX", "true", "Enable Armv8.7-A HCRX_EL2 system register (FEAT_HCX)">; def FeatureLS64 : Extension<"ls64", "LS64", - "Enable Armv8.7-A LD64B/ST64B Accelerator Extension (FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA)", [], - "FEAT_LS64", "", 520>; + "Enable Armv8.7-A LD64B/ST64B Accelerator Extension (FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA)">; def FeatureHBC : Extension<"hbc", "HBC", "Enable Armv8.8-A Hinted Conditional Branches Extension (FEAT_HBC)">; def FeatureMOPS : Extension<"mops", "MOPS", - "Enable Armv8.8-A memcpy and memset acceleration instructions (FEAT_MOPS)", [], - "FEAT_MOPS", "+mops", 650>; + "Enable Armv8.8-A memcpy and memset acceleration instructions (FEAT_MOPS)">; def FeatureNMI : SubtargetFeature<"nmi", "HasNMI", "true", "Enable Armv8.8-A Non-maskable Interrupts (FEAT_NMI, FEAT_GICv3_NMI)">; @@ -631,29 +531,23 @@ def FeatureRME : SubtargetFeature<"rme", "HasRME", "true", "Enable Realm Management Extension (FEAT_RME)">; def FeatureSME : Extension<"sme", "SME", - "Enable Scalable Matrix Extension (SME) (FEAT_SME)", [FeatureBF16, FeatureUseScalarIncVL], - "FEAT_SME", "+sme,+bf16", 430>; + "Enable Scalable Matrix Extension (SME) (FEAT_SME)", [FeatureBF16, FeatureUseScalarIncVL]>; def FeatureSMEF64F64 : Extension<"sme-f64f64", "SMEF64F64", - "Enable Scalable Matrix Extension (SME) F64F64 instructions (FEAT_SME_F64F64)", [FeatureSME], - "FEAT_SME_F64", "+sme,+sme-f64f64,+bf16", 560>; + "Enable Scalable Matrix Extension (SME) F64F64 instructions (FEAT_SME_F64F64)", [FeatureSME]>; def FeatureSMEI16I64 : Extension<"sme-i16i64", "SMEI16I64", - "Enable Scalable Matrix Extension (SME) I16I64 instructions (FEAT_SME_I16I64)", [FeatureSME], - "FEAT_SME_I64", "+sme,+sme-i16i64,+bf16", 570>; + "Enable Scalable Matrix Extension (SME) I16I64 instructions (FEAT_SME_I16I64)", [FeatureSME]>; def FeatureSMEFA64 : Extension<"sme-fa64", "SMEFA64", "Enable the full A64 instruction set in streaming SVE mode (FEAT_SME_FA64)", [FeatureSME, FeatureSVE2]>; def FeatureSME2 : Extension<"sme2", "SME2", - "Enable Scalable Matrix Extension 2 (SME2) instructions", [FeatureSME], - "FEAT_SME2", "+sme2,+sme,+bf16", 580>; + "Enable Scalable Matrix Extension 2 (SME2) instructions", [FeatureSME]>; -let FMVDependencies = "+sme2,+sme-f16f16" in def FeatureSMEF16F16 : Extension<"sme-f16f16", "SMEF16F16", "Enable SME non-widening Float16 instructions (FEAT_SME_F16F16)", [FeatureSME2]>; -let FMVDependencies = "+sme2p1,+sme2,+sme,+bf16" in def FeatureSME2p1 : Extension<"sme2p1", "SME2p1", "Enable Scalable Matrix Extension 2.1 (FEAT_SME2p1) instructions", [FeatureSME2]>; @@ -669,7 +563,6 @@ def FeatureFP8 : Extension<"fp8", "FP8", def FeatureFP8FMA : Extension<"fp8fma", "FP8FMA", "Enable fp8 multiply-add instructions (FEAT_FP8FMA)", [FeatureFP8]>; -let FMVDependencies = "+sme2" in def FeatureSSVE_FP8FMA : Extension<"ssve-fp8fma", "SSVE_FP8FMA", "Enable SVE2 fp8 multiply-add instructions (FEAT_SSVE_FP8FMA)", [FeatureSME2, FeatureFP8]>; @@ -679,22 +572,18 @@ def FeatureFP8DOT4: Extension<"fp8dot4", "FP8DOT4", def FeatureFP8DOT2: Extension<"fp8dot2", "FP8DOT2", "Enable fp8 2-way dot instructions (FEAT_FP8DOT2)", [FeatureFP8DOT4]>; -let FMVDependencies = "+sme2" in def FeatureSSVE_FP8DOT4 : Extension<"ssve-fp8dot4", "SSVE_FP8DOT4", "Enable SVE2 fp8 4-way dot product instructions (FEAT_SSVE_FP8DOT4)", [FeatureSSVE_FP8FMA]>; -let FMVDependencies = "+sme2" in def FeatureSSVE_FP8DOT2 : Extension<"ssve-fp8dot2", "SSVE_FP8DOT2", "Enable SVE2 fp8 2-way dot product instructions (FEAT_SSVE_FP8DOT2)", [FeatureSSVE_FP8DOT4]>; def FeatureSME_LUTv2 : Extension<"sme-lutv2", "SME_LUTv2", "Enable Scalable Matrix Extension (SME) LUTv2 instructions (FEAT_SME_LUTv2)">; -let FMVDependencies = "+sme2,+fp8" in def FeatureSMEF8F32 : Extension<"sme-f8f32", "SMEF8F32", "Enable Scalable Matrix Extension (SME) F8F32 instructions (FEAT_SME_F8F32)", [FeatureSME2, FeatureFP8]>; -let FMVDependencies = "+fp8,+sme2" in def FeatureSMEF8F16 : Extension<"sme-f8f16", "SMEF8F16", "Enable Scalable Matrix Extension (SME) F8F16 instructions(FEAT_SME_F8F16)", [FeatureSMEF8F32]>; @@ -744,8 +633,7 @@ def FeatureITE : Extension<"ite", "ITE", def FeatureRCPC3 : Extension<"rcpc3", "RCPC3", "Enable Armv8.9-A RCPC instructions for A64 and Advanced SIMD and floating-point instruction set (FEAT_LRCPC3)", - [FeatureRCPC_IMMO], - "FEAT_RCPC3", "+rcpc,+rcpc3", 241>; + [FeatureRCPC_IMMO]>; def FeatureTHE : Extension<"the", "THE", "Enable Armv8.9-A Translation Hardening Extension (FEAT_THE)">; @@ -914,4 +802,4 @@ def FeatureHardenSlsNoComdat : SubtargetFeature<"harden-sls-nocomdat", // Only intended to be used by disassemblers. def FeatureAll - : SubtargetFeature<"all", "IsAll", "true", "Enable all instructions", []>; + : SubtargetFeature<"all", "IsAll", "true", "Enable all instructions">; diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp index 58cae70d5ac97..c1ff1aad64f9a 100644 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -23,6 +23,9 @@ using namespace llvm; +#define EMIT_FMV_INFO +#include "llvm/TargetParser/AArch64TargetParserDef.inc" + static unsigned checkArchVersion(llvm::StringRef Arch) { if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1])) return (Arch[1] - 48); @@ -47,8 +50,8 @@ std::optional<AArch64::ArchInfo> AArch64::ArchInfo::findBySubArch(StringRef SubA uint64_t AArch64::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) { uint64_t FeaturesMask = 0; for (const StringRef &FeatureStr : FeatureStrs) { - if (auto Ext = parseArchExtension(FeatureStr)) - FeaturesMask |= (1ULL << Ext->CPUFeature); + if (auto Ext = parseFMVExtension(FeatureStr)) + FeaturesMask |= (1ULL << Ext->Bit); } return FeaturesMask; } @@ -76,7 +79,7 @@ StringRef AArch64::getArchExtFeature(StringRef ArchExt) { StringRef ArchExtBase = IsNegated ? ArchExt.drop_front(2) : ArchExt; if (auto AE = parseArchExtension(ArchExtBase)) { - // Note: the returned string can be empty. + assert(!(AE.has_value() && AE->NegFeature.empty())); return IsNegated ? AE->NegFeature : AE->Feature; } @@ -119,6 +122,19 @@ AArch64::parseArchExtension(StringRef ArchExt) { return {}; } +std::optional<AArch64::FMVInfo> +AArch64::parseFMVExtension(StringRef FMVExt) { + // FIXME introduce general alias functionality, or remove this exception. + if (FMVExt == "rdma") + FMVExt = "rdm"; + + for (const auto &I : getFMVInfo()) { + if (FMVExt == I.Name) + return I; + } + return {}; +} + std::optional<AArch64::ExtensionInfo> AArch64::targetFeatureToExtension(StringRef TargetFeature) { for (const auto &E : Extensions) @@ -280,6 +296,14 @@ void AArch64::ExtensionSet::reconstructFromParsedFeatures( } } +void AArch64::ExtensionSet::dump() const { + std::vector<StringRef> Features; + toLLVMFeatureList(Features); + for (StringRef F : Features) + llvm::outs() << F << " "; + llvm::outs() << "\n"; +} + const AArch64::ExtensionInfo & AArch64::getExtensionByID(AArch64::ArchExtKind ExtID) { return lookupExtensionByID(ExtID); diff --git a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp index 5f5e014892138..756d936c65a2b 100644 --- a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp @@ -101,25 +101,37 @@ static void EmitARMTargetDef(RecordKeeper &RK, raw_ostream &OS) { else OS << ", \"" << Alias << "\""; OS << ", AArch64::" << AEK; - if (AEK == "AEK_NONE") { - // HACK: don't emit posfeat/negfeat strings for FMVOnlyExtensions. - OS << ", {}, {}"; - } else { - OS << ", \"+" << Rec->getValueAsString("Name") << "\""; // posfeature - OS << ", \"-" << Rec->getValueAsString("Name") << "\""; // negfeature - } - OS << ", " << Rec->getValueAsString("FMVBit"); - OS << ", \"" << Rec->getValueAsString("FMVDependencies") << "\""; - OS << ", " << (uint64_t)Rec->getValueAsInt("FMVPriority"); + OS << ", \"+" << Rec->getValueAsString("Name") << "\""; // posfeature + OS << ", \"-" << Rec->getValueAsString("Name") << "\""; // negfeature OS << "},\n"; }; - OS << " {\"none\", {}, AArch64::AEK_NONE, {}, {}, FEAT_INIT, \"\", " - "ExtensionInfo::MaxFMVPriority},\n"; + OS << " {\"none\", {}, AArch64::AEK_NONE, {}, {} },\n"; OS << "};\n" << "#undef EMIT_EXTENSIONS\n" << "#endif // EMIT_EXTENSIONS\n" << "\n"; + // Emit FMV information + auto FMVExts = RK.getAllDerivedDefinitionsIfDefined("FMVExtension"); + OS << "#ifdef EMIT_FMV_INFO\n" + << "const std::vector<llvm::AArch64::FMVInfo>& llvm::AArch64::getFMVInfo() {\n" + << " static std::vector<FMVInfo> I;\n" + << " if(I.size()) return I;\n" + << " I.reserve(" << FMVExts.size() << ");\n"; + for (const Record *Rec : FMVExts) { + OS << " I.emplace_back("; + OS << "\"" << Rec->getValueAsString("Name") << "\""; + OS << ", " << Rec->getValueAsString("Bit"); + OS << ", \"" << Rec->getValueAsString("BackendFeatures") << "\""; + OS << ", " << (uint64_t)Rec->getValueAsInt("Priority"); + OS << ");\n"; + }; + OS << " return I;\n" + << "}\n" + << "#undef EMIT_FMV_INFO\n" + << "#endif // EMIT_FMV_INFO\n" + << "\n"; + // Emit extension dependencies OS << "#ifdef EMIT_EXTENSION_DEPENDENCIES\n" << "inline constexpr ExtensionDependency ExtensionDependencies[] = {\n"; >From fe42ad55a3304aeb12b2c823640e5bd7cd0287ae Mon Sep 17 00:00:00 2001 From: Tomas Matheson <tomas.mathe...@arm.com> Date: Wed, 19 Jun 2024 08:30:34 +0100 Subject: [PATCH 2/2] clang-format --- llvm/include/llvm/TargetParser/AArch64TargetParser.h | 10 +++++----- llvm/lib/TargetParser/AArch64TargetParser.cpp | 3 +-- llvm/utils/TableGen/ARMTargetDefEmitter.cpp | 3 ++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index f81ee1f93bfdd..a40bca9563cdd 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -128,10 +128,10 @@ struct ExtensionInfo { #include "llvm/TargetParser/AArch64TargetParserDef.inc" struct FMVInfo { - StringRef Name; // The target_version/target_clones spelling. - CPUFeatures Bit; // Index of the bit in the FMV feature bitset. - StringRef Features; // List of SubtargetFeatures to enable. - unsigned Priority; // FMV priority. + StringRef Name; // The target_version/target_clones spelling. + CPUFeatures Bit; // Index of the bit in the FMV feature bitset. + StringRef Features; // List of SubtargetFeatures to enable. + unsigned Priority; // FMV priority. FMVInfo(StringRef Name, CPUFeatures Bit, StringRef Features, unsigned Priority) : Name(Name), Bit(Bit), Features(Features), Priority(Priority){}; @@ -143,7 +143,7 @@ struct FMVInfo { } }; -const std::vector<FMVInfo>& getFMVInfo(); +const std::vector<FMVInfo> &getFMVInfo(); // Represents a dependency between two architecture extensions. Later is the // feature which was added to the architecture after Earlier, and expands the diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp index c1ff1aad64f9a..7986f07538df7 100644 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -122,8 +122,7 @@ AArch64::parseArchExtension(StringRef ArchExt) { return {}; } -std::optional<AArch64::FMVInfo> -AArch64::parseFMVExtension(StringRef FMVExt) { +std::optional<AArch64::FMVInfo> AArch64::parseFMVExtension(StringRef FMVExt) { // FIXME introduce general alias functionality, or remove this exception. if (FMVExt == "rdma") FMVExt = "rdm"; diff --git a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp index 756d936c65a2b..e22f353b451f9 100644 --- a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp @@ -114,7 +114,8 @@ static void EmitARMTargetDef(RecordKeeper &RK, raw_ostream &OS) { // Emit FMV information auto FMVExts = RK.getAllDerivedDefinitionsIfDefined("FMVExtension"); OS << "#ifdef EMIT_FMV_INFO\n" - << "const std::vector<llvm::AArch64::FMVInfo>& llvm::AArch64::getFMVInfo() {\n" + << "const std::vector<llvm::AArch64::FMVInfo>& " + "llvm::AArch64::getFMVInfo() {\n" << " static std::vector<FMVInfo> I;\n" << " if(I.size()) return I;\n" << " I.reserve(" << FMVExts.size() << ");\n"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits