Skip to content

Commit 1c476b1

Browse files
labrineajroelofs
authored andcommitted
[clang] Refactor target attribute mangling. (llvm#81893)
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. Cherry-pick: b42b7c8
1 parent 4ea8fb1 commit 1c476b1

File tree

4 files changed

+119
-95
lines changed

4 files changed

+119
-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
@@ -1604,59 +1604,6 @@ static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM,
16041604
Out << ".resolver";
16051605
}
16061606

1607-
static void AppendTargetVersionMangling(const CodeGenModule &CGM,
1608-
const TargetVersionAttr *Attr,
1609-
raw_ostream &Out) {
1610-
if (Attr->isDefaultVersion()) {
1611-
Out << ".default";
1612-
return;
1613-
}
1614-
Out << "._";
1615-
const TargetInfo &TI = CGM.getTarget();
1616-
llvm::SmallVector<StringRef, 8> Feats;
1617-
Attr->getFeatures(Feats);
1618-
llvm::stable_sort(Feats, [&TI](const StringRef FeatL, const StringRef FeatR) {
1619-
return TI.multiVersionSortPriority(FeatL) <
1620-
TI.multiVersionSortPriority(FeatR);
1621-
});
1622-
for (const auto &Feat : Feats) {
1623-
Out << 'M';
1624-
Out << Feat;
1625-
}
1626-
}
1627-
1628-
static void AppendTargetMangling(const CodeGenModule &CGM,
1629-
const TargetAttr *Attr, raw_ostream &Out) {
1630-
if (Attr->isDefaultVersion())
1631-
return;
1632-
1633-
Out << '.';
1634-
const TargetInfo &Target = CGM.getTarget();
1635-
ParsedTargetAttr Info = Target.parseTargetAttr(Attr->getFeaturesStr());
1636-
llvm::sort(Info.Features, [&Target](StringRef LHS, StringRef RHS) {
1637-
// Multiversioning doesn't allow "no-${feature}", so we can
1638-
// only have "+" prefixes here.
1639-
assert(LHS.startswith("+") && RHS.startswith("+") &&
1640-
"Features should always have a prefix.");
1641-
return Target.multiVersionSortPriority(LHS.substr(1)) >
1642-
Target.multiVersionSortPriority(RHS.substr(1));
1643-
});
1644-
1645-
bool IsFirst = true;
1646-
1647-
if (!Info.CPU.empty()) {
1648-
IsFirst = false;
1649-
Out << "arch_" << Info.CPU;
1650-
}
1651-
1652-
for (StringRef Feat : Info.Features) {
1653-
if (!IsFirst)
1654-
Out << '_';
1655-
IsFirst = false;
1656-
Out << Feat.substr(1);
1657-
}
1658-
}
1659-
16601607
// Returns true if GD is a function decl with internal linkage and
16611608
// needs a unique suffix after the mangled name.
16621609
static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
@@ -1666,41 +1613,6 @@ static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
16661613
(CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage);
16671614
}
16681615

1669-
static void AppendTargetClonesMangling(const CodeGenModule &CGM,
1670-
const TargetClonesAttr *Attr,
1671-
unsigned VersionIndex,
1672-
raw_ostream &Out) {
1673-
const TargetInfo &TI = CGM.getTarget();
1674-
if (TI.getTriple().isAArch64()) {
1675-
StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
1676-
if (FeatureStr == "default") {
1677-
Out << ".default";
1678-
return;
1679-
}
1680-
Out << "._";
1681-
SmallVector<StringRef, 8> Features;
1682-
FeatureStr.split(Features, "+");
1683-
llvm::stable_sort(Features,
1684-
[&TI](const StringRef FeatL, const StringRef FeatR) {
1685-
return TI.multiVersionSortPriority(FeatL) <
1686-
TI.multiVersionSortPriority(FeatR);
1687-
});
1688-
for (auto &Feat : Features) {
1689-
Out << 'M';
1690-
Out << Feat;
1691-
}
1692-
} else {
1693-
Out << '.';
1694-
StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
1695-
if (FeatureStr.startswith("arch="))
1696-
Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1);
1697-
else
1698-
Out << FeatureStr;
1699-
1700-
Out << '.' << Attr->getMangledIndex(VersionIndex);
1701-
}
1702-
}
1703-
17041616
static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
17051617
const NamedDecl *ND,
17061618
bool OmitMultiVersionMangling = false) {
@@ -1751,16 +1663,25 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
17511663
FD->getAttr<CPUSpecificAttr>(),
17521664
GD.getMultiVersionIndex(), Out);
17531665
break;
1754-
case MultiVersionKind::Target:
1755-
AppendTargetMangling(CGM, FD->getAttr<TargetAttr>(), Out);
1666+
case MultiVersionKind::Target: {
1667+
auto *Attr = FD->getAttr<TargetAttr>();
1668+
const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo();
1669+
Info.appendAttributeMangling(Attr, Out);
17561670
break;
1757-
case MultiVersionKind::TargetVersion:
1758-
AppendTargetVersionMangling(CGM, FD->getAttr<TargetVersionAttr>(), Out);
1671+
}
1672+
case MultiVersionKind::TargetVersion: {
1673+
auto *Attr = FD->getAttr<TargetVersionAttr>();
1674+
const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo();
1675+
Info.appendAttributeMangling(Attr, Out);
17591676
break;
1760-
case MultiVersionKind::TargetClones:
1761-
AppendTargetClonesMangling(CGM, FD->getAttr<TargetClonesAttr>(),
1762-
GD.getMultiVersionIndex(), Out);
1677+
}
1678+
case MultiVersionKind::TargetClones: {
1679+
auto *Attr = FD->getAttr<TargetClonesAttr>();
1680+
unsigned Index = GD.getMultiVersionIndex();
1681+
const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo();
1682+
Info.appendAttributeMangling(Attr, Index, Out);
17631683
break;
1684+
}
17641685
case MultiVersionKind::None:
17651686
llvm_unreachable("None multiversion type isn't valid here");
17661687
}

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include "ABIInfoImpl.h"
1010
#include "TargetInfo.h"
11+
#include "clang/Basic/DiagnosticFrontend.h"
12+
#include "llvm/TargetParser/AArch64TargetParser.h"
1113

1214
using namespace clang;
1315
using namespace clang::CodeGen;
@@ -74,6 +76,12 @@ class AArch64ABIInfo : public ABIInfo {
7476
bool allowBFloatArgsAndRet() const override {
7577
return getTarget().hasBFloat16Type();
7678
}
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;
7785
};
7886

7987
class AArch64SwiftABIInfo : public SwiftABIInfo {
@@ -811,6 +819,39 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
811819
/*allowHigherAlign*/ false);
812820
}
813821

822+
void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
823+
unsigned Index,
824+
raw_ostream &Out) const {
825+
appendAttributeMangling(Attr->getFeatureStr(Index), Out);
826+
}
827+
828+
void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr,
829+
raw_ostream &Out) const {
830+
if (AttrStr == "default") {
831+
Out << ".default";
832+
return;
833+
}
834+
835+
Out << "._";
836+
SmallVector<StringRef, 8> Features;
837+
AttrStr.split(Features, "+");
838+
for (auto &Feat : Features)
839+
Feat = Feat.trim();
840+
841+
// FIXME: It was brought up in #79316 that sorting the features which are
842+
// used for mangling based on their multiversion priority is not a good
843+
// practice. Changing the feature priorities will break the ABI. Perhaps
844+
// it would be preferable to perform a lexicographical sort instead.
845+
const TargetInfo &TI = CGT.getTarget();
846+
llvm::sort(Features, [&TI](const StringRef LHS, const StringRef RHS) {
847+
return TI.multiVersionSortPriority(LHS) < TI.multiVersionSortPriority(RHS);
848+
});
849+
850+
for (auto &Feat : Features)
851+
if (auto Ext = llvm::AArch64::parseArchExtension(Feat))
852+
Out << 'M' << Ext->Name;
853+
}
854+
814855
std::unique_ptr<TargetCodeGenInfo>
815856
CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM,
816857
AArch64ABIKind Kind) {

0 commit comments

Comments
 (0)