From 14c6dfb89564dec95cdcd230279a58ad2f032eb8 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Fri, 5 Nov 2010 17:40:29 +0300 Subject: [PATCH] Added pointers to shared constructors and destructors to ModuleInfo. --- gen/functions.cpp | 12 ++++ gen/irstate.h | 4 ++ gen/toobj.cpp | 142 ++++++++++++++++++----------------------- runtime/CMakeLists.txt | 2 +- 4 files changed, 78 insertions(+), 82 deletions(-) diff --git a/gen/functions.cpp b/gen/functions.cpp index d1671f8c..3b149881 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -513,6 +513,18 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) gIR->dtors.push_back(fdecl); } } + // shared static ctor + else if (fdecl->isSharedStaticCtorDeclaration()) { + if (mustDefineSymbol(fdecl)) { + gIR->sharedCtors.push_back(fdecl); + } + } + // static dtor + else if (fdecl->isSharedStaticDtorDeclaration()) { + if (mustDefineSymbol(fdecl)) { + gIR->sharedDtors.push_back(fdecl); + } + } // we never reference parameters of function prototypes std::string str; diff --git a/gen/irstate.h b/gen/irstate.h index 1ab5a30c..2b2d91b9 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -163,6 +163,10 @@ struct IRState typedef std::vector FuncDeclVector; FuncDeclVector ctors; FuncDeclVector dtors; +#if DMDV2 + FuncDeclVector sharedCtors; + FuncDeclVector sharedDtors; +#endif FuncDeclVector unitTests; // all template instances that had members emitted diff --git a/gen/toobj.cpp b/gen/toobj.cpp index 850fd3e8..b82845a6 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -387,25 +387,14 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath) /* ================================================================== */ -// the following code generates functions and needs to output -// debug info. these macros are useful for that -#define DBG_TYPE ( getPtrToType(llvm::StructType::get(gIR->context(),NULL,NULL)) ) -#define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) - -// build module ctor - -llvm::Function* build_module_ctor() +static llvm::Function* build_module_function(const std::string &name, const std::vector &funcs) { - if (gIR->ctors.empty()) + if (funcs.empty()) return NULL; - size_t n = gIR->ctors.size(); + size_t n = funcs.size(); if (n == 1) - return gIR->ctors[0]->ir.irFunc->func; - - std::string name("_D"); - name.append(gIR->dmodule->mangle()); - name.append("6__ctorZ"); + return funcs[0]->ir.irFunc->func; std::vector argsTy; const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); @@ -423,7 +412,7 @@ llvm::Function* build_module_ctor() #endif for (size_t i=0; ictors[i]->ir.irFunc->func; + llvm::Function* f = funcs[i]->ir.irFunc->func; llvm::CallInst* call = builder.CreateCall(f,""); call->setCallingConv(DtoCallingConv(0, LINKd)); } @@ -432,87 +421,60 @@ llvm::Function* build_module_ctor() return fn; } +// build module ctor + +llvm::Function* build_module_ctor() +{ + std::string name("_D"); + name.append(gIR->dmodule->mangle()); + name.append("6__ctorZ"); + return build_module_function(name, gIR->ctors); +} + // build module dtor static llvm::Function* build_module_dtor() { - if (gIR->dtors.empty()) - return NULL; - - size_t n = gIR->dtors.size(); - if (n == 1) - return gIR->dtors[0]->ir.irFunc->func; - std::string name("_D"); name.append(gIR->dmodule->mangle()); name.append("6__dtorZ"); - - std::vector argsTy; - const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); - assert(gIR->module->getFunction(name) == NULL); - llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); - fn->setCallingConv(DtoCallingConv(0, LINKd)); - - llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); - IRBuilder<> builder(bb); - - #ifndef DISABLE_DEBUG_INFO - // debug info - if(global.params.symdebug) - DtoDwarfSubProgramInternal(name.c_str(), name.c_str()); - #endif - - for (size_t i=0; idtors[i]->ir.irFunc->func; - llvm::CallInst* call = builder.CreateCall(f,""); - call->setCallingConv(DtoCallingConv(0, LINKd)); - } - - builder.CreateRetVoid(); - return fn; + return build_module_function(name, gIR->dtors); } // build module unittest static llvm::Function* build_module_unittest() { - if (gIR->unitTests.empty()) - return NULL; - - size_t n = gIR->unitTests.size(); - if (n == 1) - return gIR->unitTests[0]->ir.irFunc->func; - std::string name("_D"); name.append(gIR->dmodule->mangle()); name.append("10__unittestZ"); - - std::vector argsTy; - const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); - assert(gIR->module->getFunction(name) == NULL); - llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); - fn->setCallingConv(DtoCallingConv(0, LINKd)); - - llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); - IRBuilder<> builder(bb); - - #ifndef DISABLE_DEBUG_INFO - // debug info - llvm::DISubprogram subprog; - if(global.params.symdebug) - subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()); - #endif - - for (size_t i=0; iunitTests[i]->ir.irFunc->func; - llvm::CallInst* call = builder.CreateCall(f,""); - call->setCallingConv(DtoCallingConv(0, LINKd)); - } - - builder.CreateRetVoid(); - return fn; + return build_module_function(name, gIR->unitTests); } +#if DMDV2 + +// build module shared ctor + +llvm::Function* build_module_shared_ctor() +{ + std::string name("_D"); + name.append(gIR->dmodule->mangle()); + name.append("13__shared_ctorZ"); + return build_module_function(name, gIR->sharedCtors); +} + +// build module shared dtor + +static llvm::Function* build_module_shared_dtor() +{ + std::string name("_D"); + name.append(gIR->dmodule->mangle()); + name.append("13__shared_dtorZ"); + return build_module_function(name, gIR->sharedDtors); +} + +#endif + // build ModuleReference and register function, to register the module info in the global linked list static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo) { @@ -722,12 +684,20 @@ void Module::genmoduleinfo() const LLType* fnptrTy = getPtrToType(LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false)); // ctor +#if DMDV2 + llvm::Function* fctor = build_module_shared_ctor(); +#else llvm::Function* fctor = build_module_ctor(); +#endif c = fctor ? fctor : getNullValue(fnptrTy); b.push(c); // dtor +#if DMDV2 + llvm::Function* fdtor = build_module_shared_dtor(); +#else llvm::Function* fdtor = build_module_dtor(); +#endif c = fdtor ? fdtor : getNullValue(fnptrTy); b.push(c); @@ -746,8 +716,18 @@ void Module::genmoduleinfo() #if DMDV2 - // void*[4] reserved :/ - const LLType* AT = llvm::ArrayType::get(getVoidPtrType(), 4); + // tls ctor + fctor = build_module_ctor(); + c = fctor ? fctor : getNullValue(fnptrTy); + b.push(c); + + // tls dtor + fdtor = build_module_dtor(); + c = fdtor ? fdtor : getNullValue(fnptrTy); + b.push(c); + + // index + reserved void*[1] + const LLType* AT = llvm::ArrayType::get(getVoidPtrType(), 2); c = getNullValue(AT); b.push(c); diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 7e73bada..b9da4ca4 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -187,7 +187,7 @@ macro(dc INPUT_D OUTLIST_O OUTLIST_BC INCDIR MOREFLAGS PATH) OUTPUT ${OUTPUT_O} ${OUTPUT_BC} - COMMAND ${LDC_LOC} --output-o --output-bc -c -I${INCDIR} -I${RUNTIME_GC_DIR} ${INPUT_D} -of${OUTPUT_O} ${D_FLAGS} ${MOREFLAGS} + COMMAND ${LDC_LOC} --output-o --output-bc -c -I${INCDIR} -I${RUNTIME_GC_DIR} ${INPUT_D} -of${OUTPUT_O} ${D_FLAGS} ${MOREFLAGS} --unittest DEPENDS ${LDC_LOC} ${INPUT_D} ${LDC_IMPORTS}