Skip to content

Commit 2b16239

Browse files
committed
[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 llvm#80540 demonstrates a motivating case.
1 parent 8cfb716 commit 2b16239

File tree

4 files changed

+115
-95
lines changed

4 files changed

+115
-95
lines changed

clang/lib/CodeGen/ABIInfo.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,58 @@ ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty,
184184
/*ByVal*/ false, Realign);
185185
}
186186

187+
void ABIInfo::appendAttributeMangling(TargetAttr *Attr,
188+
raw_ostream &Out) const {
189+
if (Attr->isDefaultVersion())
190+
return;
191+
appendAttributeMangling(Attr->getFeaturesStr(), Out);
192+
}
193+
194+
void ABIInfo::appendAttributeMangling(TargetVersionAttr *Attr,
195+
raw_ostream &Out) const {
196+
appendAttributeMangling(Attr->getNamesStr(), Out);
197+
}
198+
199+
void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
200+
raw_ostream &Out) const {
201+
appendAttributeMangling(Attr->getFeatureStr(Index), Out);
202+
Out << '.' << Attr->getMangledIndex(Index);
203+
}
204+
205+
void ABIInfo::appendAttributeMangling(StringRef AttrStr,
206+
raw_ostream &Out) const {
207+
if (AttrStr == "default") {
208+
Out << ".default";
209+
return;
210+
}
211+
212+
Out << '.';
213+
const TargetInfo &TI = CGT.getTarget();
214+
ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);
215+
216+
llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {
217+
// Multiversioning doesn't allow "no-${feature}", so we can
218+
// only have "+" prefixes here.
219+
assert(LHS.starts_with("+") && RHS.starts_with("+") &&
220+
"Features should always have a prefix.");
221+
return TI.multiVersionSortPriority(LHS.substr(1)) >
222+
TI.multiVersionSortPriority(RHS.substr(1));
223+
});
224+
225+
bool IsFirst = true;
226+
if (!Info.CPU.empty()) {
227+
IsFirst = false;
228+
Out << "arch_" << Info.CPU;
229+
}
230+
231+
for (StringRef Feat : Info.Features) {
232+
if (!IsFirst)
233+
Out << '_';
234+
IsFirst = false;
235+
Out << Feat.substr(1);
236+
}
237+
}
238+
187239
// Pin the vtable to this file.
188240
SwiftABIInfo::~SwiftABIInfo() = default;
189241

clang/lib/CodeGen/ABIInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
1010
#define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
1111

12+
#include "clang/AST/Attr.h"
1213
#include "clang/AST/CharUnits.h"
1314
#include "clang/AST/Type.h"
1415
#include "llvm/IR/CallingConv.h"
@@ -111,6 +112,15 @@ class ABIInfo {
111112

112113
CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty,
113114
bool Realign = false) const;
115+
116+
virtual void appendAttributeMangling(TargetAttr *Attr,
117+
raw_ostream &Out) const;
118+
virtual void appendAttributeMangling(TargetVersionAttr *Attr,
119+
raw_ostream &Out) const;
120+
virtual void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
121+
raw_ostream &Out) const;
122+
virtual void appendAttributeMangling(StringRef AttrStr,
123+
raw_ostream &Out) const;
114124
};
115125

116126
/// Target specific hooks for defining how a type should be passed or returned

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 16 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,59 +1726,6 @@ static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM,
17261726
Out << ".resolver";
17271727
}
17281728

1729-
static void AppendTargetVersionMangling(const CodeGenModule &CGM,
1730-
const TargetVersionAttr *Attr,
1731-
raw_ostream &Out) {
1732-
if (Attr->isDefaultVersion()) {
1733-
Out << ".default";
1734-
return;
1735-
}
1736-
Out << "._";
1737-
const TargetInfo &TI = CGM.getTarget();
1738-
llvm::SmallVector<StringRef, 8> Feats;
1739-
Attr->getFeatures(Feats);
1740-
llvm::stable_sort(Feats, [&TI](const StringRef FeatL, const StringRef FeatR) {
1741-
return TI.multiVersionSortPriority(FeatL) <
1742-
TI.multiVersionSortPriority(FeatR);
1743-
});
1744-
for (const auto &Feat : Feats) {
1745-
Out << 'M';
1746-
Out << Feat;
1747-
}
1748-
}
1749-
1750-
static void AppendTargetMangling(const CodeGenModule &CGM,
1751-
const TargetAttr *Attr, raw_ostream &Out) {
1752-
if (Attr->isDefaultVersion())
1753-
return;
1754-
1755-
Out << '.';
1756-
const TargetInfo &Target = CGM.getTarget();
1757-
ParsedTargetAttr Info = Target.parseTargetAttr(Attr->getFeaturesStr());
1758-
llvm::sort(Info.Features, [&Target](StringRef LHS, StringRef RHS) {
1759-
// Multiversioning doesn't allow "no-${feature}", so we can
1760-
// only have "+" prefixes here.
1761-
assert(LHS.starts_with("+") && RHS.starts_with("+") &&
1762-
"Features should always have a prefix.");
1763-
return Target.multiVersionSortPriority(LHS.substr(1)) >
1764-
Target.multiVersionSortPriority(RHS.substr(1));
1765-
});
1766-
1767-
bool IsFirst = true;
1768-
1769-
if (!Info.CPU.empty()) {
1770-
IsFirst = false;
1771-
Out << "arch_" << Info.CPU;
1772-
}
1773-
1774-
for (StringRef Feat : Info.Features) {
1775-
if (!IsFirst)
1776-
Out << '_';
1777-
IsFirst = false;
1778-
Out << Feat.substr(1);
1779-
}
1780-
}
1781-
17821729
// Returns true if GD is a function decl with internal linkage and
17831730
// needs a unique suffix after the mangled name.
17841731
static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
@@ -1788,41 +1735,6 @@ static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
17881735
(CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage);
17891736
}
17901737

1791-
static void AppendTargetClonesMangling(const CodeGenModule &CGM,
1792-
const TargetClonesAttr *Attr,
1793-
unsigned VersionIndex,
1794-
raw_ostream &Out) {
1795-
const TargetInfo &TI = CGM.getTarget();
1796-
if (TI.getTriple().isAArch64()) {
1797-
StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
1798-
if (FeatureStr == "default") {
1799-
Out << ".default";
1800-
return;
1801-
}
1802-
Out << "._";
1803-
SmallVector<StringRef, 8> Features;
1804-
FeatureStr.split(Features, "+");
1805-
llvm::stable_sort(Features,
1806-
[&TI](const StringRef FeatL, const StringRef FeatR) {
1807-
return TI.multiVersionSortPriority(FeatL) <
1808-
TI.multiVersionSortPriority(FeatR);
1809-
});
1810-
for (auto &Feat : Features) {
1811-
Out << 'M';
1812-
Out << Feat;
1813-
}
1814-
} else {
1815-
Out << '.';
1816-
StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
1817-
if (FeatureStr.starts_with("arch="))
1818-
Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1);
1819-
else
1820-
Out << FeatureStr;
1821-
1822-
Out << '.' << Attr->getMangledIndex(VersionIndex);
1823-
}
1824-
}
1825-
18261738
static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
18271739
const NamedDecl *ND,
18281740
bool OmitMultiVersionMangling = false) {
@@ -1876,16 +1788,25 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
18761788
FD->getAttr<CPUSpecificAttr>(),
18771789
GD.getMultiVersionIndex(), Out);
18781790
break;
1879-
case MultiVersionKind::Target:
1880-
AppendTargetMangling(CGM, FD->getAttr<TargetAttr>(), Out);
1791+
case MultiVersionKind::Target: {
1792+
auto *Attr = FD->getAttr<TargetAttr>();
1793+
const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo();
1794+
Info.appendAttributeMangling(Attr, Out);
18811795
break;
1882-
case MultiVersionKind::TargetVersion:
1883-
AppendTargetVersionMangling(CGM, FD->getAttr<TargetVersionAttr>(), Out);
1796+
}
1797+
case MultiVersionKind::TargetVersion: {
1798+
auto *Attr = FD->getAttr<TargetVersionAttr>();
1799+
const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo();
1800+
Info.appendAttributeMangling(Attr, Out);
18841801
break;
1885-
case MultiVersionKind::TargetClones:
1886-
AppendTargetClonesMangling(CGM, FD->getAttr<TargetClonesAttr>(),
1887-
GD.getMultiVersionIndex(), Out);
1802+
}
1803+
case MultiVersionKind::TargetClones: {
1804+
auto *Attr = FD->getAttr<TargetClonesAttr>();
1805+
unsigned Index = GD.getMultiVersionIndex();
1806+
const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo();
1807+
Info.appendAttributeMangling(Attr, Index, Out);
18881808
break;
1809+
}
18891810
case MultiVersionKind::None:
18901811
llvm_unreachable("None multiversion type isn't valid here");
18911812
}

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "ABIInfoImpl.h"
1010
#include "TargetInfo.h"
1111
#include "clang/Basic/DiagnosticFrontend.h"
12+
#include "llvm/TargetParser/AArch64TargetParser.h"
1213

1314
using namespace clang;
1415
using namespace clang::CodeGen;
@@ -75,6 +76,12 @@ class AArch64ABIInfo : public ABIInfo {
7576
bool allowBFloatArgsAndRet() const override {
7677
return getTarget().hasBFloat16Type();
7778
}
79+
80+
using ABIInfo::appendAttributeMangling;
81+
void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
82+
raw_ostream &Out) const override;
83+
void appendAttributeMangling(StringRef AttrStr,
84+
raw_ostream &Out) const override;
7885
};
7986

8087
class AArch64SwiftABIInfo : public SwiftABIInfo {
@@ -857,6 +864,36 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABI(
857864
<< Callee->getDeclName();
858865
}
859866

867+
void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
868+
unsigned Index,
869+
raw_ostream &Out) const {
870+
appendAttributeMangling(Attr->getFeatureStr(Index), Out);
871+
}
872+
873+
void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr,
874+
raw_ostream &Out) const {
875+
if (AttrStr == "default") {
876+
Out << ".default";
877+
return;
878+
}
879+
880+
Out << "._";
881+
SmallVector<StringRef, 8> Features;
882+
AttrStr.split(Features, "+");
883+
for (auto &Feat : Features)
884+
Feat = Feat.trim();
885+
886+
// TODO Lexicographical order won't break the ABI if priorities change.
887+
const TargetInfo &TI = CGT.getTarget();
888+
llvm::sort(Features, [&TI](const StringRef LHS, const StringRef RHS) {
889+
return TI.multiVersionSortPriority(LHS) < TI.multiVersionSortPriority(RHS);
890+
});
891+
892+
for (auto &Feat : Features)
893+
if (auto Ext = llvm::AArch64::parseArchExtension(Feat))
894+
Out << 'M' << Ext->Name;
895+
}
896+
860897
std::unique_ptr<TargetCodeGenInfo>
861898
CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM,
862899
AArch64ABIKind Kind) {

0 commit comments

Comments
 (0)