diff options
author | Alexandros Lamprineas <alexandros.lamprineas@arm.com> | 2024-11-28 09:22:05 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-28 09:22:05 +0000 |
commit | 88c2af80fac423fc338027c007e1499333f05ddb (patch) | |
tree | b4ead2c118ffc1c84ae127499c361a4df5148705 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 2c242b98c608021e6768f0369498f5b8b5144d34 (diff) | |
download | llvm-88c2af80fac423fc338027c007e1499333f05ddb.zip llvm-88c2af80fac423fc338027c007e1499333f05ddb.tar.gz llvm-88c2af80fac423fc338027c007e1499333f05ddb.tar.bz2 |
[NFC][clang][FMV][TargetInfo] Refactor API for FMV feature priority. (#116257)
Currently we have code with target hooks in CodeGenModule shared between
X86 and AArch64 for sorting MultiVersionResolverOptions. Those are used
when generating IFunc resolvers for FMV. The RISCV target has different
criteria for sorting, therefore it repeats sorting after calling
CodeGenFunction::EmitMultiVersionResolver.
I am moving the FMV priority logic in TargetInfo, so that it can be
implemented by the TargetParser which then makes it possible to query it
from llvm. Here is an example why this is handy:
https://github.com/llvm/llvm-project/pull/87939
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 86 |
1 files changed, 32 insertions, 54 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 716c434..7189a46 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4223,23 +4223,12 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, llvm::Function *NewFn); -static unsigned -TargetMVPriority(const TargetInfo &TI, - const CodeGenFunction::MultiVersionResolverOption &RO) { - unsigned Priority = 0; - 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; +static unsigned getFMVPriority(const TargetInfo &TI, + const CodeGenFunction::FMVResolverOption &RO) { + llvm::SmallVector<StringRef, 8> Features{RO.Features}; + if (RO.Architecture) + Features.push_back(*RO.Architecture); + return TI.getFMVPriority(Features); } // Multiversion functions should be at most 'WeakODRLinkage' so that a different @@ -4285,7 +4274,7 @@ void CodeGenModule::emitMultiVersionFunctions() { // target_version("default")) or target_clones() is present and defined // in this TU. For other architectures it is always emitted. bool ShouldEmitResolver = !getTarget().getTriple().isAArch64(); - SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; + SmallVector<CodeGenFunction::FMVResolverOption, 10> Options; getContext().forEachMultiversionedFunctionVersion( FD, [&](const FunctionDecl *CurFD) { @@ -4293,20 +4282,17 @@ void CodeGenModule::emitMultiVersionFunctions() { bool IsDefined = CurFD->doesThisDeclarationHaveABody(); if (const auto *TA = CurFD->getAttr<TargetAttr>()) { - TA->getAddedFeatures(Feats); + assert(getTarget().getTriple().isX86() && "Unsupported target"); + TA->getX86AddedFeatures(Feats); llvm::Function *Func = createFunction(CurFD); - Options.emplace_back(Func, TA->getArchitecture(), Feats); + Options.emplace_back(Func, Feats, TA->getX86Architecture()); } else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) { if (TVA->isDefaultVersion() && IsDefined) ShouldEmitResolver = true; llvm::Function *Func = createFunction(CurFD); - if (getTarget().getTriple().isRISCV()) { - Feats.push_back(TVA->getName()); - } else { - assert(getTarget().getTriple().isAArch64()); - TVA->getFeatures(Feats); - } - Options.emplace_back(Func, /*Architecture*/ "", Feats); + char Delim = getTarget().getTriple().isAArch64() ? '+' : ','; + TVA->getFeatures(Feats, Delim); + Options.emplace_back(Func, Feats); } else if (const auto *TC = CurFD->getAttr<TargetClonesAttr>()) { if (IsDefined) ShouldEmitResolver = true; @@ -4315,21 +4301,15 @@ void CodeGenModule::emitMultiVersionFunctions() { continue; llvm::Function *Func = createFunction(CurFD, I); - StringRef Architecture; Feats.clear(); - if (getTarget().getTriple().isAArch64()) - TC->getFeatures(Feats, I); - else if (getTarget().getTriple().isRISCV()) { - StringRef Version = TC->getFeatureStr(I); - Feats.push_back(Version); + if (getTarget().getTriple().isX86()) { + TC->getX86Feature(Feats, I); + Options.emplace_back(Func, Feats, TC->getX86Architecture(I)); } else { - StringRef Version = TC->getFeatureStr(I); - if (Version.starts_with("arch=")) - Architecture = Version.drop_front(sizeof("arch=") - 1); - else if (Version != "default") - Feats.push_back(Version); + char Delim = getTarget().getTriple().isAArch64() ? '+' : ','; + TC->getFeatures(Feats, I, Delim); + Options.emplace_back(Func, Feats); } - Options.emplace_back(Func, Architecture, Feats); } } else llvm_unreachable("unexpected MultiVersionKind"); @@ -4368,9 +4348,9 @@ void CodeGenModule::emitMultiVersionFunctions() { const TargetInfo &TI = getTarget(); llvm::stable_sort( - Options, [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS, - const CodeGenFunction::MultiVersionResolverOption &RHS) { - return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS); + Options, [&TI](const CodeGenFunction::FMVResolverOption &LHS, + const CodeGenFunction::FMVResolverOption &RHS) { + return getFMVPriority(TI, LHS) > getFMVPriority(TI, RHS); }); CodeGenFunction CGF(*this); CGF.EmitMultiVersionResolver(ResolverFunc, Options); @@ -4429,7 +4409,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { ResolverFunc->setComdat( getModule().getOrInsertComdat(ResolverFunc->getName())); - SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; + SmallVector<CodeGenFunction::FMVResolverOption, 10> Options; const TargetInfo &Target = getTarget(); unsigned Index = 0; for (const IdentifierInfo *II : DD->cpus()) { @@ -4463,25 +4443,23 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { llvm::erase_if(Features, [&Target](StringRef Feat) { return !Target.validateCpuSupports(Feat); }); - Options.emplace_back(cast<llvm::Function>(Func), StringRef{}, Features); + Options.emplace_back(cast<llvm::Function>(Func), Features); ++Index; } - llvm::stable_sort( - Options, [](const CodeGenFunction::MultiVersionResolverOption &LHS, - const CodeGenFunction::MultiVersionResolverOption &RHS) { - return llvm::X86::getCpuSupportsMask(LHS.Conditions.Features) > - llvm::X86::getCpuSupportsMask(RHS.Conditions.Features); - }); + llvm::stable_sort(Options, [](const CodeGenFunction::FMVResolverOption &LHS, + const CodeGenFunction::FMVResolverOption &RHS) { + return llvm::X86::getCpuSupportsMask(LHS.Features) > + llvm::X86::getCpuSupportsMask(RHS.Features); + }); // If the list contains multiple 'default' versions, such as when it contains // 'pentium' and 'generic', don't emit the call to the generic one (since we // always run on at least a 'pentium'). We do this by deleting the 'least // advanced' (read, lowest mangling letter). - while (Options.size() > 1 && - llvm::all_of(llvm::X86::getCpuSupportsMask( - (Options.end() - 2)->Conditions.Features), - [](auto X) { return X == 0; })) { + while (Options.size() > 1 && llvm::all_of(llvm::X86::getCpuSupportsMask( + (Options.end() - 2)->Features), + [](auto X) { return X == 0; })) { StringRef LHSName = (Options.end() - 2)->Function->getName(); StringRef RHSName = (Options.end() - 1)->Function->getName(); if (LHSName.compare(RHSName) < 0) |