Skip to content

Commit 20734a1

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 20734a1

File tree

4 files changed

+109
-95
lines changed

4 files changed

+109
-95
lines changed

clang/lib/CodeGen/ABIInfo.cpp

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

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

clang/lib/CodeGen/ABIInfo.h

Lines changed: 8 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,13 @@ class ABIInfo {
111112

112113
CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty,
113114
bool Realign = false) const;
115+
116+
virtual std::string getManglingSuffixFromAttr(TargetAttr *Attr) const;
117+
virtual std::string getManglingSuffixFromAttr(TargetVersionAttr *Attr) const;
118+
virtual std::string getManglingSuffixFromAttr(TargetClonesAttr *Attr,
119+
unsigned VersionIndex) const;
120+
121+
virtual std::string getManglingSuffixFromStr(StringRef AttrStr) const;
114122
};
115123

116124
/// 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+
Out << Info.getManglingSuffixFromAttr(Attr);
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+
Out << Info.getManglingSuffixFromAttr(Attr);
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 VersionIndex = GD.getMultiVersionIndex();
1806+
const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo();
1807+
Out << Info.getManglingSuffixFromAttr(Attr, VersionIndex);
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: 34 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,11 @@ class AArch64ABIInfo : public ABIInfo {
7576
bool allowBFloatArgsAndRet() const override {
7677
return getTarget().hasBFloat16Type();
7778
}
79+
80+
using ABIInfo::getManglingSuffixFromAttr;
81+
std::string getManglingSuffixFromAttr(TargetClonesAttr *Attr,
82+
unsigned VersionIndex) const override;
83+
std::string getManglingSuffixFromStr(StringRef Str) const override;
7884
};
7985

8086
class AArch64SwiftABIInfo : public SwiftABIInfo {
@@ -857,6 +863,34 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABI(
857863
<< Callee->getDeclName();
858864
}
859865

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

0 commit comments

Comments
 (0)