r180739 - Emit the TLS intialization functions into a list.

Bill Wendling isanbard at gmail.com
Mon Apr 29 17:13:33 PDT 2013


On Apr 29, 2013, at 5:09 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> On Mon, Apr 29, 2013 at 3:27 PM, Bill Wendling <isanbard at gmail.com> wrote:
> Author: void
> Date: Mon Apr 29 17:27:16 2013
> New Revision: 180739
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=180739&view=rev
> Log:
> Emit the TLS intialization functions into a list.
> 
> Add the TLS initialization functions to a list of initialization functions. The
> back-end takes this list and places the function pointers into the correct
> section. This way they're called before `main().'
> 
> Why?

"Why" what? Just as the description says, we place the function pointers into the correct section and, at least on Darwin, the TLS variables are initialized via calls to the those function pointers. Just like global c'tors.

-bw

>  
> <rdar://problem/13733006>
> 
> Added:
>     cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp
> Modified:
>     cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
>     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>     cfe/trunk/lib/CodeGen/CodeGenModule.h
> 
> Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=180739&r1=180738&r2=180739&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Mon Apr 29 17:27:16 2013
> @@ -304,6 +304,7 @@ void CodeGenModule::EmitCXXThreadLocalIn
>      Guard->setThreadLocal(true);
>      CodeGenFunction(*this)
>          .GenerateCXXGlobalInitFunc(InitFn, CXXThreadLocalInits, Guard);
> +    AddTLSInitFunc(InitFn);
>    }
> 
>    getCXXABI().EmitThreadLocalInitFuncs(CXXThreadLocals, InitFn);
> 
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=180739&r1=180738&r2=180739&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Apr 29 17:27:16 2013
> @@ -182,6 +182,7 @@ void CodeGenModule::Release() {
>        AddGlobalCtor(ObjCInitFunction);
>    EmitCtorList(GlobalCtors, "llvm.global_ctors");
>    EmitCtorList(GlobalDtors, "llvm.global_dtors");
> +  EmitTLSList(TLSInitFuncs);
>    EmitGlobalAnnotations();
>    EmitStaticExternCAliases();
>    EmitLLVMUsed();
> @@ -479,6 +480,12 @@ void CodeGenModule::AddGlobalDtor(llvm::
>    GlobalDtors.push_back(std::make_pair(Dtor, Priority));
>  }
> 
> +/// AddTLSInitFunc - Add a function to the list that will initialize TLS
> +/// variables before main() runs.
> +void CodeGenModule::AddTLSInitFunc(llvm::Function *Init) {
> +  TLSInitFuncs.push_back(Init);
> +}
> +
>  void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
>    // Ctor function type is void()*.
>    llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false);
> @@ -507,6 +514,25 @@ void CodeGenModule::EmitCtorList(const C
>    }
>  }
> 
> +void CodeGenModule::EmitTLSList(ArrayRef<llvm::Constant*> Fns) {
> +  if (Fns.empty()) return;
> +
> +  // TLS init function types are void()*.
> +  llvm::FunctionType* TLSFTy = llvm::FunctionType::get(VoidTy, false);
> +  llvm::Type *TLSPFTy = llvm::PointerType::getUnqual(TLSFTy);
> +
> +  SmallVector<llvm::Constant*, 8> Inits;
> +  for (ArrayRef<llvm::Constant*>::iterator I = Fns.begin(),
> +         E = Fns.end(); I != E; ++I)
> +    Inits.push_back(llvm::ConstantExpr::getBitCast(*I, TLSPFTy));
> +
> +  llvm::ArrayType *AT = llvm::ArrayType::get(TLSPFTy, Inits.size());
> +  new llvm::GlobalVariable(TheModule, AT, false,
> +                           llvm::GlobalValue::AppendingLinkage,
> +                           llvm::ConstantArray::get(AT, Inits),
> +                           "llvm.tls_init_funcs");
> +}
> +
>  llvm::GlobalValue::LinkageTypes
>  CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
>    GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
> 
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=180739&r1=180738&r2=180739&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Apr 29 17:27:16 2013
> @@ -293,6 +293,10 @@ class CodeGenModule : public CodeGenType
>    /// priorities to be emitted when the translation unit is complete.
>    CtorList GlobalDtors;
> 
> +  /// TLSInitFuncs - Store the list of TLS initialization functions toe be
> +  /// emitted with the translation unit is complete.
> +  std::vector<llvm::Constant*> TLSInitFuncs;
> +
>    /// MangledDeclNames - A map of canonical GlobalDecls to their mangled names.
>    llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames;
>    llvm::BumpPtrAllocator MangledNamesAllocator;
> @@ -1053,11 +1057,18 @@ private:
>    void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535);
>    void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535);
> 
> +  void AddTLSInitFunc(llvm::Function *Init);
> +
>    /// EmitCtorList - Generates a global array of functions and priorities using
>    /// the given list and name. This array will have appending linkage and is
>    /// suitable for use as a LLVM constructor or destructor array.
>    void EmitCtorList(const CtorList &Fns, const char *GlobalName);
> 
> +  /// EmitTLSList - Generates a global array of functions with the name
> +  /// `llvm.tls_init_funcs'. This array will have appending linkage and is meant
> +  /// to hold initialization functions for TLS variables.
> +  void EmitTLSList(ArrayRef<llvm::Constant*> Fns);
> +
>    /// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the
>    /// given type.
>    void EmitFundamentalRTTIDescriptor(QualType Type);
> 
> Added: cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp?rev=180739&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp (added)
> +++ cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp Mon Apr 29 17:27:16 2013
> @@ -0,0 +1,21 @@
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -std=c++11 -S -emit-llvm %s -o - | FileCheck -check-prefix=BITCODE %s
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -std=c++11 -S %s -o - | FileCheck -check-prefix=ASM %s
> +
> +// BITCODE: @llvm.tls_init_funcs = appending global [1 x void ()*] [void ()* @__tls_init]
> +
> +struct A {
> +  A();
> +};
> +
> +struct B {
> +  int i;
> +  B(int i);
> +};
> +
> +thread_local int i = 37;
> +thread_local A a;
> +thread_local B b(927);
> +
> +// ASM: .section __DATA,__thread_init,thread_local_init_function_pointers
> +// ASM: .align 3
> +// ASM: .quad ___tls_init
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 





More information about the cfe-commits mailing list