On Mon, Apr 29, 2013 at 3:27 PM, Bill Wendling <[email protected]> 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? > <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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
