summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorPavel Iliin <Pavel.Iliin@arm.com>2021-12-15 02:12:37 +0000
committerPavel Iliin <Pavel.Iliin@arm.com>2022-12-20 15:42:25 +0000
commite43924a75145d2f9e722f74b673145c3e62bfd07 (patch)
treeb1e75d388206af5bf7a9c7a19951941a87136eb7 /clang/lib/CodeGen/CodeGenModule.cpp
parentdaa022ca5707d8ddde987d3c8c2aea6bd9954e3f (diff)
[AArch64] FMV support and necessary target features dependencies.
This is Function Multi Versioning (FMV) implementation for AArch64 target in accordance with Beta Arm C Language Extensions specification https://github.com/ARM-software/acle/blob/main/main/acle.md#function-multi-versioning It supports new "target_version" function attribute and extends existing "target_clones" one. Also missing dependencies for target features were added. Differential Revision: https://reviews.llvm.org/D127812
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp93
1 files changed, 73 insertions, 20 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c8783ea8578d..e89ac0778c79 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1337,6 +1337,20 @@ static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM,
Out << ".resolver";
}
+static void AppendTargetVersionMangling(const CodeGenModule &CGM,
+ const TargetVersionAttr *Attr,
+ raw_ostream &Out) {
+ if (Attr->isDefaultVersion())
+ return;
+ Out << "._";
+ llvm::SmallVector<StringRef, 8> Feats;
+ Attr->getFeatures(Feats);
+ for (const auto &Feat : Feats) {
+ Out << 'M';
+ Out << Feat;
+ }
+}
+
static void AppendTargetMangling(const CodeGenModule &CGM,
const TargetAttr *Attr, raw_ostream &Out) {
if (Attr->isDefaultVersion())
@@ -1382,14 +1396,27 @@ static void AppendTargetClonesMangling(const CodeGenModule &CGM,
const TargetClonesAttr *Attr,
unsigned VersionIndex,
raw_ostream &Out) {
- Out << '.';
- StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
- if (FeatureStr.startswith("arch="))
- Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1);
- else
- Out << FeatureStr;
+ if (CGM.getTarget().getTriple().isAArch64()) {
+ StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
+ if (FeatureStr == "default")
+ return;
+ Out << "._";
+ SmallVector<StringRef, 8> Features;
+ FeatureStr.split(Features, "+");
+ for (auto &Feat : Features) {
+ Out << 'M';
+ Out << Feat;
+ }
+ } else {
+ Out << '.';
+ StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
+ if (FeatureStr.startswith("arch="))
+ Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1);
+ else
+ Out << FeatureStr;
- Out << '.' << Attr->getMangledIndex(VersionIndex);
+ Out << '.' << Attr->getMangledIndex(VersionIndex);
+ }
}
static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
@@ -1445,6 +1472,9 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
case MultiVersionKind::Target:
AppendTargetMangling(CGM, FD->getAttr<TargetAttr>(), Out);
break;
+ case MultiVersionKind::TargetVersion:
+ AppendTargetVersionMangling(CGM, FD->getAttr<TargetVersionAttr>(), Out);
+ break;
case MultiVersionKind::TargetClones:
AppendTargetClonesMangling(CGM, FD->getAttr<TargetClonesAttr>(),
GD.getMultiVersionIndex(), Out);
@@ -2166,10 +2196,12 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
const auto *FD = dyn_cast_or_null<FunctionDecl>(GD.getDecl());
FD = FD ? FD->getMostRecentDecl() : FD;
const auto *TD = FD ? FD->getAttr<TargetAttr>() : nullptr;
+ const auto *TV = FD ? FD->getAttr<TargetVersionAttr>() : nullptr;
+ assert((!TD || !TV) && "both target_version and target specified");
const auto *SD = FD ? FD->getAttr<CPUSpecificAttr>() : nullptr;
const auto *TC = FD ? FD->getAttr<TargetClonesAttr>() : nullptr;
bool AddedAttr = false;
- if (TD || SD || TC) {
+ if (TD || TV || SD || TC) {
llvm::StringMap<bool> FeatureMap;
getContext().getFunctionFeatureMap(FeatureMap, GD);
@@ -3623,12 +3655,18 @@ static unsigned
TargetMVPriority(const TargetInfo &TI,
const CodeGenFunction::MultiVersionResolverOption &RO) {
unsigned Priority = 0;
- for (StringRef Feat : RO.Conditions.Features)
+ unsigned NumFeatures = 0;
+ for (StringRef Feat : RO.Conditions.Features) {
Priority = std::max(Priority, TI.multiVersionSortPriority(Feat));
+ NumFeatures++;
+ }
if (!RO.Conditions.Architecture.empty())
Priority = std::max(
Priority, TI.multiVersionSortPriority(RO.Conditions.Architecture));
+
+ Priority += TI.multiVersionFeatureCost() * NumFeatures;
+
return Priority;
}
@@ -3673,13 +3711,19 @@ void CodeGenModule::emitMultiVersionFunctions() {
}
assert(Func && "This should have just been created");
}
-
- const auto *TA = CurFD->getAttr<TargetAttr>();
- llvm::SmallVector<StringRef, 8> Feats;
- TA->getAddedFeatures(Feats);
-
- Options.emplace_back(cast<llvm::Function>(Func),
- TA->getArchitecture(), Feats);
+ if (CurFD->getMultiVersionKind() == MultiVersionKind::Target) {
+ const auto *TA = CurFD->getAttr<TargetAttr>();
+ llvm::SmallVector<StringRef, 8> Feats;
+ TA->getAddedFeatures(Feats);
+ Options.emplace_back(cast<llvm::Function>(Func),
+ TA->getArchitecture(), Feats);
+ } else {
+ const auto *TVA = CurFD->getAttr<TargetVersionAttr>();
+ llvm::SmallVector<StringRef, 8> Feats;
+ TVA->getFeatures(Feats);
+ Options.emplace_back(cast<llvm::Function>(Func),
+ /*Architecture*/ "", Feats);
+ }
});
} else if (FD->isTargetClonesMultiVersion()) {
const auto *TC = FD->getAttr<TargetClonesAttr>();
@@ -3709,10 +3753,19 @@ void CodeGenModule::emitMultiVersionFunctions() {
StringRef Architecture;
llvm::SmallVector<StringRef, 1> Feature;
- if (Version.startswith("arch="))
- Architecture = Version.drop_front(sizeof("arch=") - 1);
- else if (Version != "default")
- Feature.push_back(Version);
+ if (getTarget().getTriple().isAArch64()) {
+ if (Version != "default") {
+ llvm::SmallVector<StringRef, 8> VerFeats;
+ Version.split(VerFeats, "+");
+ for (auto &CurFeat : VerFeats)
+ Feature.push_back(CurFeat.trim());
+ }
+ } else {
+ if (Version.startswith("arch="))
+ Architecture = Version.drop_front(sizeof("arch=") - 1);
+ else if (Version != "default")
+ Feature.push_back(Version);
+ }
Options.emplace_back(cast<llvm::Function>(Func), Architecture, Feature);
}