From f353ae184877a2d78aaa1f63646709de54fa0e76 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Thu, 13 Sep 2018 16:58:24 +0000 Subject: [NFC]Refactor MultiVersion Resolver Emission to combine types Previously, both types (plus the future target-clones) of multiversioning had a separate ResolverOption structure and emission function. This patch combines the two, at the expense of a slightly more expensive sorting function. llvm-svn: 342152 --- clang/lib/CodeGen/CodeGenModule.cpp | 47 ++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6d42b3c..7df2ea7 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2441,9 +2441,22 @@ 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; + for (StringRef Feat : RO.Conditions.Features) + Priority = std::max(Priority, TI.multiVersionSortPriority(Feat)); + + if (!RO.Conditions.Architecture.empty()) + Priority = std::max( + Priority, TI.multiVersionSortPriority(RO.Conditions.Architecture)); + return Priority; +} + void CodeGenModule::emitMultiVersionFunctions() { for (GlobalDecl GD : MultiVersionFuncs) { - SmallVector Options; + SmallVector Options; const FunctionDecl *FD = cast(GD.getDecl()); getContext().forEachMultiversionedFunctionVersion( FD, [this, &GD, &Options](const FunctionDecl *CurFD) { @@ -2464,8 +2477,13 @@ void CodeGenModule::emitMultiVersionFunctions() { } assert(Func && "This should have just been created"); } - Options.emplace_back(getTarget(), cast(Func), - CurFD->getAttr()->parse()); + + const auto *TA = CurFD->getAttr(); + llvm::SmallVector Feats; + TA->getAddedFeatures(Feats); + + Options.emplace_back(cast(Func), + TA->getArchitecture(), Feats); }); llvm::Function *ResolverFunc = cast( @@ -2473,11 +2491,16 @@ void CodeGenModule::emitMultiVersionFunctions() { if (supportsCOMDAT()) ResolverFunc->setComdat( getModule().getOrInsertComdat(ResolverFunc->getName())); + + const TargetInfo &TI = getTarget(); std::stable_sort( Options.begin(), Options.end(), - std::greater()); + [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS, + const CodeGenFunction::MultiVersionResolverOption &RHS) { + return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS); + }); CodeGenFunction CGF(*this); - CGF.EmitTargetMultiVersionResolver(ResolverFunc, Options); + CGF.EmitMultiVersionResolver(ResolverFunc, Options); } } @@ -2497,8 +2520,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { GetOrCreateLLVMFunction(ResolverName, ResolverType, GlobalDecl{}, /*ForVTable=*/false)); - SmallVector - Options; + SmallVector Options; const TargetInfo &Target = getTarget(); for (const IdentifierInfo *II : DD->cpus()) { // Get the name of the target function so we can look it up/create it. @@ -2515,15 +2537,18 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { Features.begin(), Features.end(), [&Target](StringRef Feat) { return !Target.validateCpuSupports(Feat); }), Features.end()); - Options.emplace_back(cast(Func), - CodeGenFunction::GetX86CpuSupportsMask(Features)); + Options.emplace_back(cast(Func), StringRef{}, Features); } llvm::sort( Options.begin(), Options.end(), - std::greater()); + [](const CodeGenFunction::MultiVersionResolverOption &LHS, + const CodeGenFunction::MultiVersionResolverOption &RHS) { + return CodeGenFunction::GetX86CpuSupportsMask(LHS.Conditions.Features) > + CodeGenFunction::GetX86CpuSupportsMask(RHS.Conditions.Features); + }); CodeGenFunction CGF(*this); - CGF.EmitCPUDispatchMultiVersionResolver(ResolverFunc, Options); + CGF.EmitMultiVersionResolver(ResolverFunc, Options); } /// If an ifunc for the specified mangled name is not in the module, create and -- cgit v1.1