aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-05-23 21:13:45 +0000
committerReid Kleckner <reid@kleckner.net>2014-05-23 21:13:45 +0000
commit563f0e852c5002ff177aa73802b543d5e3781388 (patch)
tree0c4b207fb3ca3b86cf291fc5f4c88f08d5c15cdd /clang/lib/CodeGen/CodeGenModule.cpp
parent2f75351c02a32592f5c0f2af3a2ab10cf12cdb07 (diff)
downloadllvm-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.cpp22
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));
}