comparison gen/toobj.cpp @ 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 163cad969791
children c542d12017e5
comparison
equal deleted inserted replaced
322:1aaf6ff7f685 323:0d52412d5b1a
129 genmoduleinfo(); 129 genmoduleinfo();
130 // do this again as moduleinfo might have pulled something in! 130 // do this again as moduleinfo might have pulled something in!
131 DtoEmptyAllLists(); 131 DtoEmptyAllLists();
132 132
133 // emit usedArray 133 // emit usedArray
134 const LLArrayType* usedTy = LLArrayType::get(getVoidPtrType(), ir.usedArray.size()); 134 if (!ir.usedArray.empty())
135 LLConstant* usedInit = LLConstantArray::get(usedTy, ir.usedArray); 135 {
136 LLGlobalVariable* usedArray = new LLGlobalVariable(usedTy, true, LLGlobalValue::AppendingLinkage, usedInit, "llvm.used", ir.module); 136 const LLArrayType* usedTy = LLArrayType::get(getVoidPtrType(), ir.usedArray.size());
137 usedArray->setSection("llvm.metadata"); 137 LLConstant* usedInit = LLConstantArray::get(usedTy, ir.usedArray);
138 LLGlobalVariable* usedArray = new LLGlobalVariable(usedTy, true, LLGlobalValue::AppendingLinkage, usedInit, "llvm.used", ir.module);
139 usedArray->setSection("llvm.metadata");
140 }
138 141
139 // verify the llvm 142 // verify the llvm
140 if (!global.params.novalidate) { 143 if (!global.params.novalidate) {
141 std::string verifyErr; 144 std::string verifyErr;
142 Logger::println("Verifying module..."); 145 Logger::println("Verifying module...");
294 297
295 builder.CreateRetVoid(); 298 builder.CreateRetVoid();
296 return fn; 299 return fn;
297 } 300 }
298 301
302 // build ModuleReference and register function, to register the module info in the global linked list
303 static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
304 {
305 // build ctor type
306 const LLFunctionType* fty = LLFunctionType::get(LLType::VoidTy, std::vector<const LLType*>(), false);
307
308 // build ctor name
309 std::string fname = gIR->dmodule->mangle();
310 fname += "16__moduleinfoCtorZ";
311
312 // build a function that registers the moduleinfo in the global moduleinfo linked list
313 LLFunction* ctor = LLFunction::Create(fty, LLGlobalValue::InternalLinkage, fname, gIR->module);
314
315 // provide the default initializer
316 const LLStructType* modulerefTy = DtoModuleReferenceType();
317 std::vector<LLConstant*> mrefvalues;
318 mrefvalues.push_back(LLConstant::getNullValue(modulerefTy->getContainedType(0)));
319 mrefvalues.push_back(moduleinfo);
320 LLConstant* thismrefinit = LLConstantStruct::get(modulerefTy, mrefvalues);
321
322 // create the ModuleReference node for this module
323 std::string thismrefname = gIR->dmodule->mangle();
324 thismrefname += "11__moduleRefZ";
325 LLGlobalVariable* thismref = new LLGlobalVariable(modulerefTy, false, LLGlobalValue::InternalLinkage, thismrefinit, thismrefname, gIR->module);
326
327 // make sure _Dmodule_ref is declared
328 LLGlobalVariable* mref = gIR->module->getNamedGlobal("_Dmodule_ref");
329 if (!mref)
330 mref = new LLGlobalVariable(getPtrToType(modulerefTy), false, LLGlobalValue::ExternalLinkage, NULL, "_Dmodule_ref", gIR->module);
331
332 // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list
333 llvm::BasicBlock* bb = llvm::BasicBlock::Create("moduleinfoCtorEntry", ctor);
334 IRBuilder builder(bb);
335
336 // get current beginning
337 LLValue* curbeg = builder.CreateLoad(mref, "current");
338
339 // put current beginning as the next of this one
340 LLValue* gep = builder.CreateStructGEP(thismref, 0, "next");
341 builder.CreateStore(curbeg, gep);
342
343 // replace beginning
344 builder.CreateStore(thismref, mref);
345
346 // return
347 builder.CreateRetVoid();
348
349 return ctor;
350 }
351
299 // Put out instance of ModuleInfo for this Module 352 // Put out instance of ModuleInfo for this Module
300 353
301 void Module::genmoduleinfo() 354 void Module::genmoduleinfo()
302 { 355 {
303 // The layout is: 356 // The layout is:
467 520
468 llvm::GlobalVariable* gvar = gIR->module->getGlobalVariable(MIname); 521 llvm::GlobalVariable* gvar = gIR->module->getGlobalVariable(MIname);
469 if (!gvar) gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module); 522 if (!gvar) gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module);
470 gvar->setInitializer(constMI); 523 gvar->setInitializer(constMI);
471 524
525 // build the modulereference and ctor for registering it
526 LLFunction* mictor = build_module_reference_and_ctor(gvar);
527
528 // register this ctor in the magic llvm.global_ctors appending array
529 const LLFunctionType* magicfty = LLFunctionType::get(LLType::VoidTy, std::vector<const LLType*>(), false);
530 std::vector<const LLType*> magictypes;
531 magictypes.push_back(LLType::Int32Ty);
532 magictypes.push_back(getPtrToType(magicfty));
533 const LLStructType* magicsty = LLStructType::get(magictypes);
534
535 // make the constant element
536 std::vector<LLConstant*> magicconstants;
537 magicconstants.push_back(DtoConstUint(65535));
538 magicconstants.push_back(mictor);
539 LLConstant* magicinit = LLConstantStruct::get(magicsty, magicconstants);
540
472 // declare the appending array 541 // declare the appending array
473 const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(getPtrToType(LLType::Int8Ty), 1); 542 const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(magicsty, 1);
474 std::vector<LLConstant*> appendInits; 543 std::vector<LLConstant*> appendInits(1, magicinit);
475 appendInits.push_back(llvm::ConstantExpr::getBitCast(gvar, getPtrToType(LLType::Int8Ty)));
476 LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits); 544 LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits);
477 std::string appendName("_d_moduleinfo_array"); 545 std::string appendName("llvm.global_ctors");
478 llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module); 546 llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module);
479 } 547 }
480 548
481 /* ================================================================== */ 549 /* ================================================================== */
482 550