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