r180739 - Emit the TLS intialization functions into a list.

Richard Smith richard at metafoo.co.uk
Mon Apr 29 17:18:30 PDT 2013


On Mon, Apr 29, 2013 at 5:13 PM, Bill Wendling <isanbard at gmail.com> wrote:

> 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.


OK, but why are we switching to eagerly initializing them rather than doing
it lazily? That's going to be extremely expensive for applications which
start lots of threads (say, by using std::async) and have thread_local
variables with non-trivial construction or destruction -- and we still emit
the dynamic initialization on every odr-use, so it doesn't seem to save us
anything.


> -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
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130429/aa7000e8/attachment.html>


More information about the cfe-commits mailing list