Mercurial > projects > ldc
changeset 323:0d52412d5b1a trunk
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
Changed the way moduleinfo is registered to use the same approach as DMD, this eliminates the need for correct linking order and should make the way for using a natively compiled runtime library. This should speed up linking tremendously and should now be possible.
Fixed the llvm.used array to only be emitted if really necessary.
author | lindquist |
---|---|
date | Wed, 09 Jul 2008 23:43:51 +0200 |
parents | 1aaf6ff7f685 |
children | c542d12017e5 |
files | dmd/mars.c gen/irstate.cpp gen/irstate.h gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp tango/lib/compiler/llvmdc/genobj.d tango/lib/compiler/llvmdc/llvmdc.mak tango/lib/compiler/llvmdc/moduleinfo.ll tango/lib/llvmdc.conf |
diffstat | 10 files changed, 129 insertions(+), 60 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/mars.c Wed Jul 09 17:02:55 2008 +0200 +++ b/dmd/mars.c Wed Jul 09 23:43:51 2008 +0200 @@ -161,7 +161,7 @@ D Language Documentation: http://www.digitalmars.com/d/1.0/index.html\n\ LLVMDC Homepage: http://www.dsource.org/projects/llvmdc\n\ Usage:\n\ - dmd files.d ... { -switch }\n\ + llvmdc files.d ... { -switch }\n\ \n\ files.d D source files\n%s\ -annotate annotate the bitcode with human readable source code\n\ @@ -188,8 +188,8 @@ -J<path> where to look for string imports\n\ -ignore ignore unsupported pragmas\n\ -inline do function inlining\n\ - -Llinkerflag pass linkerflag to llvm-ld\n\ - -m<arch> emit code specific to <arch>\n\ + -L<linkerflag> pass <linkerflag> to llvm-ld\n\ + -m<arch> emit code specific to <arch> being one of:\n\ x86 x86-64 ppc32 ppc64\n\ -noasm do not allow use of inline asm\n\ -nofloat do not emit reference to floating point\n\ @@ -199,12 +199,12 @@ -O<n> optimize at level <n> (0-5)\n\ -o- do not write object file\n\ -od<objdir> write object files to directory <objdir>\n\ - -of<filename> name output file to <filename>\n\ + -of<filename> name output file to <filename>\n\ -op do not strip paths from source file\n\ -oq write object files with fully qualified names\n\ - -profile profile runtime performance of generated code\n\ + -profile profile runtime performance of generated code\n\ -quiet suppress unnecessary messages\n\ - -release compile release version\n\ + -release compile release version\n\ -run srcfile args... run resulting program, passing args\n\ -R<path> provide path to the directory containing the runtime library\n\ -unittest compile in unit tests\n\
--- a/gen/irstate.cpp Wed Jul 09 17:02:55 2008 +0200 +++ b/gen/irstate.cpp Wed Jul 09 23:43:51 2008 +0200 @@ -51,6 +51,7 @@ { interfaceInfoType = NULL; mutexType = NULL; + moduleRefType = NULL; dmodule = 0; module = 0;
--- a/gen/irstate.h Wed Jul 09 17:02:55 2008 +0200 +++ b/gen/irstate.h Wed Jul 09 23:43:51 2008 +0200 @@ -137,6 +137,7 @@ // interface info type, used in DtoInterfaceInfoType const LLStructType* interfaceInfoType; const LLStructType* mutexType; + const LLStructType* moduleRefType; // functions typedef std::vector<IrFunction*> FunctionVector;
--- a/gen/tollvm.cpp Wed Jul 09 17:02:55 2008 +0200 +++ b/gen/tollvm.cpp Wed Jul 09 23:43:51 2008 +0200 @@ -6,6 +6,7 @@ #include "aggregate.h" #include "declaration.h" #include "init.h" +#include "module.h" #include "gen/tollvm.h" #include "gen/irstate.h" @@ -724,3 +725,30 @@ gIR->module->addTypeName("D_CRITICAL_SECTION", pmutex); return pmutex; } + +////////////////////////////////////////////////////////////////////////////////////////// + +const LLStructType* DtoModuleReferenceType() +{ + if (gIR->moduleRefType) + return gIR->moduleRefType; + + // this is a recursive type so start out with the opaque + LLOpaqueType* opaque = LLOpaqueType::get(); + + // add members + std::vector<const LLType*> types; + types.push_back(getPtrToType(opaque)); + types.push_back(DtoType(Module::moduleinfo->type)); + + // resolve type + const LLStructType* st = LLStructType::get(types); + LLPATypeHolder pa(st); + opaque->refineAbstractTypeTo(pa.get()); + st = isaStruct(pa.get()); + + // done + gIR->moduleRefType = st; + gIR->module->addTypeName("ModuleReference", st); + return st; +}
--- a/gen/tollvm.h Wed Jul 09 17:02:55 2008 +0200 +++ b/gen/tollvm.h Wed Jul 09 23:43:51 2008 +0200 @@ -40,6 +40,7 @@ const LLType* DtoSize_t(); const LLStructType* DtoInterfaceInfoType(); const LLStructType* DtoMutexType(); +const LLStructType* DtoModuleReferenceType(); // getelementptr helpers LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=NULL, llvm::BasicBlock* bb=NULL);
--- a/gen/toobj.cpp Wed Jul 09 17:02:55 2008 +0200 +++ b/gen/toobj.cpp Wed Jul 09 23:43:51 2008 +0200 @@ -131,10 +131,13 @@ DtoEmptyAllLists(); // emit usedArray - const LLArrayType* usedTy = LLArrayType::get(getVoidPtrType(), ir.usedArray.size()); - LLConstant* usedInit = LLConstantArray::get(usedTy, ir.usedArray); - LLGlobalVariable* usedArray = new LLGlobalVariable(usedTy, true, LLGlobalValue::AppendingLinkage, usedInit, "llvm.used", ir.module); - usedArray->setSection("llvm.metadata"); + if (!ir.usedArray.empty()) + { + const LLArrayType* usedTy = LLArrayType::get(getVoidPtrType(), ir.usedArray.size()); + LLConstant* usedInit = LLConstantArray::get(usedTy, ir.usedArray); + LLGlobalVariable* usedArray = new LLGlobalVariable(usedTy, true, LLGlobalValue::AppendingLinkage, usedInit, "llvm.used", ir.module); + usedArray->setSection("llvm.metadata"); + } // verify the llvm if (!global.params.novalidate) { @@ -296,6 +299,56 @@ return fn; } +// build ModuleReference and register function, to register the module info in the global linked list +static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo) +{ + // build ctor type + const LLFunctionType* fty = LLFunctionType::get(LLType::VoidTy, std::vector<const LLType*>(), false); + + // build ctor name + std::string fname = gIR->dmodule->mangle(); + fname += "16__moduleinfoCtorZ"; + + // build a function that registers the moduleinfo in the global moduleinfo linked list + LLFunction* ctor = LLFunction::Create(fty, LLGlobalValue::InternalLinkage, fname, gIR->module); + + // provide the default initializer + const LLStructType* modulerefTy = DtoModuleReferenceType(); + std::vector<LLConstant*> mrefvalues; + mrefvalues.push_back(LLConstant::getNullValue(modulerefTy->getContainedType(0))); + mrefvalues.push_back(moduleinfo); + LLConstant* thismrefinit = LLConstantStruct::get(modulerefTy, mrefvalues); + + // create the ModuleReference node for this module + std::string thismrefname = gIR->dmodule->mangle(); + thismrefname += "11__moduleRefZ"; + LLGlobalVariable* thismref = new LLGlobalVariable(modulerefTy, false, LLGlobalValue::InternalLinkage, thismrefinit, thismrefname, gIR->module); + + // make sure _Dmodule_ref is declared + LLGlobalVariable* mref = gIR->module->getNamedGlobal("_Dmodule_ref"); + if (!mref) + mref = new LLGlobalVariable(getPtrToType(modulerefTy), false, LLGlobalValue::ExternalLinkage, NULL, "_Dmodule_ref", gIR->module); + + // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list + llvm::BasicBlock* bb = llvm::BasicBlock::Create("moduleinfoCtorEntry", ctor); + IRBuilder builder(bb); + + // get current beginning + LLValue* curbeg = builder.CreateLoad(mref, "current"); + + // put current beginning as the next of this one + LLValue* gep = builder.CreateStructGEP(thismref, 0, "next"); + builder.CreateStore(curbeg, gep); + + // replace beginning + builder.CreateStore(thismref, mref); + + // return + builder.CreateRetVoid(); + + return ctor; +} + // Put out instance of ModuleInfo for this Module void Module::genmoduleinfo() @@ -469,12 +522,27 @@ if (!gvar) gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module); gvar->setInitializer(constMI); + // build the modulereference and ctor for registering it + LLFunction* mictor = build_module_reference_and_ctor(gvar); + + // register this ctor in the magic llvm.global_ctors appending array + const LLFunctionType* magicfty = LLFunctionType::get(LLType::VoidTy, std::vector<const LLType*>(), false); + std::vector<const LLType*> magictypes; + magictypes.push_back(LLType::Int32Ty); + magictypes.push_back(getPtrToType(magicfty)); + const LLStructType* magicsty = LLStructType::get(magictypes); + + // make the constant element + std::vector<LLConstant*> magicconstants; + magicconstants.push_back(DtoConstUint(65535)); + magicconstants.push_back(mictor); + LLConstant* magicinit = LLConstantStruct::get(magicsty, magicconstants); + // declare the appending array - const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(getPtrToType(LLType::Int8Ty), 1); - std::vector<LLConstant*> appendInits; - appendInits.push_back(llvm::ConstantExpr::getBitCast(gvar, getPtrToType(LLType::Int8Ty))); + const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(magicsty, 1); + std::vector<LLConstant*> appendInits(1, magicinit); LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits); - std::string appendName("_d_moduleinfo_array"); + std::string appendName("llvm.global_ctors"); llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module); }
--- a/tango/lib/compiler/llvmdc/genobj.d Wed Jul 09 17:02:55 2008 +0200 +++ b/tango/lib/compiler/llvmdc/genobj.d Wed Jul 09 23:43:51 2008 +0200 @@ -1013,19 +1013,22 @@ } -// Win32: this gets initialized by minit.asm -// linux: this gets initialized in _moduleCtor() +// this gets initialized in _moduleCtor() extern (C) ModuleInfo[] _moduleinfo_array; -// llvmdc method -extern (C) void** _d_get_moduleinfo_array(); +// This linked list is created by a compiler generated function inserted +// into the .ctor list by the compiler. +struct ModuleReference +{ + ModuleReference* next; + ModuleInfo mod; +} +extern (C) ModuleReference* _Dmodule_ref; // start of linked list +// this list is built from the linked list above ModuleInfo[] _moduleinfo_dtors; uint _moduleinfo_dtors_i; -// Register termination function pointers -extern (C) int _fatexit(void *); - /** * Initialize the modules. */ @@ -1034,32 +1037,22 @@ { debug(PRINTF) printf("_moduleCtor()\n"); - ModuleInfo* mrbegin = cast(ModuleInfo*)_d_get_moduleinfo_array(); - assert(mrbegin !is null); + int len = 0; + ModuleReference *mr; - int len = 0; - ModuleInfo* mr; - for (mr = mrbegin; *mr !is null; ++mr) + for (mr = _Dmodule_ref; mr; mr = mr.next) len++; _moduleinfo_array = new ModuleInfo[len]; - len = 0; - for (mr = mrbegin; *mr !is null; ++mr) - { _moduleinfo_array[len] = *mr; + for (mr = _Dmodule_ref; mr; mr = mr.next) + { _moduleinfo_array[len] = mr.mod; len++; } - version (Win32) - { - // Ensure module destructors also get called on program termination - //_fatexit(&_STD_moduleDtor); - } - _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length]; debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); _moduleIndependentCtors(); _moduleCtor2(_moduleinfo_array, 0); - debug(PRINTF) printf("_moduleCtor() DONE\n"); } extern (C) void _moduleIndependentCtors()
--- a/tango/lib/compiler/llvmdc/llvmdc.mak Wed Jul 09 17:02:55 2008 +0200 +++ b/tango/lib/compiler/llvmdc/llvmdc.mak Wed Jul 09 23:43:51 2008 +0200 @@ -56,9 +56,6 @@ .d.bc: $(DC) -c $(DFLAGS) $< -of$@ -.ll.bc: - $(LLC) -f -o=$@ $< - .d.html: $(DC) -c -o- $(DOCFLAGS) -Df$*.html llvmdc.ddoc $< @@ -87,12 +84,6 @@ qsort2.bc \ switch.bc \ -# NOTE: trace.obj and cover.obj are not necessary for a successful build -# as both are used for debugging features (profiling and coverage) -# NOTE: a pre-compiled minit.obj has been provided in dmd for Win32 and -# minit.asm is not used by dmd for linux -# NOTE: deh.o is only needed for Win32, linux uses deh2.o - OBJ_UTIL= \ util/console.bc \ util/ctype.bc \ @@ -139,8 +130,7 @@ ALL_OBJS= \ $(OBJ_BASE) \ $(OBJ_UTIL) \ - $(OBJ_TI) \ - moduleinfo.bc + $(OBJ_TI) ######################################################
--- a/tango/lib/compiler/llvmdc/moduleinfo.ll Wed Jul 09 17:02:55 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -; ModuleID = 'internal.moduleinit_backend' - -@_d_moduleinfo_array = appending constant [1 x i8*] [ i8* null ] - -define i8** @_d_get_moduleinfo_array() { -entry: - %tmp = getelementptr [1 x i8*]* @_d_moduleinfo_array, i32 0, i32 0 - ret i8** %tmp -}