llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-clang-codegen Author: Alexandros Lamprineas (labrinea) <details> <summary>Changes</summary> Before this patch all of the 'target', 'target_version' and 'target_clones' attributes were sharing a common mangling logic across different targets. However we would like to differenciate this logic, therefore I have moved the default path to TargetInfo and provided overrides for AArch64. This way we can resolve feature aliases without affecting the name mangling The PR #<!-- -->80540 demonstrates a motivating case. --- Full diff: https://github.com/llvm/llvm-project/pull/81893.diff 5 Files Affected: - (modified) clang/include/clang/Basic/TargetInfo.h (+8) - (modified) clang/lib/Basic/TargetInfo.cpp (+51) - (modified) clang/lib/Basic/Targets/AArch64.cpp (+27) - (modified) clang/lib/Basic/Targets/AArch64.h (+7) - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+13-95) ``````````diff diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 2f80234c0dc7e3..7ea4e0c0197761 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_TARGETINFO_H #define LLVM_CLANG_BASIC_TARGETINFO_H +#include "clang/AST/Attr.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/CodeGenOptions.h" @@ -1321,6 +1322,13 @@ class TargetInfo : public TransferrableTargetInfo, return isValidCPUName(Name); } + virtual std::string getManglingSuffixFromAttr(TargetAttr *Attr) const; + virtual std::string getManglingSuffixFromAttr(TargetVersionAttr *Attr) const; + virtual std::string getManglingSuffixFromAttr(TargetClonesAttr *Attr, + unsigned VersionIndex) const; + + virtual std::string getManglingSuffixFromStr(StringRef AttrStr) const; + virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const; /// Determine whether this TargetInfo supports tune in target attribute. diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 08fb0f2bb1bad6..c17fd4949ef0cd 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -535,6 +535,57 @@ bool TargetInfo::initFeatureMap( return true; } +std::string TargetInfo::getManglingSuffixFromAttr(TargetAttr *Attr) const { + if (Attr->isDefaultVersion()) + return {}; + + return getManglingSuffixFromStr(Attr->getFeaturesStr()); +} + +std::string +TargetInfo::getManglingSuffixFromAttr(TargetVersionAttr *Attr) const { + return getManglingSuffixFromStr(Attr->getNamesStr()); +} + +std::string TargetInfo::getManglingSuffixFromAttr(TargetClonesAttr *Attr, + unsigned Index) const { + std::string Suffix = getManglingSuffixFromStr(Attr->getFeatureStr(Index)); + Suffix.append("." + Twine(Attr->getMangledIndex(Index)).str()); + return Suffix; +} + +std::string TargetInfo::getManglingSuffixFromStr(StringRef AttrStr) const { + if (AttrStr == "default") + return ".default"; + + std::string ManglingSuffix("."); + ParsedTargetAttr Info = parseTargetAttr(AttrStr); + + llvm::sort(Info.Features, [this](StringRef LHS, StringRef RHS) { + // Multiversioning doesn't allow "no-${feature}", so we can + // only have "+" prefixes here. + assert(LHS.starts_with("+") && RHS.starts_with("+") && + "Features should always have a prefix."); + return multiVersionSortPriority(LHS.substr(1)) > + multiVersionSortPriority(RHS.substr(1)); + }); + + bool IsFirst = true; + if (!Info.CPU.empty()) { + IsFirst = false; + ManglingSuffix.append(Twine("arch_", Info.CPU).str()); + } + + for (StringRef Feat : Info.Features) { + if (!IsFirst) + ManglingSuffix.append("_"); + IsFirst = false; + ManglingSuffix.append(Feat.substr(1).str()); + } + + return ManglingSuffix; +} + ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const { ParsedTargetAttr Ret; if (Features == "default") diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index c49461bd20eeec..d288c431a46207 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1105,6 +1105,33 @@ bool AArch64TargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec); } +std::string AArch64TargetInfo::getManglingSuffixFromAttr(TargetClonesAttr *Attr, + unsigned Index) const { + return getManglingSuffixFromStr(Attr->getFeatureStr(Index)); +} + +std::string AArch64TargetInfo::getManglingSuffixFromStr(StringRef Str) const { + if (Str == "default") + return ".default"; + + std::string ManglingSuffix("._"); + SmallVector<StringRef, 8> Features; + Str.split(Features, "+"); + for (auto &Feat : Features) + Feat = Feat.trim(); + + // TODO Lexicographical order won't break the ABI if priorities change. + llvm::sort(Features, [this](const StringRef LHS, const StringRef RHS) { + return multiVersionSortPriority(LHS) < multiVersionSortPriority(RHS); + }); + + for (auto &Feat : Features) + if (auto Ext = llvm::AArch64::parseArchExtension(Feat)) + ManglingSuffix.append(Twine("M", Ext->Name).str()); + + return ManglingSuffix; +} + // Parse AArch64 Target attributes, which are a comma separated list of: // "arch=<arch>" - parsed to features as per -march=.. // "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu> diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index f4ec3543f4082c..d5b09e064660e9 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -164,7 +164,14 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool Enabled) const override; bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; + + using TargetInfo::getManglingSuffixFromAttr; + std::string getManglingSuffixFromAttr(TargetClonesAttr *Attr, + unsigned VersionIndex) const override; + std::string getManglingSuffixFromStr(StringRef Str) const override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } bool checkArithmeticFenceSupported() const override { return true; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 64836f8d174710..cc6e9f206f067f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1724,59 +1724,6 @@ static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM, Out << ".resolver"; } -static void AppendTargetVersionMangling(const CodeGenModule &CGM, - const TargetVersionAttr *Attr, - raw_ostream &Out) { - if (Attr->isDefaultVersion()) { - Out << ".default"; - return; - } - Out << "._"; - const TargetInfo &TI = CGM.getTarget(); - llvm::SmallVector<StringRef, 8> Feats; - Attr->getFeatures(Feats); - llvm::stable_sort(Feats, [&TI](const StringRef FeatL, const StringRef FeatR) { - return TI.multiVersionSortPriority(FeatL) < - TI.multiVersionSortPriority(FeatR); - }); - for (const auto &Feat : Feats) { - Out << 'M'; - Out << Feat; - } -} - -static void AppendTargetMangling(const CodeGenModule &CGM, - const TargetAttr *Attr, raw_ostream &Out) { - if (Attr->isDefaultVersion()) - return; - - Out << '.'; - const TargetInfo &Target = CGM.getTarget(); - ParsedTargetAttr Info = Target.parseTargetAttr(Attr->getFeaturesStr()); - llvm::sort(Info.Features, [&Target](StringRef LHS, StringRef RHS) { - // Multiversioning doesn't allow "no-${feature}", so we can - // only have "+" prefixes here. - assert(LHS.starts_with("+") && RHS.starts_with("+") && - "Features should always have a prefix."); - return Target.multiVersionSortPriority(LHS.substr(1)) > - Target.multiVersionSortPriority(RHS.substr(1)); - }); - - bool IsFirst = true; - - if (!Info.CPU.empty()) { - IsFirst = false; - Out << "arch_" << Info.CPU; - } - - for (StringRef Feat : Info.Features) { - if (!IsFirst) - Out << '_'; - IsFirst = false; - Out << Feat.substr(1); - } -} - // Returns true if GD is a function decl with internal linkage and // needs a unique suffix after the mangled name. static bool isUniqueInternalLinkageDecl(GlobalDecl GD, @@ -1786,41 +1733,6 @@ static bool isUniqueInternalLinkageDecl(GlobalDecl GD, (CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage); } -static void AppendTargetClonesMangling(const CodeGenModule &CGM, - const TargetClonesAttr *Attr, - unsigned VersionIndex, - raw_ostream &Out) { - const TargetInfo &TI = CGM.getTarget(); - if (TI.getTriple().isAArch64()) { - StringRef FeatureStr = Attr->getFeatureStr(VersionIndex); - if (FeatureStr == "default") { - Out << ".default"; - return; - } - Out << "._"; - SmallVector<StringRef, 8> Features; - FeatureStr.split(Features, "+"); - llvm::stable_sort(Features, - [&TI](const StringRef FeatL, const StringRef FeatR) { - return TI.multiVersionSortPriority(FeatL) < - TI.multiVersionSortPriority(FeatR); - }); - for (auto &Feat : Features) { - Out << 'M'; - Out << Feat; - } - } else { - Out << '.'; - StringRef FeatureStr = Attr->getFeatureStr(VersionIndex); - if (FeatureStr.starts_with("arch=")) - Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1); - else - Out << FeatureStr; - - Out << '.' << Attr->getMangledIndex(VersionIndex); - } -} - static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, const NamedDecl *ND, bool OmitMultiVersionMangling = false) { @@ -1874,16 +1786,22 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, FD->getAttr<CPUSpecificAttr>(), GD.getMultiVersionIndex(), Out); break; - case MultiVersionKind::Target: - AppendTargetMangling(CGM, FD->getAttr<TargetAttr>(), Out); + case MultiVersionKind::Target: { + auto *Attr = FD->getAttr<TargetAttr>(); + Out << CGM.getTarget().getManglingSuffixFromAttr(Attr); break; - case MultiVersionKind::TargetVersion: - AppendTargetVersionMangling(CGM, FD->getAttr<TargetVersionAttr>(), Out); + } + case MultiVersionKind::TargetVersion: { + auto *Attr = FD->getAttr<TargetVersionAttr>(); + Out << CGM.getTarget().getManglingSuffixFromAttr(Attr); break; - case MultiVersionKind::TargetClones: - AppendTargetClonesMangling(CGM, FD->getAttr<TargetClonesAttr>(), - GD.getMultiVersionIndex(), Out); + } + case MultiVersionKind::TargetClones: { + auto *Attr = FD->getAttr<TargetClonesAttr>(); + unsigned VersionIndex = GD.getMultiVersionIndex(); + Out << CGM.getTarget().getManglingSuffixFromAttr(Attr, VersionIndex); break; + } case MultiVersionKind::None: llvm_unreachable("None multiversion type isn't valid here"); } `````````` </details> https://github.com/llvm/llvm-project/pull/81893 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits