diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-05-23 21:13:45 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-05-23 21:13:45 +0000 |
commit | 563f0e852c5002ff177aa73802b543d5e3781388 (patch) | |
tree | 0c4b207fb3ca3b86cf291fc5f4c88f08d5c15cdd /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 2f75351c02a32592f5c0f2af3a2ab10cf12cdb07 (diff) | |
download | llvm-563f0e852c5002ff177aa73802b543d5e3781388.zip llvm-563f0e852c5002ff177aa73802b543d5e3781388.tar.gz llvm-563f0e852c5002ff177aa73802b543d5e3781388.tar.bz2 |
Use comdats to avoid double initialization of weak data
Initializers of global data that can appear multiple TUs (static data
members of class templates or __declspec(selectany) data) are now in a
comdat group keyed on the global variable being initialized. On
non-Windows platforms, this is a code size and startup time
optimization. On Windows, this is necessary for ABI compatibility with
MSVC.
Fixes PR16959.
Reviewers: rsmith
Differential Revision: http://reviews.llvm.org/D3811
llvm-svn: 209555
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0d781fd..9e8401d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -511,16 +511,17 @@ llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) { /// AddGlobalCtor - Add a function to the list that will be called before /// main() runs. -void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor, int Priority) { +void CodeGenModule::AddGlobalCtor(llvm::Function *Ctor, int Priority, + llvm::Constant *AssociatedData) { // FIXME: Type coercion of void()* types. - GlobalCtors.push_back(std::make_pair(Ctor, Priority)); + GlobalCtors.push_back(Structor(Priority, Ctor, AssociatedData)); } /// AddGlobalDtor - Add a function to the list that will be called /// when the module is unloaded. -void CodeGenModule::AddGlobalDtor(llvm::Function * Dtor, int Priority) { +void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority) { // FIXME: Type coercion of void()* types. - GlobalDtors.push_back(std::make_pair(Dtor, Priority)); + GlobalDtors.push_back(Structor(Priority, Dtor, 0)); } void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) { @@ -528,16 +529,19 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) { llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false); llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy); - // Get the type of a ctor entry, { i32, void ()* }. - llvm::StructType *CtorStructTy = - llvm::StructType::get(Int32Ty, llvm::PointerType::getUnqual(CtorFTy), NULL); + // Get the type of a ctor entry, { i32, void ()*, i8* }. + llvm::StructType *CtorStructTy = llvm::StructType::get( + Int32Ty, llvm::PointerType::getUnqual(CtorFTy), VoidPtrTy, NULL); // Construct the constructor and destructor arrays. SmallVector<llvm::Constant*, 8> Ctors; for (CtorList::const_iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) { llvm::Constant *S[] = { - llvm::ConstantInt::get(Int32Ty, I->second, false), - llvm::ConstantExpr::getBitCast(I->first, CtorPFTy) + llvm::ConstantInt::get(Int32Ty, I->Priority, false), + llvm::ConstantExpr::getBitCast(I->Initializer, CtorPFTy), + (I->AssociatedData + ? llvm::ConstantExpr::getBitCast(I->AssociatedData, VoidPtrTy) + : llvm::Constant::getNullValue(VoidPtrTy)) }; Ctors.push_back(llvm::ConstantStruct::get(CtorStructTy, S)); } |