@@ -3449,9 +3449,6 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
3449
3449
// Implicit template instantiations may change linkage if they are later
3450
3450
// explicitly instantiated, so they should not be emitted eagerly.
3451
3451
return false ;
3452
- // Defer until all versions have been semantically checked.
3453
- if (FD->hasAttr <TargetVersionAttr>() && !FD->isMultiVersion ())
3454
- return false ;
3455
3452
}
3456
3453
if (const auto *VD = dyn_cast<VarDecl>(Global)) {
3457
3454
if (Context.getInlineVariableDefinitionKind (VD) ==
@@ -4000,13 +3997,10 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD,
4000
3997
EmitGlobalFunctionDefinition (GD.getWithMultiVersionIndex (I), nullptr );
4001
3998
// Ensure that the resolver function is also emitted.
4002
3999
GetOrCreateMultiVersionResolver (GD);
4000
+ } else if (FD->hasAttr <TargetVersionAttr>()) {
4001
+ GetOrCreateMultiVersionResolver (GD);
4003
4002
} else
4004
4003
EmitGlobalFunctionDefinition (GD, GV);
4005
-
4006
- // Defer the resolver emission until we can reason whether the TU
4007
- // contains a default target version implementation.
4008
- if (FD->isTargetVersionMultiVersion ())
4009
- AddDeferredMultiVersionResolverToEmit (GD);
4010
4004
}
4011
4005
4012
4006
void CodeGenModule::EmitGlobalDefinition (GlobalDecl GD, llvm::GlobalValue *GV) {
@@ -4099,11 +4093,10 @@ void CodeGenModule::emitMultiVersionFunctions() {
4099
4093
const auto *FD = cast<FunctionDecl>(GD.getDecl ());
4100
4094
assert (FD && " Expected a FunctionDecl" );
4101
4095
4102
- bool EmitResolver = !FD->isTargetVersionMultiVersion ();
4103
4096
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10 > Options;
4104
4097
if (FD->isTargetMultiVersion ()) {
4105
4098
getContext ().forEachMultiversionedFunctionVersion (
4106
- FD, [this , &GD, &Options, &EmitResolver ](const FunctionDecl *CurFD) {
4099
+ FD, [this , &GD, &Options](const FunctionDecl *CurFD) {
4107
4100
GlobalDecl CurGD{
4108
4101
(CurFD->isDefined () ? CurFD->getDefinition () : CurFD)};
4109
4102
StringRef MangledName = getMangledName (CurGD);
@@ -4129,9 +4122,6 @@ void CodeGenModule::emitMultiVersionFunctions() {
4129
4122
TA->getArchitecture (), Feats);
4130
4123
} else {
4131
4124
const auto *TVA = CurFD->getAttr <TargetVersionAttr>();
4132
- if (CurFD->isUsed () || (TVA->isDefaultVersion () &&
4133
- CurFD->doesThisDeclarationHaveABody ()))
4134
- EmitResolver = true ;
4135
4125
llvm::SmallVector<StringRef, 8 > Feats;
4136
4126
TVA->getFeatures (Feats);
4137
4127
Options.emplace_back (cast<llvm::Function>(Func),
@@ -4187,27 +4177,22 @@ void CodeGenModule::emitMultiVersionFunctions() {
4187
4177
continue ;
4188
4178
}
4189
4179
4190
- if (!EmitResolver)
4191
- continue ;
4192
-
4193
4180
llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver (GD);
4194
4181
if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) {
4195
4182
ResolverConstant = IFunc->getResolver ();
4196
4183
if (FD->isTargetClonesMultiVersion () ||
4197
4184
FD->isTargetVersionMultiVersion ()) {
4185
+ const CGFunctionInfo &FI = getTypes ().arrangeGlobalDeclaration (GD);
4186
+ llvm::FunctionType *DeclTy = getTypes ().GetFunctionType (FI);
4198
4187
std::string MangledName = getMangledNameImpl (
4199
4188
*this , GD, FD, /* OmitMultiVersionMangling=*/ true );
4200
- if (!GetGlobalValue (MangledName + " .ifunc" )) {
4201
- const CGFunctionInfo &FI = getTypes ().arrangeGlobalDeclaration (GD);
4202
- llvm::FunctionType *DeclTy = getTypes ().GetFunctionType (FI);
4203
- // In prior versions of Clang, the mangling for ifuncs incorrectly
4204
- // included an .ifunc suffix. This alias is generated for backward
4205
- // compatibility. It is deprecated, and may be removed in the future.
4206
- auto *Alias = llvm::GlobalAlias::create (
4207
- DeclTy, 0 , getMultiversionLinkage (*this , GD),
4208
- MangledName + " .ifunc" , IFunc, &getModule ());
4209
- SetCommonAttributes (FD, Alias);
4210
- }
4189
+ // In prior versions of Clang, the mangling for ifuncs incorrectly
4190
+ // included an .ifunc suffix. This alias is generated for backward
4191
+ // compatibility. It is deprecated, and may be removed in the future.
4192
+ auto *Alias = llvm::GlobalAlias::create (
4193
+ DeclTy, 0 , getMultiversionLinkage (*this , GD),
4194
+ MangledName + " .ifunc" , IFunc, &getModule ());
4195
+ SetCommonAttributes (FD, Alias);
4211
4196
}
4212
4197
}
4213
4198
llvm::Function *ResolverFunc = cast<llvm::Function>(ResolverConstant);
@@ -4364,20 +4349,6 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
4364
4349
}
4365
4350
}
4366
4351
4367
- // / Adds a declaration to the list of multi version functions if not present.
4368
- void CodeGenModule::AddDeferredMultiVersionResolverToEmit (GlobalDecl GD) {
4369
- const auto *FD = cast<FunctionDecl>(GD.getDecl ());
4370
- assert (FD && " Not a FunctionDecl?" );
4371
-
4372
- if (FD->isTargetVersionMultiVersion ()) {
4373
- std::string MangledName =
4374
- getMangledNameImpl (*this , GD, FD, /* OmitMultiVersionMangling=*/ true );
4375
- if (!DeferredResolversToEmit.insert (MangledName).second )
4376
- return ;
4377
- }
4378
- MultiVersionFuncs.push_back (GD);
4379
- }
4380
-
4381
4352
// / If a dispatcher for the specified mangled name is not in the module, create
4382
4353
// / and return an llvm Function with the specified type.
4383
4354
llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver (GlobalDecl GD) {
@@ -4417,7 +4388,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
4417
4388
// The resolver needs to be created. For target and target_clones, defer
4418
4389
// creation until the end of the TU.
4419
4390
if (FD->isTargetMultiVersion () || FD->isTargetClonesMultiVersion ())
4420
- AddDeferredMultiVersionResolverToEmit (GD);
4391
+ MultiVersionFuncs. push_back (GD);
4421
4392
4422
4393
// For cpu_specific, don't create an ifunc yet because we don't know if the
4423
4394
// cpu_dispatch will be emitted in this translation unit.
0 commit comments