summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-09-11 01:54:48 +0000
committerFangrui Song <maskray@google.com>2019-09-11 01:54:48 +0000
commit9ca1b94a6d3f491f26ccbeacf910342e6861fc7f (patch)
treef8197545a4a7e4829b20cbee9edb46e7c5969703 /clang/lib/CodeGen
parent56a34f4541cb6ca70f41f6229911894db18ff113 (diff)
downloadbcm5719-llvm-9ca1b94a6d3f491f26ccbeacf910342e6861fc7f.tar.gz
bcm5719-llvm-9ca1b94a6d3f491f26ccbeacf910342e6861fc7f.zip
[CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type
Multi-versioned functions defined by cpu_dispatch and implemented with IFunc can not be called outside the translation units where they are defined due to lack of symbols. This patch add function aliases for these functions and thus make them visible outside. Differential Revision: https://reviews.llvm.org/D67058 Patch by Senran Zhang llvm-svn: 371586
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp27
1 files changed, 24 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index eedf70b8d50..be7dfc97a98 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2836,11 +2836,13 @@ void CodeGenModule::emitMultiVersionFunctions() {
llvm::Function *ResolverFunc;
const TargetInfo &TI = getTarget();
- if (TI.supportsIFunc() || FD->isTargetMultiVersion())
+ if (TI.supportsIFunc() || FD->isTargetMultiVersion()) {
ResolverFunc = cast<llvm::Function>(
GetGlobalValue((getMangledName(GD) + ".resolver").str()));
- else
+ ResolverFunc->setLinkage(llvm::Function::WeakODRLinkage);
+ } else {
ResolverFunc = cast<llvm::Function>(GetGlobalValue(getMangledName(GD)));
+ }
if (supportsCOMDAT())
ResolverFunc->setComdat(
@@ -2884,6 +2886,10 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
auto *ResolverFunc = cast<llvm::Function>(GetOrCreateLLVMFunction(
ResolverName, ResolverType, ResolverGD, /*ForVTable=*/false));
+ ResolverFunc->setLinkage(llvm::Function::WeakODRLinkage);
+ if (supportsCOMDAT())
+ ResolverFunc->setComdat(
+ getModule().getOrInsertComdat(ResolverFunc->getName()));
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;
const TargetInfo &Target = getTarget();
@@ -2948,6 +2954,21 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
CodeGenFunction CGF(*this);
CGF.EmitMultiVersionResolver(ResolverFunc, Options);
+
+ if (getTarget().supportsIFunc()) {
+ std::string AliasName = getMangledNameImpl(
+ *this, GD, FD, /*OmitMultiVersionMangling=*/true);
+ llvm::Constant *AliasFunc = GetGlobalValue(AliasName);
+ if (!AliasFunc) {
+ auto *IFunc = cast<llvm::GlobalIFunc>(GetOrCreateLLVMFunction(
+ AliasName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true,
+ /*IsThunk=*/false, llvm::AttributeList(), NotForDefinition));
+ auto *GA = llvm::GlobalAlias::create(
+ DeclTy, 0, getFunctionLinkage(GD), AliasName, IFunc, &getModule());
+ GA->setLinkage(llvm::Function::WeakODRLinkage);
+ SetCommonAttributes(GD, GA);
+ }
+ }
}
/// If a dispatcher for the specified mangled name is not in the module, create
@@ -2984,7 +3005,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(
MangledName + ".resolver", ResolverType, GlobalDecl{},
/*ForVTable=*/false);
llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create(
- DeclTy, 0, llvm::Function::ExternalLinkage, "", Resolver, &getModule());
+ DeclTy, 0, llvm::Function::WeakODRLinkage, "", Resolver, &getModule());
GIF->setName(ResolverName);
SetCommonAttributes(FD, GIF);
OpenPOWER on IntegriCloud