diff options
author | Manman Ren <manman.ren@gmail.com> | 2015-11-11 22:42:31 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2015-11-11 22:42:31 +0000 |
commit | 68150269914cb43e10a636cc9c84eb6a36cc8262 (patch) | |
tree | d5dfa3c1f7e9c196597183a512ba6016b0d80ae9 /clang/lib/CodeGen | |
parent | fdbf201fc97004417cdb644aa8d10d2fcb096768 (diff) | |
download | bcm5719-llvm-68150269914cb43e10a636cc9c84eb6a36cc8262.tar.gz bcm5719-llvm-68150269914cb43e10a636cc9c84eb6a36cc8262.zip |
[TLS on Darwin] change how we handle globals with linkonce or weak linkage.
This is about how we handle static member of a template. Before this commit,
we use internal linkage for the IR thread-local variable, which is inefficient.
With this commit, we will start to follow Itanium C++ ABI.
rdar://problem/23415206
Reviewed by John McCall.
llvm-svn: 252814
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 14 |
2 files changed, 16 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 5d7794e4a30..d36a85df54c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2315,12 +2315,17 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { llvm::GlobalValue::LinkageTypes Linkage = getLLVMLinkageVarDefinition(D, GV->isConstant()); - // On Darwin, the backing variable for a C++11 thread_local variable always - // has internal linkage; all accesses should just be calls to the + // On Darwin, if the normal linkage of a C++ thread_local variable is + // LinkOnce or Weak, we keep the normal linkage to prevent multiple + // copies within a linkage unit; otherwise, the backing variable has + // internal linkage and all accesses should just be calls to the // Itanium-specified entry point, which has the normal linkage of the - // variable. + // variable. This is to preserve the ability to change the implementation + // behind the scenes. if (!D->isStaticLocal() && D->getTLSKind() == VarDecl::TLS_Dynamic && - Context.getTargetInfo().getTriple().isMacOSX()) + Context.getTargetInfo().getTriple().isMacOSX() && + !llvm::GlobalVariable::isLinkOnceLinkage(Linkage) && + !llvm::GlobalVariable::isWeakLinkage(Linkage)) Linkage = llvm::GlobalValue::InternalLinkage; GV->setLinkage(Linkage); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 0eea014b3d9..a6402f233c3 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2163,12 +2163,10 @@ getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) { return VarLinkage; // If the thread wrapper is replaceable, give it appropriate linkage. - if (isThreadWrapperReplaceable(VD, CGM)) { - if (llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) || - llvm::GlobalVariable::isWeakODRLinkage(VarLinkage)) - return llvm::GlobalVariable::WeakAnyLinkage; - return VarLinkage; - } + if (isThreadWrapperReplaceable(VD, CGM)) + if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) && + !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage)) + return VarLinkage; return llvm::GlobalValue::WeakODRLinkage; } @@ -2194,7 +2192,9 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM), WrapperName.str(), &CGM.getModule()); // Always resolve references to the wrapper at link time. - if (!Wrapper->hasLocalLinkage() && !isThreadWrapperReplaceable(VD, CGM)) + if (!Wrapper->hasLocalLinkage() && !(isThreadWrapperReplaceable(VD, CGM) && + !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) && + !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()))) Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility); return Wrapper; } |