Mercurial > projects > ldc
comparison gen/functions.cpp @ 155:7f92f477ff53 trunk
[svn r171] starting to move IR data from AST nodes into IRState; started with IrFunction
author | ChristianK |
---|---|
date | Tue, 29 Apr 2008 21:33:50 +0200 |
parents | 2c447715c047 |
children | ccd07d9f2ce9 |
comparison
equal
deleted
inserted
replaced
154:5cb946f323d2 | 155:7f92f477ff53 |
---|---|
230 assert(0); | 230 assert(0); |
231 | 231 |
232 llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn); | 232 llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn); |
233 assert(func); | 233 assert(func); |
234 assert(func->isIntrinsic()); | 234 assert(func->isIntrinsic()); |
235 fdecl->irFunc->func = func; | 235 gIR->irFunc[fdecl]->func = func; |
236 return func; | 236 return func; |
237 } | 237 } |
238 | 238 |
239 ////////////////////////////////////////////////////////////////////////////////////////// | 239 ////////////////////////////////////////////////////////////////////////////////////////// |
240 | 240 |
309 fatal(); | 309 fatal(); |
310 } | 310 } |
311 | 311 |
312 if (fdecl->runTimeHack) { | 312 if (fdecl->runTimeHack) { |
313 Logger::println("runtime hack func chars: %s", fdecl->toChars()); | 313 Logger::println("runtime hack func chars: %s", fdecl->toChars()); |
314 if (!fdecl->irFunc) { | 314 if (gIR->irFunc.find(fdecl) == gIR->irFunc.end()) { |
315 fdecl->irFunc = new IrFunction(fdecl); | 315 gIR->irFunc[fdecl] = new IrFunction(fdecl); |
316 fdecl->irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); | 316 gIR->irFunc[fdecl]->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); |
317 } | 317 } |
318 return; | 318 return; |
319 } | 319 } |
320 | 320 |
321 bool declareOnly = false; | 321 bool declareOnly = false; |
328 declareOnly = true; | 328 declareOnly = true; |
329 } | 329 } |
330 else if (fdecl->llvmInternal == LLVMva_start) | 330 else if (fdecl->llvmInternal == LLVMva_start) |
331 declareOnly = true; | 331 declareOnly = true; |
332 | 332 |
333 if (!fdecl->irFunc) { | 333 if (gIR->irFunc.find(fdecl) == gIR->irFunc.end()) { |
334 fdecl->irFunc = new IrFunction(fdecl); | 334 gIR->irFunc[fdecl] = new IrFunction(fdecl); |
335 } | 335 } |
336 | 336 |
337 // mangled name | 337 // mangled name |
338 char* mangled_name; | 338 char* mangled_name; |
339 if (fdecl->llvmInternal == LLVMintrinsic) | 339 if (fdecl->llvmInternal == LLVMintrinsic) |
356 func = new llvm::Function(functype, DtoLinkage(fdecl), mangled_name, gIR->module); | 356 func = new llvm::Function(functype, DtoLinkage(fdecl), mangled_name, gIR->module); |
357 else | 357 else |
358 assert(func->getFunctionType() == functype); | 358 assert(func->getFunctionType() == functype); |
359 | 359 |
360 // add func to IRFunc | 360 // add func to IRFunc |
361 fdecl->irFunc->func = func; | 361 gIR->irFunc[fdecl]->func = func; |
362 | 362 |
363 // calling convention | 363 // calling convention |
364 if (!vafunc && fdecl->llvmInternal != LLVMintrinsic) | 364 if (!vafunc && fdecl->llvmInternal != LLVMintrinsic) |
365 func->setCallingConv(DtoCallingConv(f->linkage)); | 365 func->setCallingConv(DtoCallingConv(f->linkage)); |
366 else // fall back to C, it should be the right thing to do | 366 else // fall back to C, it should be the right thing to do |
367 func->setCallingConv(llvm::CallingConv::C); | 367 func->setCallingConv(llvm::CallingConv::C); |
368 | 368 |
369 fdecl->irFunc->func = func; | 369 gIR->irFunc[fdecl]->func = func; |
370 assert(llvm::isa<llvm::FunctionType>(f->llvmType->get())); | 370 assert(llvm::isa<llvm::FunctionType>(f->llvmType->get())); |
371 | 371 |
372 // main | 372 // main |
373 if (fdecl->isMain()) { | 373 if (fdecl->isMain()) { |
374 gIR->mainFunc = func; | 374 gIR->mainFunc = func; |
386 // name parameters | 386 // name parameters |
387 llvm::Function::arg_iterator iarg = func->arg_begin(); | 387 llvm::Function::arg_iterator iarg = func->arg_begin(); |
388 int k = 0; | 388 int k = 0; |
389 if (f->llvmRetInPtr) { | 389 if (f->llvmRetInPtr) { |
390 iarg->setName("retval"); | 390 iarg->setName("retval"); |
391 fdecl->irFunc->retArg = iarg; | 391 gIR->irFunc[fdecl]->retArg = iarg; |
392 ++iarg; | 392 ++iarg; |
393 } | 393 } |
394 if (f->llvmUsesThis) { | 394 if (f->llvmUsesThis) { |
395 iarg->setName("this"); | 395 iarg->setName("this"); |
396 fdecl->irFunc->thisVar = iarg; | 396 gIR->irFunc[fdecl]->thisVar = iarg; |
397 assert(fdecl->irFunc->thisVar); | 397 assert(gIR->irFunc[fdecl]->thisVar); |
398 ++iarg; | 398 ++iarg; |
399 } | 399 } |
400 | 400 |
401 if (f->linkage == LINKd && f->varargs == 1) { | 401 if (f->linkage == LINKd && f->varargs == 1) { |
402 iarg->setName("_arguments"); | 402 iarg->setName("_arguments"); |
403 fdecl->irFunc->_arguments = iarg; | 403 gIR->irFunc[fdecl]->_arguments = iarg; |
404 ++iarg; | 404 ++iarg; |
405 iarg->setName("_argptr"); | 405 iarg->setName("_argptr"); |
406 fdecl->irFunc->_argptr = iarg; | 406 gIR->irFunc[fdecl]->_argptr = iarg; |
407 ++iarg; | 407 ++iarg; |
408 } | 408 } |
409 | 409 |
410 for (; iarg != func->arg_end(); ++iarg) | 410 for (; iarg != func->arg_end(); ++iarg) |
411 { | 411 { |
455 LOG_SCOPE; | 455 LOG_SCOPE; |
456 | 456 |
457 // debug info | 457 // debug info |
458 if (global.params.symdebug) { | 458 if (global.params.symdebug) { |
459 Module* mo = fd->getModule(); | 459 Module* mo = fd->getModule(); |
460 fd->irFunc->dwarfSubProg = DtoDwarfSubProgram(fd, DtoDwarfCompileUnit(mo)); | 460 gIR->irFunc[fd]->dwarfSubProg = DtoDwarfSubProgram(fd, DtoDwarfCompileUnit(mo)); |
461 } | 461 } |
462 | 462 |
463 Type* t = DtoDType(fd->type); | 463 Type* t = DtoDType(fd->type); |
464 TypeFunction* f = (TypeFunction*)t; | 464 TypeFunction* f = (TypeFunction*)t; |
465 assert(f->llvmType); | 465 assert(f->llvmType); |
466 | 466 |
467 llvm::Function* func = fd->irFunc->func; | 467 llvm::Function* func = gIR->irFunc[fd]->func; |
468 const llvm::FunctionType* functype = func->getFunctionType(); | 468 const llvm::FunctionType* functype = func->getFunctionType(); |
469 | 469 |
470 // only members of the current module or template instances maybe be defined | 470 // only members of the current module or template instances maybe be defined |
471 if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)) | 471 if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)) |
472 { | 472 { |
474 | 474 |
475 // function definition | 475 // function definition |
476 if (fd->fbody != 0) | 476 if (fd->fbody != 0) |
477 { | 477 { |
478 Logger::println("Doing function body for: %s", fd->toChars()); | 478 Logger::println("Doing function body for: %s", fd->toChars()); |
479 assert(fd->irFunc); | 479 assert(gIR->irFunc.count(fd) != 0); |
480 gIR->functions.push_back(fd->irFunc); | 480 gIR->functions.push_back(gIR->irFunc[fd]); |
481 | 481 |
482 if (fd->isMain()) | 482 if (fd->isMain()) |
483 gIR->emitMain = true; | 483 gIR->emitMain = true; |
484 | 484 |
485 llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func); | 485 llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func); |
525 if (global.params.symdebug) DtoDwarfFuncStart(fd); | 525 if (global.params.symdebug) DtoDwarfFuncStart(fd); |
526 | 526 |
527 llvm::Value* parentNested = NULL; | 527 llvm::Value* parentNested = NULL; |
528 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { | 528 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { |
529 if (!fd->isStatic()) // huh? | 529 if (!fd->isStatic()) // huh? |
530 parentNested = fd2->irFunc->nestedVar; | 530 parentNested = gIR->irFunc[fd2]->nestedVar; |
531 } | 531 } |
532 | 532 |
533 // need result variable? (nested) | 533 // need result variable? (nested) |
534 if (fd->vresult && fd->vresult->nestedref) { | 534 if (fd->vresult && fd->vresult->nestedref) { |
535 Logger::println("nested vresult value: %s", fd->vresult->toChars()); | 535 Logger::println("nested vresult value: %s", fd->vresult->toChars()); |
551 vd->irLocal = new IrLocal(vd); | 551 vd->irLocal = new IrLocal(vd); |
552 vd->irLocal->nestedIndex = j++; | 552 vd->irLocal->nestedIndex = j++; |
553 if (vd->isParameter()) { | 553 if (vd->isParameter()) { |
554 if (!vd->irLocal->value) { | 554 if (!vd->irLocal->value) { |
555 assert(vd == fd->vthis); | 555 assert(vd == fd->vthis); |
556 vd->irLocal->value = fd->irFunc->thisVar; | 556 vd->irLocal->value = gIR->irFunc[fd]->thisVar; |
557 } | 557 } |
558 assert(vd->irLocal->value); | 558 assert(vd->irLocal->value); |
559 nestTypes.push_back(vd->irLocal->value->getType()); | 559 nestTypes.push_back(vd->irLocal->value->getType()); |
560 } | 560 } |
561 else { | 561 else { |
562 nestTypes.push_back(DtoType(vd->type)); | 562 nestTypes.push_back(DtoType(vd->type)); |
563 } | 563 } |
564 } | 564 } |
565 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); | 565 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); |
566 Logger::cout() << "nested var struct has type:" << *nestSType << '\n'; | 566 Logger::cout() << "nested var struct has type:" << *nestSType << '\n'; |
567 fd->irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint); | 567 gIR->irFunc[fd]->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint); |
568 if (parentNested) { | 568 if (parentNested) { |
569 assert(fd->irFunc->thisVar); | 569 assert(gIR->irFunc[fd]->thisVar); |
570 llvm::Value* ptr = gIR->ir->CreateBitCast(fd->irFunc->thisVar, parentNested->getType(), "tmp"); | 570 llvm::Value* ptr = gIR->ir->CreateBitCast(gIR->irFunc[fd]->thisVar, parentNested->getType(), "tmp"); |
571 gIR->ir->CreateStore(ptr, DtoGEPi(fd->irFunc->nestedVar, 0,0, "tmp")); | 571 gIR->ir->CreateStore(ptr, DtoGEPi(gIR->irFunc[fd]->nestedVar, 0,0, "tmp")); |
572 } | 572 } |
573 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { | 573 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { |
574 VarDeclaration* vd = *i; | 574 VarDeclaration* vd = *i; |
575 if (vd->isParameter()) { | 575 if (vd->isParameter()) { |
576 assert(vd->irLocal); | 576 assert(vd->irLocal); |
577 gIR->ir->CreateStore(vd->irLocal->value, DtoGEPi(fd->irFunc->nestedVar, 0, vd->irLocal->nestedIndex, "tmp")); | 577 gIR->ir->CreateStore(vd->irLocal->value, DtoGEPi(gIR->irFunc[fd]->nestedVar, 0, vd->irLocal->nestedIndex, "tmp")); |
578 vd->irLocal->value = fd->irFunc->nestedVar; | 578 vd->irLocal->value = gIR->irFunc[fd]->nestedVar; |
579 } | 579 } |
580 } | 580 } |
581 } | 581 } |
582 | 582 |
583 // copy _argptr to a memory location | 583 // copy _argptr to a memory location |
584 if (f->linkage == LINKd && f->varargs == 1) | 584 if (f->linkage == LINKd && f->varargs == 1) |
585 { | 585 { |
586 llvm::Value* argptrmem = new llvm::AllocaInst(fd->irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint()); | 586 llvm::Value* argptrmem = new llvm::AllocaInst(gIR->irFunc[fd]->_argptr->getType(), "_argptrmem", gIR->topallocapoint()); |
587 new llvm::StoreInst(fd->irFunc->_argptr, argptrmem, gIR->scopebb()); | 587 new llvm::StoreInst(gIR->irFunc[fd]->_argptr, argptrmem, gIR->scopebb()); |
588 fd->irFunc->_argptr = argptrmem; | 588 gIR->irFunc[fd]->_argptr = argptrmem; |
589 } | 589 } |
590 | 590 |
591 // output function body | 591 // output function body |
592 fd->fbody->toIR(gIR); | 592 fd->fbody->toIR(gIR); |
593 | 593 |