summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-07-11 20:28:10 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-07-11 20:28:10 +0000
commit9b21c33da44985b59e637ee3a235ad1fb3472c60 (patch)
tree42666061684dd195d1b58270fd21a276fc9288ff /clang/lib
parent83510e70a9fd0bd2bbe474f510e037937dd6abc7 (diff)
downloadbcm5719-llvm-9b21c33da44985b59e637ee3a235ad1fb3472c60.tar.gz
bcm5719-llvm-9b21c33da44985b59e637ee3a235ad1fb3472c60.zip
CodeGen: Don't emit a thread-wrapper if we can't touch the backing variable
OS X TLS has all accesses going through the thread-wrapper function and gives the backing thread-local variable internal linkage. This means that thread-wrappers must have WeakAnyLinkage so that references to the internal thread-local variables do not get propagated to other code. It also means that translation units which do not provide a definition for the thread-local variable cannot attempt to emit a thread-wrapper because the thread wrapper will attempt to reference the backing variable. Differential Revision: http://reviews.llvm.org/D4109 llvm-svn: 212841
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp30
1 files changed, 23 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index baf09274941..d7e61f0fe57 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1818,6 +1818,15 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
}
+static bool isThreadWrapperReplaceable(const VarDecl *VD,
+ CodeGen::CodeGenModule &CGM) {
+ assert(!VD->isStaticLocal() && "static local VarDecls don't need wrappers!");
+ // OS X prefers to have references to thread local variables to go through
+ // the thread wrapper instead of directly referencing the backing variable.
+ return VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+ CGM.getTarget().getTriple().isMacOSX();
+}
+
/// Get the appropriate linkage for the wrapper function. This is essentially
/// the weak form of the variable's linkage; every translation unit which needs
/// the wrapper emits a copy, and we want the linker to merge them.
@@ -1830,12 +1839,13 @@ getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
return VarLinkage;
- // All accesses to the thread_local variable go through the thread wrapper.
- // However, this means that we cannot allow the thread wrapper to get inlined
- // into any functions.
- if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
- CGM.getTarget().getTriple().isMacOSX())
- return llvm::GlobalValue::WeakAnyLinkage;
+ // 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;
+ }
return llvm::GlobalValue::WeakODRLinkage;
}
@@ -1862,7 +1872,7 @@ 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())
+ if (!Wrapper->hasLocalLinkage() && !isThreadWrapperReplaceable(VD, CGM))
Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
return Wrapper;
}
@@ -1874,6 +1884,12 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
const VarDecl *VD = Decls[I].first;
llvm::GlobalVariable *Var = Decls[I].second;
+ // Some targets require that all access to thread local variables go through
+ // the thread wrapper. This means that we cannot attempt to create a thread
+ // wrapper or a thread helper.
+ if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition())
+ continue;
+
// Mangle the name for the thread_local initialization function.
SmallString<256> InitFnName;
{
OpenPOWER on IntegriCloud