# HG changeset patch # User Tomas Lindquist Olsen # Date 1233769683 -3600 # Node ID 39519a1ff603a7d71a7357e07c0c094a9c8ceb71 # Parent cac9895be400c788bb24f298aaa1aa899273cb18 Changed the way LDC determines if a template instantiation needs to get a definition, seems to speed up compile times quite a bit in some cases. diff -r cac9895be400 -r 39519a1ff603 dmd/template.c --- a/dmd/template.c Wed Feb 04 18:39:39 2009 +0100 +++ b/dmd/template.c Wed Feb 04 18:48:03 2009 +0100 @@ -2901,7 +2901,10 @@ this->havetempdecl = 1; this->isnested = NULL; this->errors = 0; + + // LDC this->tinst = NULL; + this->tmodule = NULL; assert((size_t)tempdecl->scope > 0x10000); } @@ -2979,6 +2982,7 @@ // get the enclosing template instance from the scope tinst tinst = sc->tinst; + tmodule = sc->module; #if LOG printf("\tdo semantic\n"); diff -r cac9895be400 -r 39519a1ff603 dmd/template.h --- a/dmd/template.h Wed Feb 04 18:39:39 2009 +0100 +++ b/dmd/template.h Wed Feb 04 18:48:03 2009 +0100 @@ -326,6 +326,7 @@ // LDC TemplateInstance *tinst; // enclosing template instance + Module* tmodule; // module from outermost enclosing template instantiation void printInstantiationTrace(); }; diff -r cac9895be400 -r 39519a1ff603 gen/classes.cpp --- a/gen/classes.cpp Wed Feb 04 18:39:39 2009 +0100 +++ b/gen/classes.cpp Wed Feb 04 18:48:03 2009 +0100 @@ -324,7 +324,7 @@ gIR->constInitList.push_back(cd); // emit typeinfo and request definition - if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) + if (mustDefineSymbol(cd)) { gIR->defineList.push_back(cd); DtoTypeInfoOf(cd->type, false); @@ -360,7 +360,7 @@ gIR->structs.push_back(irstruct); bool needs_definition = false; - if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) { + if (mustDefineSymbol(cd)) { needs_definition = true; } @@ -821,7 +821,7 @@ DefineInterfaceInfos(cd->ir.irStruct); // define the classinfo - if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) + if (mustDefineSymbol(cd)) { DtoDefineClassInfo(cd); } @@ -851,7 +851,7 @@ IrStruct* irstruct = cd->ir.irStruct; - assert(cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)); + assert(mustDefineSymbol(cd)); // sanity check assert(irstruct->init); diff -r cac9895be400 -r 39519a1ff603 gen/functions.cpp --- a/gen/functions.cpp Wed Feb 04 18:39:39 2009 +0100 +++ b/gen/functions.cpp Wed Feb 04 18:48:03 2009 +0100 @@ -486,20 +486,9 @@ Type* t = fdecl->type->toBasetype(); TypeFunction* f = (TypeFunction*)t; - bool declareOnly = false; - bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent); - if (!templInst && fdecl->getModule() != gIR->dmodule) - { - Logger::println("not template instance, and not in this module. declare only!"); - Logger::println("current module: %s", gIR->dmodule->ident->toChars()); - if(fdecl->getModule()) - Logger::println("func module: %s", fdecl->getModule()->ident->toChars()); - else { - Logger::println("func not in a module, is runtime"); - } - declareOnly = true; - } - else if (fdecl->llvmInternal == LLVMva_start) + bool declareOnly = !mustDefineSymbol(fdecl); + + if (fdecl->llvmInternal == LLVMva_start) declareOnly = true; if (!fdecl->ir.irFunc) { @@ -668,9 +657,8 @@ llvm::Function* func = fd->ir.irFunc->func; const llvm::FunctionType* functype = func->getFunctionType(); - // only members of the current module or template instances maybe be defined - if (!(fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent))) - return; + // sanity check + assert(mustDefineSymbol(fd)); // set module owner fd->ir.DModule = gIR->dmodule; diff -r cac9895be400 -r 39519a1ff603 gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Wed Feb 04 18:39:39 2009 +0100 +++ b/gen/llvmhelpers.cpp Wed Feb 04 18:48:03 2009 +0100 @@ -831,15 +831,14 @@ // TEMPLATE HELPERS ////////////////////////////////////////////////////////////////////////////////////////*/ -// FIXME: when is this the right one to use instead of Dsymbol::inTemplateInstance() ? -bool DtoIsTemplateInstance(Dsymbol* s) +Module* DtoIsTemplateInstance(Dsymbol* s) { - if (!s) return false; + if (!s) return NULL; if (s->isTemplateInstance() && !s->isTemplateMixin()) - return true; + return s->isTemplateInstance()->tmodule; else if (s->parent) return DtoIsTemplateInstance(s->parent); - return false; + return NULL; } /****************************************************************************************/ @@ -958,15 +957,10 @@ assert(!glob->constInit); glob->constInit = initVal; - bool istempl = false; - if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) { - istempl = true; - } - // assign the initializer llvm::GlobalVariable* globalvar = llvm::cast(glob->value); - if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) + if (!(vd->storage_class & STCextern) && mustDefineSymbol(vd)) { if (Logger::enabled()) { @@ -1559,3 +1553,27 @@ Logger::println("final intrinsic name: %s", name.c_str()); } + +////////////////////////////////////////////////////////////////////////////////////////// + +bool mustDefineSymbol(Dsymbol* s) +{ + Module* M = DtoIsTemplateInstance(s); + // if it's a template instance, check the instantiating module + // not the module that defines the template + if (M) + return M == gIR->dmodule; + return s->getModule() == gIR->dmodule; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +bool needsTemplateLinkage(Dsymbol* s) +{ + Module* M = DtoIsTemplateInstance(s); + // only return true if the symbol is a template instances + // and if this instance originated in the current module + if (M) + return M == gIR->dmodule; + return false; +} diff -r cac9895be400 -r 39519a1ff603 gen/llvmhelpers.h --- a/gen/llvmhelpers.h Wed Feb 04 18:39:39 2009 +0100 +++ b/gen/llvmhelpers.h Wed Feb 04 18:48:03 2009 +0100 @@ -61,8 +61,8 @@ // return the same val as passed in, modified to the target type, if possible, otherwise returns a new DValue DValue* DtoPaintType(Loc& loc, DValue* val, Type* to); -// is template instance check -bool DtoIsTemplateInstance(Dsymbol* s); +// is template instance check, returns module where instantiated +Module* DtoIsTemplateInstance(Dsymbol* s); // these are all basically drivers for the codegeneration called by the main loop void DtoResolveDsymbol(Dsymbol* dsym); @@ -108,6 +108,12 @@ // fixup an overloaded intrinsic name string void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, std::string& name); +// return true if the symbol should be defined in the current module, not just declared +bool mustDefineSymbol(Dsymbol* s); + +// returns true if the symbol needs template linkage, or just external +bool needsTemplateLinkage(Dsymbol* s); + //////////////////////////////////////////// // gen/tocall.cpp stuff below //////////////////////////////////////////// diff -r cac9895be400 -r 39519a1ff603 gen/structs.cpp --- a/gen/structs.cpp Wed Feb 04 18:39:39 2009 +0100 +++ b/gen/structs.cpp Wed Feb 04 18:48:03 2009 +0100 @@ -607,7 +607,7 @@ sd->ir.irStruct->init = initvar; gIR->constInitList.push_back(sd); - if (DtoIsTemplateInstance(sd) || sd->getModule() == gIR->dmodule) + if (mustDefineSymbol(sd)) gIR->defineList.push_back(sd); } diff -r cac9895be400 -r 39519a1ff603 gen/tollvm.cpp --- a/gen/tollvm.cpp Wed Feb 04 18:39:39 2009 +0100 +++ b/gen/tollvm.cpp Wed Feb 04 18:48:03 2009 +0100 @@ -275,7 +275,7 @@ if (VarDeclaration* vd = sym->isVarDeclaration()) { // template - if (DtoIsTemplateInstance(sym)) + if (needsTemplateLinkage(sym)) return TEMPLATE_LINKAGE_TYPE; // local static else if (sym->parent && sym->parent->isFuncDeclaration()) @@ -296,7 +296,7 @@ // template instances should have weak linkage // but only if there's a body, and it's not naked // otherwise we make it external - else if (DtoIsTemplateInstance(fdecl) && fdecl->fbody && !fdecl->naked) + else if (needsTemplateLinkage(fdecl) && fdecl->fbody && !fdecl->naked) return TEMPLATE_LINKAGE_TYPE; // extern(C) functions are always external else if (ft->linkage == LINKc) @@ -306,7 +306,7 @@ else if (ClassDeclaration* cd = sym->isClassDeclaration()) { // template - if (DtoIsTemplateInstance(cd)) + if (needsTemplateLinkage(cd)) return TEMPLATE_LINKAGE_TYPE; } else @@ -320,7 +320,7 @@ llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym) { - if (DtoIsTemplateInstance(sym)) + if (needsTemplateLinkage(sym)) return TEMPLATE_LINKAGE_TYPE; else return llvm::GlobalValue::InternalLinkage; @@ -328,7 +328,7 @@ llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym) { - if (DtoIsTemplateInstance(sym)) + if (needsTemplateLinkage(sym)) return TEMPLATE_LINKAGE_TYPE; else return llvm::GlobalValue::ExternalLinkage;