[clang] [clang] Refactor target attribute mangling. (PR #81893)
Alexandros Lamprineas via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 26 02:29:13 PST 2024
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.lamprineas at 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) {
More information about the cfe-commits
mailing list