Added pointers to shared constructors and destructors to ModuleInfo.

This commit is contained in:
Alexey Prokhin 2010-11-05 17:40:29 +03:00
parent 171ef1695c
commit 14c6dfb895
4 changed files with 78 additions and 82 deletions

View file

@ -513,6 +513,18 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
gIR->dtors.push_back(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 // we never reference parameters of function prototypes
std::string str; std::string str;

View file

@ -163,6 +163,10 @@ struct IRState
typedef std::vector<FuncDeclaration*> FuncDeclVector; typedef std::vector<FuncDeclaration*> FuncDeclVector;
FuncDeclVector ctors; FuncDeclVector ctors;
FuncDeclVector dtors; FuncDeclVector dtors;
#if DMDV2
FuncDeclVector sharedCtors;
FuncDeclVector sharedDtors;
#endif
FuncDeclVector unitTests; FuncDeclVector unitTests;
// all template instances that had members emitted // all template instances that had members emitted

View file

@ -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 static llvm::Function* build_module_function(const std::string &name, const std::vector<FuncDeclaration*> &funcs)
// 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()
{ {
if (gIR->ctors.empty()) if (funcs.empty())
return NULL; return NULL;
size_t n = gIR->ctors.size(); size_t n = funcs.size();
if (n == 1) if (n == 1)
return gIR->ctors[0]->ir.irFunc->func; return funcs[0]->ir.irFunc->func;
std::string name("_D");
name.append(gIR->dmodule->mangle());
name.append("6__ctorZ");
std::vector<const LLType*> argsTy; std::vector<const LLType*> argsTy;
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false);
@ -423,7 +412,7 @@ llvm::Function* build_module_ctor()
#endif #endif
for (size_t i=0; i<n; i++) { for (size_t i=0; i<n; i++) {
llvm::Function* f = gIR->ctors[i]->ir.irFunc->func; llvm::Function* f = funcs[i]->ir.irFunc->func;
llvm::CallInst* call = builder.CreateCall(f,""); llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(DtoCallingConv(0, LINKd)); call->setCallingConv(DtoCallingConv(0, LINKd));
} }
@ -432,87 +421,60 @@ llvm::Function* build_module_ctor()
return fn; 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 // build module dtor
static llvm::Function* 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"); std::string name("_D");
name.append(gIR->dmodule->mangle()); name.append(gIR->dmodule->mangle());
name.append("6__dtorZ"); name.append("6__dtorZ");
return build_module_function(name, gIR->dtors);
std::vector<const LLType*> 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; i<n; i++) {
llvm::Function* f = gIR->dtors[i]->ir.irFunc->func;
llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(DtoCallingConv(0, LINKd));
}
builder.CreateRetVoid();
return fn;
} }
// build module unittest // build module unittest
static llvm::Function* 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"); std::string name("_D");
name.append(gIR->dmodule->mangle()); name.append(gIR->dmodule->mangle());
name.append("10__unittestZ"); name.append("10__unittestZ");
return build_module_function(name, gIR->unitTests);
std::vector<const LLType*> 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; i<n; i++) {
llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func;
llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(DtoCallingConv(0, LINKd));
}
builder.CreateRetVoid();
return fn;
} }
#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 // build ModuleReference and register function, to register the module info in the global linked list
static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo) 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<const LLType*>(), false)); const LLType* fnptrTy = getPtrToType(LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<const LLType*>(), false));
// ctor // ctor
#if DMDV2
llvm::Function* fctor = build_module_shared_ctor();
#else
llvm::Function* fctor = build_module_ctor(); llvm::Function* fctor = build_module_ctor();
#endif
c = fctor ? fctor : getNullValue(fnptrTy); c = fctor ? fctor : getNullValue(fnptrTy);
b.push(c); b.push(c);
// dtor // dtor
#if DMDV2
llvm::Function* fdtor = build_module_shared_dtor();
#else
llvm::Function* fdtor = build_module_dtor(); llvm::Function* fdtor = build_module_dtor();
#endif
c = fdtor ? fdtor : getNullValue(fnptrTy); c = fdtor ? fdtor : getNullValue(fnptrTy);
b.push(c); b.push(c);
@ -746,8 +716,18 @@ void Module::genmoduleinfo()
#if DMDV2 #if DMDV2
// void*[4] reserved :/ // tls ctor
const LLType* AT = llvm::ArrayType::get(getVoidPtrType(), 4); 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); c = getNullValue(AT);
b.push(c); b.push(c);

View file

@ -187,7 +187,7 @@ macro(dc INPUT_D OUTLIST_O OUTLIST_BC INCDIR MOREFLAGS PATH)
OUTPUT OUTPUT
${OUTPUT_O} ${OUTPUT_O}
${OUTPUT_BC} ${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} DEPENDS ${LDC_LOC}
${INPUT_D} ${INPUT_D}
${LDC_IMPORTS} ${LDC_IMPORTS}