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/CodeGenFunction.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/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 109 |
1 files changed, 38 insertions, 71 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index ef6bb4f..f8138e9 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2828,23 +2828,17 @@ void CodeGenFunction::EmitKCFIOperandBundle( Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar())); } -llvm::Value *CodeGenFunction::FormAArch64ResolverCondition( - const MultiVersionResolverOption &RO) { - llvm::SmallVector<StringRef, 8> CondFeatures; - for (const StringRef &Feature : RO.Conditions.Features) - CondFeatures.push_back(Feature); - if (!CondFeatures.empty()) { - return EmitAArch64CpuSupports(CondFeatures); - } - return nullptr; +llvm::Value * +CodeGenFunction::FormAArch64ResolverCondition(const FMVResolverOption &RO) { + return RO.Features.empty() ? nullptr : EmitAArch64CpuSupports(RO.Features); } -llvm::Value *CodeGenFunction::FormX86ResolverCondition( - const MultiVersionResolverOption &RO) { +llvm::Value * +CodeGenFunction::FormX86ResolverCondition(const FMVResolverOption &RO) { llvm::Value *Condition = nullptr; - if (!RO.Conditions.Architecture.empty()) { - StringRef Arch = RO.Conditions.Architecture; + if (RO.Architecture) { + StringRef Arch = *RO.Architecture; // If arch= specifies an x86-64 micro-architecture level, test the feature // with __builtin_cpu_supports, otherwise use __builtin_cpu_is. if (Arch.starts_with("x86-64")) @@ -2853,8 +2847,8 @@ llvm::Value *CodeGenFunction::FormX86ResolverCondition( Condition = EmitX86CpuIs(Arch); } - if (!RO.Conditions.Features.empty()) { - llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features); + if (!RO.Features.empty()) { + llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Features); Condition = Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond; } @@ -2884,7 +2878,7 @@ static void CreateMultiVersionResolverReturn(CodeGenModule &CGM, } void CodeGenFunction::EmitMultiVersionResolver( - llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { + llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) { llvm::Triple::ArchType ArchType = getContext().getTargetInfo().getTriple().getArch(); @@ -2907,26 +2901,8 @@ void CodeGenFunction::EmitMultiVersionResolver( } } -static unsigned getPriorityFromAttrString(StringRef AttrStr) { - SmallVector<StringRef, 8> Attrs; - - AttrStr.split(Attrs, ';'); - - // Default Priority is zero. - unsigned Priority = 0; - for (auto Attr : Attrs) { - if (Attr.consume_front("priority=")) { - unsigned Result; - if (!Attr.getAsInteger(0, Result)) - Priority = Result; - } - } - - return Priority; -} - void CodeGenFunction::EmitRISCVMultiVersionResolver( - llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { + llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) { if (getContext().getTargetInfo().getTriple().getOS() != llvm::Triple::OSType::Linux) { @@ -2942,20 +2918,10 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver( bool HasDefault = false; unsigned DefaultIndex = 0; - SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> CurrOptions( - Options); - - llvm::stable_sort( - CurrOptions, [](const CodeGenFunction::MultiVersionResolverOption &LHS, - const CodeGenFunction::MultiVersionResolverOption &RHS) { - return getPriorityFromAttrString(LHS.Conditions.Features[0]) > - getPriorityFromAttrString(RHS.Conditions.Features[0]); - }); - // Check the each candidate function. - for (unsigned Index = 0; Index < CurrOptions.size(); Index++) { + for (unsigned Index = 0; Index < Options.size(); Index++) { - if (CurrOptions[Index].Conditions.Features[0].starts_with("default")) { + if (Options[Index].Features.empty()) { HasDefault = true; DefaultIndex = Index; continue; @@ -2963,15 +2929,6 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver( Builder.SetInsertPoint(CurBlock); - std::vector<std::string> TargetAttrFeats = - getContext() - .getTargetInfo() - .parseTargetAttr(CurrOptions[Index].Conditions.Features[0]) - .Features; - - if (TargetAttrFeats.empty()) - continue; - // FeaturesCondition: The bitmask of the required extension has been // enabled by the runtime object. // (__riscv_feature_bits.features[i] & REQUIRED_BITMASK) == @@ -2994,20 +2951,32 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver( // Without checking the length first, we may access an incorrect memory // address when using different versions. llvm::SmallVector<StringRef, 8> CurrTargetAttrFeats; + llvm::SmallVector<std::string, 8> TargetAttrFeats; - for (auto &Feat : TargetAttrFeats) { - StringRef CurrFeat = Feat; - if (CurrFeat.starts_with('+')) - CurrTargetAttrFeats.push_back(CurrFeat.substr(1)); + for (StringRef Feat : Options[Index].Features) { + std::vector<std::string> FeatStr = + getContext().getTargetInfo().parseTargetAttr(Feat).Features; + + assert(FeatStr.size() == 1 && "Feature string not delimited"); + + std::string &CurrFeat = FeatStr.front(); + if (CurrFeat[0] == '+') + TargetAttrFeats.push_back(CurrFeat.substr(1)); } + if (TargetAttrFeats.empty()) + continue; + + for (std::string &Feat : TargetAttrFeats) + CurrTargetAttrFeats.push_back(Feat); + Builder.SetInsertPoint(CurBlock); llvm::Value *FeatsCondition = EmitRISCVCpuSupports(CurrTargetAttrFeats); llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver); CGBuilderTy RetBuilder(*this, RetBlock); - CreateMultiVersionResolverReturn( - CGM, Resolver, RetBuilder, CurrOptions[Index].Function, SupportsIFunc); + CreateMultiVersionResolverReturn(CGM, Resolver, RetBuilder, + Options[Index].Function, SupportsIFunc); llvm::BasicBlock *ElseBlock = createBasicBlock("resolver_else", Resolver); Builder.SetInsertPoint(CurBlock); @@ -3019,9 +2988,8 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver( // Finally, emit the default one. if (HasDefault) { Builder.SetInsertPoint(CurBlock); - CreateMultiVersionResolverReturn(CGM, Resolver, Builder, - CurrOptions[DefaultIndex].Function, - SupportsIFunc); + CreateMultiVersionResolverReturn( + CGM, Resolver, Builder, Options[DefaultIndex].Function, SupportsIFunc); return; } @@ -3035,17 +3003,16 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver( } void CodeGenFunction::EmitAArch64MultiVersionResolver( - llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { + llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) { assert(!Options.empty() && "No multiversion resolver options found"); - assert(Options.back().Conditions.Features.size() == 0 && - "Default case must be last"); + assert(Options.back().Features.size() == 0 && "Default case must be last"); bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc(); assert(SupportsIFunc && "Multiversion resolver requires target IFUNC support"); bool AArch64CpuInitialized = false; llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver); - for (const MultiVersionResolverOption &RO : Options) { + for (const FMVResolverOption &RO : Options) { Builder.SetInsertPoint(CurBlock); llvm::Value *Condition = FormAArch64ResolverCondition(RO); @@ -3081,7 +3048,7 @@ void CodeGenFunction::EmitAArch64MultiVersionResolver( } void CodeGenFunction::EmitX86MultiVersionResolver( - llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { + llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) { bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc(); @@ -3090,7 +3057,7 @@ void CodeGenFunction::EmitX86MultiVersionResolver( Builder.SetInsertPoint(CurBlock); EmitX86CpuInit(); - for (const MultiVersionResolverOption &RO : Options) { + for (const FMVResolverOption &RO : Options) { Builder.SetInsertPoint(CurBlock); llvm::Value *Condition = FormX86ResolverCondition(RO); |