@@ -4090,77 +4090,80 @@ llvm::GlobalValue::LinkageTypes getMultiversionLinkage(CodeGenModule &CGM,
4090
4090
return llvm::GlobalValue::WeakODRLinkage;
4091
4091
}
4092
4092
4093
+ static FunctionDecl *createDefaultTargetVersionFrom (const FunctionDecl *FD) {
4094
+ DeclContext *DeclCtx = FD->getASTContext ().getTranslationUnitDecl ();
4095
+ TypeSourceInfo *TInfo = FD->getTypeSourceInfo ();
4096
+ StorageClass SC = FD->getStorageClass ();
4097
+ DeclarationName Name = FD->getNameInfo ().getName ();
4098
+
4099
+ FunctionDecl *NewDecl =
4100
+ FunctionDecl::Create (FD->getASTContext (), DeclCtx, FD->getBeginLoc (),
4101
+ FD->getEndLoc (), Name, TInfo->getType (), TInfo, SC);
4102
+
4103
+ NewDecl->setIsMultiVersion ();
4104
+ NewDecl->addAttr (TargetVersionAttr::CreateImplicit (
4105
+ NewDecl->getASTContext (), " default" , NewDecl->getSourceRange ()));
4106
+
4107
+ return NewDecl;
4108
+ }
4109
+
4093
4110
void CodeGenModule::emitMultiVersionFunctions () {
4094
4111
std::vector<GlobalDecl> MVFuncsToEmit;
4095
4112
MultiVersionFuncs.swap (MVFuncsToEmit);
4096
4113
for (GlobalDecl GD : MVFuncsToEmit) {
4097
4114
const auto *FD = cast<FunctionDecl>(GD.getDecl ());
4098
4115
assert (FD && " Expected a FunctionDecl" );
4099
4116
4100
- bool EmitResolver = !FD->isTargetVersionMultiVersion ();
4117
+ auto createFunction = [&](const FunctionDecl *Decl, unsigned MVIdx = 0 ) {
4118
+ GlobalDecl CurGD{Decl->isDefined () ? Decl->getDefinition () : Decl, MVIdx};
4119
+ StringRef MangledName = getMangledName (CurGD);
4120
+ llvm::Constant *Func = GetGlobalValue (MangledName);
4121
+ if (!Func) {
4122
+ if (Decl->isDefined ()) {
4123
+ EmitGlobalFunctionDefinition (CurGD, nullptr );
4124
+ Func = GetGlobalValue (MangledName);
4125
+ } else {
4126
+ const CGFunctionInfo &FI = getTypes ().arrangeGlobalDeclaration (CurGD);
4127
+ llvm::FunctionType *Ty = getTypes ().GetFunctionType (FI);
4128
+ Func = GetAddrOfFunction (CurGD, Ty, /* ForVTable=*/ false ,
4129
+ /* DontDefer=*/ false , ForDefinition);
4130
+ }
4131
+ assert (Func && " This should have just been created" );
4132
+ }
4133
+ return Func;
4134
+ };
4135
+
4136
+ bool HasDefaultDecl = !FD->isTargetVersionMultiVersion ();
4137
+ bool ShouldEmitResolver = !FD->isTargetVersionMultiVersion ();
4101
4138
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10 > Options;
4102
4139
if (FD->isTargetMultiVersion ()) {
4103
4140
getContext ().forEachMultiversionedFunctionVersion (
4104
- FD, [this , &GD, &Options, &EmitResolver](const FunctionDecl *CurFD) {
4105
- GlobalDecl CurGD{
4106
- (CurFD->isDefined () ? CurFD->getDefinition () : CurFD)};
4107
- StringRef MangledName = getMangledName (CurGD);
4108
- llvm::Constant *Func = GetGlobalValue (MangledName);
4109
- if (!Func) {
4110
- if (CurFD->isDefined ()) {
4111
- EmitGlobalFunctionDefinition (CurGD, nullptr );
4112
- Func = GetGlobalValue (MangledName);
4113
- } else {
4114
- const CGFunctionInfo &FI =
4115
- getTypes ().arrangeGlobalDeclaration (GD);
4116
- llvm::FunctionType *Ty = getTypes ().GetFunctionType (FI);
4117
- Func = GetAddrOfFunction (CurGD, Ty, /* ForVTable=*/ false ,
4118
- /* DontDefer=*/ false , ForDefinition);
4119
- }
4120
- assert (Func && " This should have just been created" );
4121
- }
4122
- if (CurFD->getMultiVersionKind () == MultiVersionKind::Target) {
4123
- const auto *TA = CurFD->getAttr <TargetAttr>();
4124
- llvm::SmallVector<StringRef, 8 > Feats;
4141
+ FD, [&](const FunctionDecl *CurFD) {
4142
+ llvm::SmallVector<StringRef, 8 > Feats;
4143
+ llvm::Constant *Func = createFunction (CurFD);
4144
+
4145
+ if (const auto *TA = CurFD->getAttr <TargetAttr>()) {
4125
4146
TA->getAddedFeatures (Feats);
4126
4147
Options.emplace_back (cast<llvm::Function>(Func),
4127
4148
TA->getArchitecture (), Feats);
4128
- } else {
4129
- const auto *TVA = CurFD->getAttr <TargetVersionAttr>();
4130
- if (CurFD->isUsed () || (TVA->isDefaultVersion () &&
4131
- CurFD->doesThisDeclarationHaveABody ()))
4132
- EmitResolver = true ;
4133
- llvm::SmallVector<StringRef, 8 > Feats;
4149
+ } else if (const auto *TVA = CurFD->getAttr <TargetVersionAttr>()) {
4150
+ bool HasDefaultDef = TVA->isDefaultVersion () &&
4151
+ CurFD->doesThisDeclarationHaveABody ();
4152
+ HasDefaultDecl |= TVA->isDefaultVersion ();
4153
+ ShouldEmitResolver |= (CurFD->isUsed () || HasDefaultDef);
4134
4154
TVA->getFeatures (Feats);
4135
4155
Options.emplace_back (cast<llvm::Function>(Func),
4136
4156
/* Architecture*/ " " , Feats);
4137
- }
4157
+ } else
4158
+ llvm_unreachable (" unexpected MultiVersionKind" );
4138
4159
});
4139
- } else if (FD->isTargetClonesMultiVersion ()) {
4140
- const auto *TC = FD->getAttr <TargetClonesAttr>();
4141
- for (unsigned VersionIndex = 0 ; VersionIndex < TC->featuresStrs_size ();
4142
- ++VersionIndex) {
4143
- if (!TC->isFirstOfVersion (VersionIndex))
4160
+ } else if (const auto *TC = FD->getAttr <TargetClonesAttr>()) {
4161
+ for (unsigned I = 0 ; I < TC->featuresStrs_size (); ++I) {
4162
+ if (!TC->isFirstOfVersion (I))
4144
4163
continue ;
4145
- GlobalDecl CurGD{(FD->isDefined () ? FD->getDefinition () : FD),
4146
- VersionIndex};
4147
- StringRef Version = TC->getFeatureStr (VersionIndex);
4148
- StringRef MangledName = getMangledName (CurGD);
4149
- llvm::Constant *Func = GetGlobalValue (MangledName);
4150
- if (!Func) {
4151
- if (FD->isDefined ()) {
4152
- EmitGlobalFunctionDefinition (CurGD, nullptr );
4153
- Func = GetGlobalValue (MangledName);
4154
- } else {
4155
- const CGFunctionInfo &FI =
4156
- getTypes ().arrangeGlobalDeclaration (CurGD);
4157
- llvm::FunctionType *Ty = getTypes ().GetFunctionType (FI);
4158
- Func = GetAddrOfFunction (CurGD, Ty, /* ForVTable=*/ false ,
4159
- /* DontDefer=*/ false , ForDefinition);
4160
- }
4161
- assert (Func && " This should have just been created" );
4162
- }
4163
4164
4165
+ llvm::Constant *Func = createFunction (FD, I);
4166
+ StringRef Version = TC->getFeatureStr (I);
4164
4167
StringRef Architecture;
4165
4168
llvm::SmallVector<StringRef, 1 > Feature;
4166
4169
@@ -4185,9 +4188,16 @@ void CodeGenModule::emitMultiVersionFunctions() {
4185
4188
continue ;
4186
4189
}
4187
4190
4188
- if (!EmitResolver )
4191
+ if (!ShouldEmitResolver )
4189
4192
continue ;
4190
4193
4194
+ if (!HasDefaultDecl) {
4195
+ FunctionDecl *NewFD = createDefaultTargetVersionFrom (FD);
4196
+ llvm::Constant *Func = createFunction (NewFD);
4197
+ llvm::SmallVector<StringRef, 1 > Feats;
4198
+ Options.emplace_back (cast<llvm::Function>(Func), " " , Feats);
4199
+ }
4200
+
4191
4201
llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver (GD);
4192
4202
if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) {
4193
4203
ResolverConstant = IFunc->getResolver ();
0 commit comments