From 75591b3c16af239a29a95e33772b310676dadd18 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Mon, 2 Feb 2009 01:44:51 +0100 Subject: [PATCH] Changed templates and typeinfo to use linkonce linkage instead of weak linkage, this should fix inlining problems, fixing bug #197 . If problems show up, it's easy to change it back by changing the define in mars.h . I'm 95% sure this is safe, given how we handle templates. --- dmd/mars.h | 4 ++++ dmd2/mars.h | 4 ++++ gen/llvmhelpers.cpp | 2 +- gen/toir.cpp | 4 ++-- gen/tollvm.cpp | 10 +++++----- gen/typinf.cpp | 20 ++++++++++---------- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/dmd/mars.h b/dmd/mars.h index 0c9466eb..b89db075 100644 --- a/dmd/mars.h +++ b/dmd/mars.h @@ -65,6 +65,10 @@ enum OS OSSolaris, }; +// make it easier to test new linkage types +#define TEMPLATE_LINKAGE_TYPE llvm::GlobalValue::LinkOnceLinkage +#define TYPEINFO_LINKAGE_TYPE llvm::GlobalValue::LinkOnceLinkage + // Put command line switches in here struct Param { diff --git a/dmd2/mars.h b/dmd2/mars.h index a79e8944..ac17edda 100644 --- a/dmd2/mars.h +++ b/dmd2/mars.h @@ -65,6 +65,10 @@ enum OS OSSolaris, }; +// make it easier to test new linkage types +#define TEMPLATE_LINKAGE_TYPE llvm::GlobalValue::LinkOnceLinkage +#define TYPEINFO_LINKAGE_TYPE llvm::GlobalValue::LinkOnceLinkage + // Put command line switches in here struct Param { diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 4e821ca8..99195f3a 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -844,7 +844,7 @@ bool DtoIsTemplateInstance(Dsymbol* s) void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t) { // create a flag to make sure initialization only happens once - llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage; + llvm::GlobalValue::LinkageTypes gflaglink = istempl ? TEMPLATE_LINKAGE_TYPE : llvm::GlobalValue::InternalLinkage; std::string gflagname(gvar->getName()); gflagname.append("__initflag"); llvm::GlobalVariable* gflag = new llvm::GlobalVariable(LLType::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,gIR->module); diff --git a/gen/toir.cpp b/gen/toir.cpp index 7af6e3f9..197e1f79 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -391,7 +391,7 @@ DValue* StringExp::toElem(IRState* p) else assert(0); - llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; + llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage; if (Logger::enabled()) Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".str",gIR->module); @@ -467,7 +467,7 @@ LLConstant* StringExp::toConstElem(IRState* p) return _init; } - llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; + llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage; llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".str",gIR->module); llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 1f98e2c9..d686e0f1 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -276,7 +276,7 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) { // template if (DtoIsTemplateInstance(sym)) - return llvm::GlobalValue::WeakLinkage; + return TEMPLATE_LINKAGE_TYPE; // local static else if (sym->parent && sym->parent->isFuncDeclaration()) return llvm::GlobalValue::InternalLinkage; @@ -296,7 +296,7 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) // template instances should have weak linkage // but only if there's a body, otherwise we make it external else if (DtoIsTemplateInstance(fdecl) && fdecl->fbody) - return llvm::GlobalValue::WeakLinkage; + return TEMPLATE_LINKAGE_TYPE; // extern(C) functions are always external else if (ft->linkage == LINKc) return llvm::GlobalValue::ExternalLinkage; @@ -306,7 +306,7 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) { // template if (DtoIsTemplateInstance(cd)) - return llvm::GlobalValue::WeakLinkage; + return TEMPLATE_LINKAGE_TYPE; } else { @@ -320,7 +320,7 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym) { if (DtoIsTemplateInstance(sym)) - return llvm::GlobalValue::WeakLinkage; + return TEMPLATE_LINKAGE_TYPE; else return llvm::GlobalValue::InternalLinkage; } @@ -328,7 +328,7 @@ llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym) llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym) { if (DtoIsTemplateInstance(sym)) - return llvm::GlobalValue::WeakLinkage; + return TEMPLATE_LINKAGE_TYPE; else return llvm::GlobalValue::ExternalLinkage; } diff --git a/gen/typinf.cpp b/gen/typinf.cpp index bc4ecc96..b6c444df 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -379,7 +379,7 @@ void TypeInfoTypedefDeclaration::llvmDeclare() const LLStructType* stype = isaStruct(base->type->ir.type->get()); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoTypedefDeclaration::llvmDefine() @@ -453,7 +453,7 @@ void TypeInfoEnumDeclaration::llvmDeclare() DtoResolveClass(base); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoEnumDeclaration::llvmDefine() @@ -528,7 +528,7 @@ static void LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, ClassDeclarati DtoResolveClass(base); // create the symbol - tid->ir.irGlobal->value = new llvm::GlobalVariable(tid->ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module); + tid->ir.irGlobal->value = new llvm::GlobalVariable(tid->ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, tid->toChars(), gIR->module); } static void LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd) @@ -627,7 +627,7 @@ void TypeInfoStaticArrayDeclaration::llvmDeclare() DtoResolveClass(base); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoStaticArrayDeclaration::llvmDefine() @@ -687,7 +687,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDeclare() DtoResolveClass(base); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoAssociativeArrayDeclaration::llvmDefine() @@ -808,7 +808,7 @@ void TypeInfoStructDeclaration::llvmDeclare() DtoResolveClass(base); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoStructDeclaration::llvmDefine() @@ -1024,7 +1024,7 @@ void TypeInfoClassDeclaration::llvmDeclare() DtoResolveClass(base); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, llvm::GlobalValue::WeakLinkage, NULL, toChars(), gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoClassDeclaration::llvmDefine() @@ -1080,7 +1080,7 @@ void TypeInfoInterfaceDeclaration::llvmDeclare() DtoResolveClass(base); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoInterfaceDeclaration::llvmDefine() @@ -1138,7 +1138,7 @@ void TypeInfoTupleDeclaration::llvmDeclare() DtoResolveClass(base); // create the symbol - ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module); + ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module); } void TypeInfoTupleDeclaration::llvmDefine() @@ -1185,7 +1185,7 @@ void TypeInfoTupleDeclaration::llvmDefine() LLConstant* arrC = llvm::ConstantArray::get(arrTy, arrInits); // need the pointer to the first element of arrC, so create a global for it - llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; + llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage; llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,_linkage,arrC,".tupleelements",gIR->module); // get pointer to first element