Mercurial > projects > ldc
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 |