@@ -3811,9 +3811,6 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
3811
3811
// Implicit template instantiations may change linkage if they are later
3812
3812
// explicitly instantiated, so they should not be emitted eagerly.
3813
3813
return false ;
3814
- // Defer until all versions have been semantically checked.
3815
- if (FD->hasAttr <TargetVersionAttr>() && !FD->isMultiVersion ())
3816
- return false ;
3817
3814
}
3818
3815
if (const auto *VD = dyn_cast<VarDecl>(Global)) {
3819
3816
if (Context.getInlineVariableDefinitionKind (VD) ==
@@ -4431,13 +4428,10 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD,
4431
4428
EmitGlobalFunctionDefinition (GD.getWithMultiVersionIndex (I), nullptr );
4432
4429
// Ensure that the resolver function is also emitted.
4433
4430
GetOrCreateMultiVersionResolver (GD);
4431
+ } else if (FD->hasAttr <TargetVersionAttr>()) {
4432
+ GetOrCreateMultiVersionResolver (GD);
4434
4433
} else
4435
4434
EmitGlobalFunctionDefinition (GD, GV);
4436
-
4437
- // Defer the resolver emission until we can reason whether the TU
4438
- // contains a default target version implementation.
4439
- if (FD->isTargetVersionMultiVersion ())
4440
- AddDeferredMultiVersionResolverToEmit (GD);
4441
4435
}
4442
4436
4443
4437
void CodeGenModule::EmitGlobalDefinition (GlobalDecl GD, llvm::GlobalValue *GV) {
@@ -4530,11 +4524,10 @@ void CodeGenModule::emitMultiVersionFunctions() {
4530
4524
const auto *FD = cast<FunctionDecl>(GD.getDecl ());
4531
4525
assert (FD && " Expected a FunctionDecl" );
4532
4526
4533
- bool EmitResolver = !FD->isTargetVersionMultiVersion ();
4534
4527
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10 > Options;
4535
4528
if (FD->isTargetMultiVersion ()) {
4536
4529
getContext ().forEachMultiversionedFunctionVersion (
4537
- FD, [this , &GD, &Options, &EmitResolver ](const FunctionDecl *CurFD) {
4530
+ FD, [this , &GD, &Options](const FunctionDecl *CurFD) {
4538
4531
GlobalDecl CurGD{
4539
4532
(CurFD->isDefined () ? CurFD->getDefinition () : CurFD)};
4540
4533
StringRef MangledName = getMangledName (CurGD);
@@ -4560,9 +4553,6 @@ void CodeGenModule::emitMultiVersionFunctions() {
4560
4553
TA->getArchitecture (), Feats);
4561
4554
} else {
4562
4555
const auto *TVA = CurFD->getAttr <TargetVersionAttr>();
4563
- if (CurFD->isUsed () || (TVA->isDefaultVersion () &&
4564
- CurFD->doesThisDeclarationHaveABody ()))
4565
- EmitResolver = true ;
4566
4556
llvm::SmallVector<StringRef, 8 > Feats;
4567
4557
TVA->getFeatures (Feats);
4568
4558
Options.emplace_back (cast<llvm::Function>(Func),
@@ -4618,27 +4608,22 @@ void CodeGenModule::emitMultiVersionFunctions() {
4618
4608
continue ;
4619
4609
}
4620
4610
4621
- if (!EmitResolver)
4622
- continue ;
4623
-
4624
4611
llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver (GD);
4625
4612
if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) {
4626
4613
ResolverConstant = IFunc->getResolver ();
4627
4614
if (FD->isTargetClonesMultiVersion () ||
4628
4615
FD->isTargetVersionMultiVersion ()) {
4616
+ const CGFunctionInfo &FI = getTypes ().arrangeGlobalDeclaration (GD);
4617
+ llvm::FunctionType *DeclTy = getTypes ().GetFunctionType (FI);
4629
4618
std::string MangledName = getMangledNameImpl (
4630
4619
*this , GD, FD, /* OmitMultiVersionMangling=*/ true );
4631
- if (!GetGlobalValue (MangledName + " .ifunc" )) {
4632
- const CGFunctionInfo &FI = getTypes ().arrangeGlobalDeclaration (GD);
4633
- llvm::FunctionType *DeclTy = getTypes ().GetFunctionType (FI);
4634
- // In prior versions of Clang, the mangling for ifuncs incorrectly
4635
- // included an .ifunc suffix. This alias is generated for backward
4636
- // compatibility. It is deprecated, and may be removed in the future.
4637
- auto *Alias = llvm::GlobalAlias::create (
4638
- DeclTy, 0 , getMultiversionLinkage (*this , GD),
4639
- MangledName + " .ifunc" , IFunc, &getModule ());
4640
- SetCommonAttributes (FD, Alias);
4641
- }
4620
+ // In prior versions of Clang, the mangling for ifuncs incorrectly
4621
+ // included an .ifunc suffix. This alias is generated for backward
4622
+ // compatibility. It is deprecated, and may be removed in the future.
4623
+ auto *Alias = llvm::GlobalAlias::create (
4624
+ DeclTy, 0 , getMultiversionLinkage (*this , GD),
4625
+ MangledName + " .ifunc" , IFunc, &getModule ());
4626
+ SetCommonAttributes (FD, Alias);
4642
4627
}
4643
4628
}
4644
4629
llvm::Function *ResolverFunc = cast<llvm::Function>(ResolverConstant);
@@ -4795,20 +4780,6 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
4795
4780
}
4796
4781
}
4797
4782
4798
- // / Adds a declaration to the list of multi version functions if not present.
4799
- void CodeGenModule::AddDeferredMultiVersionResolverToEmit (GlobalDecl GD) {
4800
- const auto *FD = cast<FunctionDecl>(GD.getDecl ());
4801
- assert (FD && " Not a FunctionDecl?" );
4802
-
4803
- if (FD->isTargetVersionMultiVersion ()) {
4804
- std::string MangledName =
4805
- getMangledNameImpl (*this , GD, FD, /* OmitMultiVersionMangling=*/ true );
4806
- if (!DeferredResolversToEmit.insert (MangledName).second )
4807
- return ;
4808
- }
4809
- MultiVersionFuncs.push_back (GD);
4810
- }
4811
-
4812
4783
// / If a dispatcher for the specified mangled name is not in the module, create
4813
4784
// / and return an llvm Function with the specified type.
4814
4785
llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver (GlobalDecl GD) {
@@ -4848,7 +4819,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
4848
4819
// The resolver needs to be created. For target and target_clones, defer
4849
4820
// creation until the end of the TU.
4850
4821
if (FD->isTargetMultiVersion () || FD->isTargetClonesMultiVersion ())
4851
- AddDeferredMultiVersionResolverToEmit (GD);
4822
+ MultiVersionFuncs. push_back (GD);
4852
4823
4853
4824
// For cpu_specific, don't create an ifunc yet because we don't know if the
4854
4825
// cpu_dispatch will be emitted in this translation unit.
0 commit comments