<div dir="ltr">On Mon, Apr 29, 2013 at 3:27 PM, Bill Wendling <span dir="ltr"><<a href="mailto:isanbard@gmail.com" target="_blank">isanbard@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: void<br>
Date: Mon Apr 29 17:27:16 2013<br>
New Revision: 180739<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=180739&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=180739&view=rev</a><br>
Log:<br>
Emit the TLS intialization functions into a list.<br>
<br>
Add the TLS initialization functions to a list of initialization functions. The<br>
back-end takes this list and places the function pointers into the correct<br>
section. This way they're called before `main().'<br></blockquote><div><br></div><div style>Why?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<rdar://problem/13733006><br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=180739&r1=180738&r2=180739&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=180739&r1=180738&r2=180739&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Mon Apr 29 17:27:16 2013<br>
@@ -304,6 +304,7 @@ void CodeGenModule::EmitCXXThreadLocalIn<br>
     Guard->setThreadLocal(true);<br>
     CodeGenFunction(*this)<br>
         .GenerateCXXGlobalInitFunc(InitFn, CXXThreadLocalInits, Guard);<br>
+    AddTLSInitFunc(InitFn);<br>
   }<br>
<br>
   getCXXABI().EmitThreadLocalInitFuncs(CXXThreadLocals, InitFn);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=180739&r1=180738&r2=180739&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=180739&r1=180738&r2=180739&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Apr 29 17:27:16 2013<br>
@@ -182,6 +182,7 @@ void CodeGenModule::Release() {<br>
       AddGlobalCtor(ObjCInitFunction);<br>
   EmitCtorList(GlobalCtors, "llvm.global_ctors");<br>
   EmitCtorList(GlobalDtors, "llvm.global_dtors");<br>
+  EmitTLSList(TLSInitFuncs);<br>
   EmitGlobalAnnotations();<br>
   EmitStaticExternCAliases();<br>
   EmitLLVMUsed();<br>
@@ -479,6 +480,12 @@ void CodeGenModule::AddGlobalDtor(llvm::<br>
   GlobalDtors.push_back(std::make_pair(Dtor, Priority));<br>
 }<br>
<br>
+/// AddTLSInitFunc - Add a function to the list that will initialize TLS<br>
+/// variables before main() runs.<br>
+void CodeGenModule::AddTLSInitFunc(llvm::Function *Init) {<br>
+  TLSInitFuncs.push_back(Init);<br>
+}<br>
+<br>
 void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {<br>
   // Ctor function type is void()*.<br>
   llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false);<br>
@@ -507,6 +514,25 @@ void CodeGenModule::EmitCtorList(const C<br>
   }<br>
 }<br>
<br>
+void CodeGenModule::EmitTLSList(ArrayRef<llvm::Constant*> Fns) {<br>
+  if (Fns.empty()) return;<br>
+<br>
+  // TLS init function types are void()*.<br>
+  llvm::FunctionType* TLSFTy = llvm::FunctionType::get(VoidTy, false);<br>
+  llvm::Type *TLSPFTy = llvm::PointerType::getUnqual(TLSFTy);<br>
+<br>
+  SmallVector<llvm::Constant*, 8> Inits;<br>
+  for (ArrayRef<llvm::Constant*>::iterator I = Fns.begin(),<br>
+         E = Fns.end(); I != E; ++I)<br>
+    Inits.push_back(llvm::ConstantExpr::getBitCast(*I, TLSPFTy));<br>
+<br>
+  llvm::ArrayType *AT = llvm::ArrayType::get(TLSPFTy, Inits.size());<br>
+  new llvm::GlobalVariable(TheModule, AT, false,<br>
+                           llvm::GlobalValue::AppendingLinkage,<br>
+                           llvm::ConstantArray::get(AT, Inits),<br>
+                           "llvm.tls_init_funcs");<br>
+}<br>
+<br>
 llvm::GlobalValue::LinkageTypes<br>
 CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {<br>
   GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=180739&r1=180738&r2=180739&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=180739&r1=180738&r2=180739&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Apr 29 17:27:16 2013<br>
@@ -293,6 +293,10 @@ class CodeGenModule : public CodeGenType<br>
   /// priorities to be emitted when the translation unit is complete.<br>
   CtorList GlobalDtors;<br>
<br>
+  /// TLSInitFuncs - Store the list of TLS initialization functions toe be<br>
+  /// emitted with the translation unit is complete.<br>
+  std::vector<llvm::Constant*> TLSInitFuncs;<br>
+<br>
   /// MangledDeclNames - A map of canonical GlobalDecls to their mangled names.<br>
   llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames;<br>
   llvm::BumpPtrAllocator MangledNamesAllocator;<br>
@@ -1053,11 +1057,18 @@ private:<br>
   void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535);<br>
   void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535);<br>
<br>
+  void AddTLSInitFunc(llvm::Function *Init);<br>
+<br>
   /// EmitCtorList - Generates a global array of functions and priorities using<br>
   /// the given list and name. This array will have appending linkage and is<br>
   /// suitable for use as a LLVM constructor or destructor array.<br>
   void EmitCtorList(const CtorList &Fns, const char *GlobalName);<br>
<br>
+  /// EmitTLSList - Generates a global array of functions with the name<br>
+  /// `llvm.tls_init_funcs'. This array will have appending linkage and is meant<br>
+  /// to hold initialization functions for TLS variables.<br>
+  void EmitTLSList(ArrayRef<llvm::Constant*> Fns);<br>
+<br>
   /// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the<br>
   /// given type.<br>
   void EmitFundamentalRTTIDescriptor(QualType Type);<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp?rev=180739&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp?rev=180739&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp Mon Apr 29 17:27:16 2013<br>
@@ -0,0 +1,21 @@<br>
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -std=c++11 -S -emit-llvm %s -o - | FileCheck -check-prefix=BITCODE %s<br>
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -std=c++11 -S %s -o - | FileCheck -check-prefix=ASM %s<br>
+<br>
+// BITCODE: @llvm.tls_init_funcs = appending global [1 x void ()*] [void ()* @__tls_init]<br>
+<br>
+struct A {<br>
+  A();<br>
+};<br>
+<br>
+struct B {<br>
+  int i;<br>
+  B(int i);<br>
+};<br>
+<br>
+thread_local int i = 37;<br>
+thread_local A a;<br>
+thread_local B b(927);<br>
+<br>
+// ASM: .section __DATA,__thread_init,thread_local_init_function_pointers<br>
+// ASM: .align 3<br>
+// ASM: .quad ___tls_init<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>