https://github.com/labrinea updated https://github.com/llvm/llvm-project/pull/81893
>From 20734a17b90e4b425aa86f152777301cda810e63 Mon Sep 17 00:00:00 2001 From: Alexandros Lamprineas <alexandros.lamprin...@arm.com> Date: Thu, 15 Feb 2024 15:53:51 +0000 Subject: [PATCH] [clang] Refactor target attribute mangling. 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 ABIInfo and provided overrides for AArch64. This way we can resolve feature aliases without affecting the name mangling The PR #80540 demonstrates a motivating case. --- clang/lib/CodeGen/ABIInfo.cpp | 51 ++++++++++++ clang/lib/CodeGen/ABIInfo.h | 8 ++ clang/lib/CodeGen/CodeGenModule.cpp | 111 ++++---------------------- clang/lib/CodeGen/Targets/AArch64.cpp | 34 ++++++++ 4 files changed, 109 insertions(+), 95 deletions(-) diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp index 1b56cf7c596d06..7eb0b2e31159b9 100644 --- a/clang/lib/CodeGen/ABIInfo.cpp +++ b/clang/lib/CodeGen/ABIInfo.cpp @@ -184,6 +184,57 @@ ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty, /*ByVal*/ false, Realign); } +std::string ABIInfo::getManglingSuffixFromAttr(TargetAttr *Attr) const { + if (Attr->isDefaultVersion()) + return {}; + + return getManglingSuffixFromStr(Attr->getFeaturesStr()); +} + +std::string ABIInfo::getManglingSuffixFromAttr(TargetVersionAttr *Attr) const { + return getManglingSuffixFromStr(Attr->getNamesStr()); +} + +std::string ABIInfo::getManglingSuffixFromAttr(TargetClonesAttr *Attr, + unsigned Index) const { + std::string Suffix = getManglingSuffixFromStr(Attr->getFeatureStr(Index)); + Suffix.append("." + Twine(Attr->getMangledIndex(Index)).str()); + return Suffix; +} + +std::string ABIInfo::getManglingSuffixFromStr(StringRef AttrStr) const { + if (AttrStr == "default") + return ".default"; + + std::string ManglingSuffix("."); + const TargetInfo &TI = CGT.getTarget(); + ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr); + + llvm::sort(Info.Features, [&TI](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 TI.multiVersionSortPriority(LHS.substr(1)) > + TI.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; +} + // Pin the vtable to this file. SwiftABIInfo::~SwiftABIInfo() = default; diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h index b9a5ef6e436693..56b4a89d2507f1 100644 --- a/clang/lib/CodeGen/ABIInfo.h +++ b/clang/lib/CodeGen/ABIInfo.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H +#include "clang/AST/Attr.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Type.h" #include "llvm/IR/CallingConv.h" @@ -111,6 +112,13 @@ class ABIInfo { CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const; + + 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; }; /// Target specific hooks for defining how a type should be passed or returned diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 95e457bef28ed3..e9bbc2706a693c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1726,59 +1726,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, @@ -1788,41 +1735,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) { @@ -1876,16 +1788,25 @@ 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>(); + const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo(); + Out << Info.getManglingSuffixFromAttr(Attr); break; - case MultiVersionKind::TargetVersion: - AppendTargetVersionMangling(CGM, FD->getAttr<TargetVersionAttr>(), Out); + } + case MultiVersionKind::TargetVersion: { + auto *Attr = FD->getAttr<TargetVersionAttr>(); + const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo(); + Out << Info.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(); + const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo(); + Out << Info.getManglingSuffixFromAttr(Attr, VersionIndex); break; + } case MultiVersionKind::None: llvm_unreachable("None multiversion type isn't valid here"); } diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 94f8e7be2ee6eb..36ce6e7d499714 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -9,6 +9,7 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "llvm/TargetParser/AArch64TargetParser.h" using namespace clang; using namespace clang::CodeGen; @@ -75,6 +76,11 @@ class AArch64ABIInfo : public ABIInfo { bool allowBFloatArgsAndRet() const override { return getTarget().hasBFloat16Type(); } + + using ABIInfo::getManglingSuffixFromAttr; + std::string getManglingSuffixFromAttr(TargetClonesAttr *Attr, + unsigned VersionIndex) const override; + std::string getManglingSuffixFromStr(StringRef Str) const override; }; class AArch64SwiftABIInfo : public SwiftABIInfo { @@ -857,6 +863,34 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABI( << Callee->getDeclName(); } +std::string AArch64ABIInfo::getManglingSuffixFromAttr(TargetClonesAttr *Attr, + unsigned Index) const { + return getManglingSuffixFromStr(Attr->getFeatureStr(Index)); +} + +std::string AArch64ABIInfo::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. + const TargetInfo &TI = CGT.getTarget(); + llvm::sort(Features, [&TI](const StringRef LHS, const StringRef RHS) { + return TI.multiVersionSortPriority(LHS) < TI.multiVersionSortPriority(RHS); + }); + + for (auto &Feat : Features) + if (auto Ext = llvm::AArch64::parseArchExtension(Feat)) + ManglingSuffix.append(Twine("M", Ext->Name).str()); + + return ManglingSuffix; +} + std::unique_ptr<TargetCodeGenInfo> CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits