comparison gen/toobj.cpp @ 1650:40bd4a0d4870

Update to work with LLVM 2.7. Removed use of dyn_cast, llvm no compiles without exceptions and rtti by default. We do need exceptions for the libconfig stuff, but rtti isn't necessary (anymore). Debug info needs to be rewritten, as in LLVM 2.7 the format has completely changed. To have something to look at while rewriting, the old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means that you have to define this to compile at the moment. Updated tango 0.99.9 patch to include updated EH runtime code, which is needed for LLVM 2.7 as well.
author Tomas Lindquist Olsen
date Wed, 19 May 2010 12:42:32 +0200
parents 299a6b634178
children
comparison
equal deleted inserted replaced
1649:36da40ecbbe0 1650:40bd4a0d4870
12 12
13 #include "gen/llvm.h" 13 #include "gen/llvm.h"
14 #include "llvm/Analysis/Verifier.h" 14 #include "llvm/Analysis/Verifier.h"
15 #include "llvm/Bitcode/ReaderWriter.h" 15 #include "llvm/Bitcode/ReaderWriter.h"
16 #include "llvm/Module.h" 16 #include "llvm/Module.h"
17 #include "llvm/ModuleProvider.h"
18 #include "llvm/PassManager.h" 17 #include "llvm/PassManager.h"
19 #include "llvm/LinkAllPasses.h" 18 #include "llvm/LinkAllPasses.h"
20 #include "llvm/System/Program.h" 19 #include "llvm/System/Program.h"
21 #include "llvm/Support/raw_ostream.h" 20 #include "llvm/Support/raw_ostream.h"
22 #include "llvm/Support/CommandLine.h" 21 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/FormattedStream.h" 22 #include "llvm/Support/FormattedStream.h"
24 #include "llvm/Target/TargetMachine.h" 23 #include "llvm/Target/TargetMachine.h"
24 #include "llvm/CodeGen/MachineCodeEmitter.h"
25 25
26 #include "mars.h" 26 #include "mars.h"
27 #include "module.h" 27 #include "module.h"
28 #include "mtype.h" 28 #include "mtype.h"
29 #include "declaration.h" 29 #include "declaration.h"
112 Logger::cout() << "Final data layout: " << global.params.dataLayout << '\n'; 112 Logger::cout() << "Final data layout: " << global.params.dataLayout << '\n';
113 113
114 // allocate the target abi 114 // allocate the target abi
115 gABI = TargetABI::getTarget(); 115 gABI = TargetABI::getTarget();
116 116
117 #ifndef DISABLE_DEBUG_INFO
117 // debug info 118 // debug info
118 if (global.params.symdebug) { 119 if (global.params.symdebug) {
119 RegisterDwarfSymbols(ir.module); 120 RegisterDwarfSymbols(ir.module);
120 DtoDwarfCompileUnit(this); 121 DtoDwarfCompileUnit(this);
121 } 122 }
123 #endif
122 124
123 // handle invalid 'objectø module 125 // handle invalid 'objectø module
124 if (!ClassDeclaration::object) { 126 if (!ClassDeclaration::object) {
125 error("is missing 'class Object'"); 127 error("is missing 'class Object'");
126 fatal(); 128 fatal();
127 } 129 }
128 if (!ClassDeclaration::classinfo) { 130 if (!ClassDeclaration::classinfo) {
129 error("is missing 'class ClassInfo'"); 131 error("is missing 'class ClassInfo'");
130 fatal(); 132 fatal();
131 } 133 }
132 134
133 LLVM_D_InitRuntime(); 135 LLVM_D_InitRuntime();
134 136
135 // process module members 137 // process module members
136 for (int k=0; k < members->dim; k++) { 138 for (int k=0; k < members->dim; k++) {
137 Dsymbol* dsym = (Dsymbol*)(members->data[k]); 139 Dsymbol* dsym = (Dsymbol*)(members->data[k]);
223 if (global.params.output_bc) { 225 if (global.params.output_bc) {
224 LLPath bcpath = LLPath(filename); 226 LLPath bcpath = LLPath(filename);
225 bcpath.eraseSuffix(); 227 bcpath.eraseSuffix();
226 bcpath.appendSuffix(std::string(global.bc_ext)); 228 bcpath.appendSuffix(std::string(global.bc_ext));
227 Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str()); 229 Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str());
228 std::ofstream bos(bcpath.c_str(), std::ios::binary); 230 std::string errinfo;
229 if (bos.fail()) 231 llvm::raw_fd_ostream bos(bcpath.c_str(), errinfo, llvm::raw_fd_ostream::F_Binary);
232 if (bos.has_error())
230 { 233 {
231 error("cannot write LLVM bitcode, failed to open file '%s'", bcpath.c_str()); 234 error("cannot write LLVM bitcode file '%s': %s", bcpath.c_str(), errinfo.c_str());
232 fatal(); 235 fatal();
233 } 236 }
234 llvm::WriteBitcodeToFile(m, bos); 237 llvm::WriteBitcodeToFile(m, bos);
235 } 238 }
236 239
238 if (global.params.output_ll) { 241 if (global.params.output_ll) {
239 LLPath llpath = LLPath(filename); 242 LLPath llpath = LLPath(filename);
240 llpath.eraseSuffix(); 243 llpath.eraseSuffix();
241 llpath.appendSuffix(std::string(global.ll_ext)); 244 llpath.appendSuffix(std::string(global.ll_ext));
242 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); 245 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str());
243 std::ofstream aos(llpath.c_str()); 246 std::string errinfo;
244 if (aos.fail()) 247 llvm::raw_fd_ostream aos(llpath.c_str(), errinfo);
248 if (aos.has_error())
245 { 249 {
246 error("cannot write LLVM asm, failed to open file '%s'", llpath.c_str()); 250 error("cannot write LLVM asm file '%s': %s", llpath.c_str(), errinfo.c_str());
247 fatal(); 251 fatal();
248 } 252 }
249 m->print(aos, NULL); 253 m->print(aos, NULL);
250 } 254 }
251 255
258 spath.createTemporaryFileOnDisk(); 262 spath.createTemporaryFileOnDisk();
259 } 263 }
260 Logger::println("Writing native asm to: %s\n", spath.c_str()); 264 Logger::println("Writing native asm to: %s\n", spath.c_str());
261 std::string err; 265 std::string err;
262 { 266 {
263 llvm::raw_fd_ostream out(spath.c_str(), false, true, err); 267 llvm::raw_fd_ostream out(spath.c_str(), err);
264 if (err.empty()) 268 if (err.empty())
265 { 269 {
266 write_asm_to_file(*gTargetMachine, *m, out); 270 write_asm_to_file(*gTargetMachine, *m, out);
267 } 271 }
268 else 272 else
290 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out) 294 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out)
291 { 295 {
292 using namespace llvm; 296 using namespace llvm;
293 297
294 // Build up all of the passes that we want to do to the module. 298 // Build up all of the passes that we want to do to the module.
295 ExistingModuleProvider Provider(&m); 299 FunctionPassManager Passes(&m);
296 FunctionPassManager Passes(&Provider);
297 300
298 if (const TargetData *TD = Target.getTargetData()) 301 if (const TargetData *TD = Target.getTargetData())
299 Passes.add(new TargetData(*TD)); 302 Passes.add(new TargetData(*TD));
300 else 303 else
301 Passes.add(new TargetData(&m)); 304 Passes.add(new TargetData(&m));
302
303 // Ask the target to add backend passes as necessary.
304 MachineCodeEmitter *MCE = 0;
305 305
306 // Last argument is enum CodeGenOpt::Level OptLevel 306 // Last argument is enum CodeGenOpt::Level OptLevel
307 // debug info doesn't work properly with OptLevel != None! 307 // debug info doesn't work properly with OptLevel != None!
308 CodeGenOpt::Level LastArg = CodeGenOpt::Default; 308 CodeGenOpt::Level LastArg = CodeGenOpt::Default;
309 if (global.params.symdebug || !optimize()) 309 if (global.params.symdebug || !optimize())
310 LastArg = CodeGenOpt::None; 310 LastArg = CodeGenOpt::None;
311 else if (optLevel() >= 3) 311 else if (optLevel() >= 3)
312 LastArg = CodeGenOpt::Aggressive; 312 LastArg = CodeGenOpt::Aggressive;
313 313
314 llvm::formatted_raw_ostream fout(out); 314 llvm::formatted_raw_ostream fout(out);
315 FileModel::Model mod = Target.addPassesToEmitFile(Passes, fout, TargetMachine::AssemblyFile, LastArg); 315 if (Target.addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, LastArg))
316 assert(mod == FileModel::AsmFile); 316 assert(0 && "no support for asm output");
317
318 bool err = Target.addPassesToEmitFileFinish(Passes, MCE, LastArg);
319 assert(!err);
320 317
321 Passes.doInitialization(); 318 Passes.doInitialization();
322 319
323 // Run our queue of passes all at once now, efficiently. 320 // Run our queue of passes all at once now, efficiently.
324 for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I) 321 for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I)
326 Passes.run(*I); 323 Passes.run(*I);
327 324
328 Passes.doFinalization(); 325 Passes.doFinalization();
329 326
330 // release module from module provider so we can delete it ourselves 327 // release module from module provider so we can delete it ourselves
331 std::string Err; 328 //std::string Err;
332 llvm::Module* rmod = Provider.releaseModule(&Err); 329 //llvm::Module* rmod = Provider.releaseModule(&Err);
333 assert(rmod); 330 //assert(rmod);
334 } 331 }
335 332
336 /* ================================================================== */ 333 /* ================================================================== */
337 334
338 // uses gcc to make an obj out of an assembly file 335 // uses gcc to make an obj out of an assembly file
348 // Note: 345 // Note:
349 // We can't just assemble and link the file with the system assembler 346 // We can't just assemble and link the file with the system assembler
350 // and linker because we don't know where to put the _start symbol. 347 // and linker because we don't know where to put the _start symbol.
351 // GCC mysteriously knows how to do it. 348 // GCC mysteriously knows how to do it.
352 std::vector<std::string> args; 349 std::vector<std::string> args;
353 args.push_back(gcc.toString()); 350 args.push_back(gcc.str());
354 args.push_back("-fno-strict-aliasing"); 351 args.push_back("-fno-strict-aliasing");
355 args.push_back("-O3"); 352 args.push_back("-O3");
356 args.push_back("-c"); 353 args.push_back("-c");
357 args.push_back("-xassembler"); 354 args.push_back("-xassembler");
358 args.push_back(asmpath.toString()); 355 args.push_back(asmpath.str());
359 args.push_back("-o"); 356 args.push_back("-o");
360 args.push_back(objpath.toString()); 357 args.push_back(objpath.str());
361 358
362 //FIXME: only use this if needed? 359 //FIXME: only use this if needed?
363 args.push_back("-fpic"); 360 args.push_back("-fpic");
364 361
365 //FIXME: enforce 64 bit 362 //FIXME: enforce 64 bit
429 426
430 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 427 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn);
431 IRBuilder<> builder(bb); 428 IRBuilder<> builder(bb);
432 429
433 // debug info 430 // debug info
431 #ifndef DISABLE_DEBUG_INFO
434 LLGlobalVariable* subprog; 432 LLGlobalVariable* subprog;
435 if(global.params.symdebug) { 433 if(global.params.symdebug) {
436 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 434 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV();
437 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 435 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
438 } 436 }
437 #endif
439 438
440 for (size_t i=0; i<n; i++) { 439 for (size_t i=0; i<n; i++) {
441 llvm::Function* f = gIR->ctors[i]->ir.irFunc->func; 440 llvm::Function* f = gIR->ctors[i]->ir.irFunc->func;
442 llvm::CallInst* call = builder.CreateCall(f,""); 441 llvm::CallInst* call = builder.CreateCall(f,"");
443 call->setCallingConv(DtoCallingConv(0, LINKd)); 442 call->setCallingConv(DtoCallingConv(0, LINKd));
444 } 443 }
445 444
446 // debug info end 445 // debug info end
446 #ifndef DISABLE_DEBUG_INFO
447 if(global.params.symdebug) 447 if(global.params.symdebug)
448 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 448 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
449 #endif
449 450
450 builder.CreateRetVoid(); 451 builder.CreateRetVoid();
451 return fn; 452 return fn;
452 } 453 }
453 454
473 fn->setCallingConv(DtoCallingConv(0, LINKd)); 474 fn->setCallingConv(DtoCallingConv(0, LINKd));
474 475
475 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 476 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn);
476 IRBuilder<> builder(bb); 477 IRBuilder<> builder(bb);
477 478
479 #ifndef DISABLE_DEBUG_INFO
478 // debug info 480 // debug info
479 LLGlobalVariable* subprog; 481 LLGlobalVariable* subprog;
480 if(global.params.symdebug) { 482 if(global.params.symdebug) {
481 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 483 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV();
482 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 484 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
483 } 485 }
486 #endif
484 487
485 for (size_t i=0; i<n; i++) { 488 for (size_t i=0; i<n; i++) {
486 llvm::Function* f = gIR->dtors[i]->ir.irFunc->func; 489 llvm::Function* f = gIR->dtors[i]->ir.irFunc->func;
487 llvm::CallInst* call = builder.CreateCall(f,""); 490 llvm::CallInst* call = builder.CreateCall(f,"");
488 call->setCallingConv(DtoCallingConv(0, LINKd)); 491 call->setCallingConv(DtoCallingConv(0, LINKd));
489 } 492 }
490 493
494 #ifndef DISABLE_DEBUG_INFO
491 // debug info end 495 // debug info end
492 if(global.params.symdebug) 496 if(global.params.symdebug)
493 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 497 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
498 #endif
494 499
495 builder.CreateRetVoid(); 500 builder.CreateRetVoid();
496 return fn; 501 return fn;
497 } 502 }
498 503
518 fn->setCallingConv(DtoCallingConv(0, LINKd)); 523 fn->setCallingConv(DtoCallingConv(0, LINKd));
519 524
520 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 525 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn);
521 IRBuilder<> builder(bb); 526 IRBuilder<> builder(bb);
522 527
528 #ifndef DISABLE_DEBUG_INFO
523 // debug info 529 // debug info
524 LLGlobalVariable* subprog; 530 LLGlobalVariable* subprog;
525 if(global.params.symdebug) { 531 if(global.params.symdebug) {
526 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 532 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV();
527 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 533 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
528 } 534 }
535 #endif
529 536
530 for (size_t i=0; i<n; i++) { 537 for (size_t i=0; i<n; i++) {
531 llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func; 538 llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func;
532 llvm::CallInst* call = builder.CreateCall(f,""); 539 llvm::CallInst* call = builder.CreateCall(f,"");
533 call->setCallingConv(DtoCallingConv(0, LINKd)); 540 call->setCallingConv(DtoCallingConv(0, LINKd));
534 } 541 }
535 542
543 #ifndef DISABLE_DEBUG_INFO
536 // debug info end 544 // debug info end
537 if(global.params.symdebug) 545 if(global.params.symdebug)
538 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 546 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
547 #endif
539 548
540 builder.CreateRetVoid(); 549 builder.CreateRetVoid();
541 return fn; 550 return fn;
542 } 551 }
543 552
576 // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list 585 // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list
577 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "moduleinfoCtorEntry", ctor); 586 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "moduleinfoCtorEntry", ctor);
578 IRBuilder<> builder(bb); 587 IRBuilder<> builder(bb);
579 588
580 // debug info 589 // debug info
590 #ifndef DISABLE_DEBUG_INFO
581 LLGlobalVariable* subprog; 591 LLGlobalVariable* subprog;
582 if(global.params.symdebug) { 592 if(global.params.symdebug) {
583 subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV(); 593 subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV();
584 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 594 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
585 } 595 }
596 #endif
586 597
587 // get current beginning 598 // get current beginning
588 LLValue* curbeg = builder.CreateLoad(mref, "current"); 599 LLValue* curbeg = builder.CreateLoad(mref, "current");
589 600
590 // put current beginning as the next of this one 601 // put current beginning as the next of this one
592 builder.CreateStore(curbeg, gep); 603 builder.CreateStore(curbeg, gep);
593 604
594 // replace beginning 605 // replace beginning
595 builder.CreateStore(thismref, mref); 606 builder.CreateStore(thismref, mref);
596 607
608 #ifndef DISABLE_DEBUG_INFO
597 // debug info end 609 // debug info end
598 if(global.params.symdebug) 610 if(global.params.symdebug)
599 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 611 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
612 #endif
600 613
601 // return 614 // return
602 builder.CreateRetVoid(); 615 builder.CreateRetVoid();
603 616
604 return ctor; 617 return ctor;
612 // { 625 // {
613 // char[] name; 626 // char[] name;
614 // ModuleInfo[] importedModules; 627 // ModuleInfo[] importedModules;
615 // ClassInfo[] localClasses; 628 // ClassInfo[] localClasses;
616 // uint flags; 629 // uint flags;
617 // 630 //
618 // void function() ctor; 631 // void function() ctor;
619 // void function() dtor; 632 // void function() dtor;
620 // void function() unitTest; 633 // void function() unitTest;
621 // 634 //
622 // void* xgetMembers; 635 // void* xgetMembers;
623 // void function() ictor; 636 // void function() ictor;
624 // 637 //
625 // version(D_Version2) 638 // version(D_Version2)
626 // void*[4] reserved; // useless to us 639 // void*[4] reserved; // useless to us