[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
This commit is contained in:
Manman Ren
2015-11-11 22:42:31 +00:00
parent fdbf201fc9
commit 6815026991
5 changed files with 60 additions and 37 deletions

View File

@@ -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);