comparison gen/functions.cpp @ 136:0e28624814e8 trunk

[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
author lindquist
date Thu, 17 Jan 2008 03:15:12 +0100
parents 44a95ac7368a
children ce7b81fb957f
comparison
equal deleted inserted replaced
135:176bd52b3cf5 136:0e28624814e8
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->llvmValue = func; 235 fdecl->irFunc->func = func;
236 return func; 236 return func;
237 } 237 }
238 238
239 ////////////////////////////////////////////////////////////////////////////////////////// 239 //////////////////////////////////////////////////////////////////////////////////////////
240 240
255 fdecl->llvmResolved = true; 255 fdecl->llvmResolved = true;
256 256
257 Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars()); 257 Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
258 LOG_SCOPE; 258 LOG_SCOPE;
259 259
260 if (fdecl->llvmRunTimeHack) { 260 if (fdecl->runTimeHack) {
261 gIR->declareList.push_back(fdecl); 261 gIR->declareList.push_back(fdecl);
262 TypeFunction* tf = (TypeFunction*)fdecl->type; 262 TypeFunction* tf = (TypeFunction*)fdecl->type;
263 tf->llvmRetInPtr = DtoIsPassedByRef(tf->next); 263 tf->llvmRetInPtr = DtoIsPassedByRef(tf->next);
264 return; 264 return;
265 } 265 }
307 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) { 307 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
308 error(fdecl->loc, "intrinsics cannot have function bodies"); 308 error(fdecl->loc, "intrinsics cannot have function bodies");
309 fatal(); 309 fatal();
310 } 310 }
311 311
312 if (fdecl->llvmRunTimeHack) { 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->llvmValue) 314 if (!fdecl->irFunc) {
315 fdecl->llvmValue = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); 315 fdecl->irFunc = new IrFunction(fdecl);
316 fdecl->irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
317 }
316 return; 318 return;
317 } 319 }
318 320
319 bool declareOnly = false; 321 bool declareOnly = false;
320 bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent); 322 bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent);
321 if (!templInst && fdecl->getModule() != gIR->dmodule) 323 if (!templInst && fdecl->getModule() != gIR->dmodule)
322 declareOnly = true; 324 declareOnly = true;
323 else if (fdecl->llvmInternal == LLVMva_start) 325 else if (fdecl->llvmInternal == LLVMva_start)
324 declareOnly = true; 326 declareOnly = true;
325 327
326 if (!fdecl->llvmIRFunc) { 328 if (!fdecl->irFunc) {
327 fdecl->llvmIRFunc = new IRFunction(fdecl); 329 fdecl->irFunc = new IrFunction(fdecl);
328 } 330 }
329 331
330 // mangled name 332 // mangled name
331 char* mangled_name; 333 char* mangled_name;
332 if (fdecl->llvmInternal == LLVMintrinsic) 334 if (fdecl->llvmInternal == LLVMintrinsic)
349 func = new llvm::Function(functype, DtoLinkage(fdecl->protection, fdecl->storage_class), mangled_name, gIR->module); 351 func = new llvm::Function(functype, DtoLinkage(fdecl->protection, fdecl->storage_class), mangled_name, gIR->module);
350 else 352 else
351 assert(func->getFunctionType() == functype); 353 assert(func->getFunctionType() == functype);
352 354
353 // add func to IRFunc 355 // add func to IRFunc
354 fdecl->llvmIRFunc->func = func; 356 fdecl->irFunc->func = func;
355 357
356 // calling convention 358 // calling convention
357 if (!vafunc && fdecl->llvmInternal != LLVMintrinsic) 359 if (!vafunc && fdecl->llvmInternal != LLVMintrinsic)
358 func->setCallingConv(DtoCallingConv(f->linkage)); 360 func->setCallingConv(DtoCallingConv(f->linkage));
359 361
370 { 372 {
371 func->setLinkage(llvm::GlobalValue::ExternalLinkage); 373 func->setLinkage(llvm::GlobalValue::ExternalLinkage);
372 func->setCallingConv(llvm::CallingConv::C); 374 func->setCallingConv(llvm::CallingConv::C);
373 } 375 }
374 376
375 fdecl->llvmValue = func; 377 fdecl->irFunc->func = func;
376 assert(llvm::isa<llvm::FunctionType>(f->llvmType->get())); 378 assert(llvm::isa<llvm::FunctionType>(f->llvmType->get()));
377 379
378 // main 380 // main
379 if (fdecl->isMain()) { 381 if (fdecl->isMain()) {
380 gIR->mainFunc = func; 382 gIR->mainFunc = func;
392 // name parameters 394 // name parameters
393 llvm::Function::arg_iterator iarg = func->arg_begin(); 395 llvm::Function::arg_iterator iarg = func->arg_begin();
394 int k = 0; 396 int k = 0;
395 if (f->llvmRetInPtr) { 397 if (f->llvmRetInPtr) {
396 iarg->setName("retval"); 398 iarg->setName("retval");
397 fdecl->llvmRetArg = iarg; 399 fdecl->irFunc->retArg = iarg;
398 ++iarg; 400 ++iarg;
399 } 401 }
400 if (f->llvmUsesThis) { 402 if (f->llvmUsesThis) {
401 iarg->setName("this"); 403 iarg->setName("this");
402 fdecl->llvmThisVar = iarg; 404 fdecl->irFunc->thisVar = iarg;
403 assert(fdecl->llvmThisVar); 405 assert(fdecl->irFunc->thisVar);
404 ++iarg; 406 ++iarg;
405 } 407 }
406 408
407 if (f->linkage == LINKd && f->varargs == 1) { 409 if (f->linkage == LINKd && f->varargs == 1) {
408 iarg->setName("_arguments"); 410 iarg->setName("_arguments");
409 fdecl->llvmArguments = iarg; 411 fdecl->irFunc->_arguments = iarg;
410 ++iarg; 412 ++iarg;
411 iarg->setName("_argptr"); 413 iarg->setName("_argptr");
412 fdecl->llvmArgPtr = iarg; 414 fdecl->irFunc->_argptr = iarg;
413 ++iarg; 415 ++iarg;
414 } 416 }
415 417
416 for (; iarg != func->arg_end(); ++iarg) 418 for (; iarg != func->arg_end(); ++iarg)
417 { 419 {
418 Argument* arg = Argument::getNth(f->parameters, k++); 420 Argument* arg = Argument::getNth(f->parameters, k++);
419 //arg->llvmValue = iarg; 421 //arg->llvmValue = iarg;
420 //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident); 422 //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
421 if (arg && arg->ident != 0) { 423 if (arg && arg->ident != 0) {
422 if (arg->vardecl) { 424 if (arg->vardecl) {
423 arg->vardecl->llvmValue = iarg; 425 assert(!arg->vardecl->irLocal);
426 arg->vardecl->irLocal = new IrLocal(arg->vardecl);
427 arg->vardecl->irLocal->value = iarg;
424 } 428 }
425 iarg->setName(arg->ident->toChars()); 429 iarg->setName(arg->ident->toChars());
426 } 430 }
427 else { 431 else {
428 iarg->setName("unnamed"); 432 iarg->setName("unnamed");
456 if (global.params.symdebug) { 460 if (global.params.symdebug) {
457 Module* mo = fd->getModule(); 461 Module* mo = fd->getModule();
458 if (!mo->llvmCompileUnit) { 462 if (!mo->llvmCompileUnit) {
459 mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false); 463 mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false);
460 } 464 }
461 fd->llvmDwarfSubProgram = DtoDwarfSubProgram(fd, mo->llvmCompileUnit); 465 fd->irFunc->dwarfSubProg = DtoDwarfSubProgram(fd, mo->llvmCompileUnit);
462 } 466 }
463 467
464 Type* t = DtoDType(fd->type); 468 Type* t = DtoDType(fd->type);
465 TypeFunction* f = (TypeFunction*)t; 469 TypeFunction* f = (TypeFunction*)t;
466 assert(f->llvmType); 470 assert(f->llvmType);
467 471
468 llvm::Function* func = fd->llvmIRFunc->func; 472 llvm::Function* func = fd->irFunc->func;
469 const llvm::FunctionType* functype = func->getFunctionType(); 473 const llvm::FunctionType* functype = func->getFunctionType();
470 474
471 // only members of the current module or template instances maybe be defined 475 // only members of the current module or template instances maybe be defined
472 if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)) 476 if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent))
473 { 477 {
475 479
476 // function definition 480 // function definition
477 if (fd->fbody != 0) 481 if (fd->fbody != 0)
478 { 482 {
479 Logger::println("Doing function body for: %s", fd->toChars()); 483 Logger::println("Doing function body for: %s", fd->toChars());
480 assert(fd->llvmIRFunc); 484 assert(fd->irFunc);
481 gIR->functions.push_back(fd->llvmIRFunc); 485 gIR->functions.push_back(fd->irFunc);
482 486
483 if (fd->isMain()) 487 if (fd->isMain())
484 gIR->emitMain = true; 488 gIR->emitMain = true;
485 489
486 llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func); 490 llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func);
494 gIR->func()->allocapoint = allocaPoint; 498 gIR->func()->allocapoint = allocaPoint;
495 499
496 // need result variable? (not nested) 500 // need result variable? (not nested)
497 if (fd->vresult && !fd->vresult->nestedref) { 501 if (fd->vresult && !fd->vresult->nestedref) {
498 Logger::println("non-nested vresult value"); 502 Logger::println("non-nested vresult value");
499 fd->vresult->llvmValue = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint); 503 fd->vresult->irLocal = new IrLocal(fd->vresult);
504 fd->vresult->irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
500 } 505 }
501 506
502 // give arguments storage 507 // give arguments storage
503 size_t n = Argument::dim(f->parameters); 508 size_t n = Argument::dim(f->parameters);
504 for (int i=0; i < n; ++i) { 509 for (int i=0; i < n; ++i) {
505 Argument* arg = Argument::getNth(f->parameters, i); 510 Argument* arg = Argument::getNth(f->parameters, i);
506 if (arg && arg->vardecl) { 511 if (arg && arg->vardecl) {
507 VarDeclaration* vd = arg->vardecl; 512 VarDeclaration* vd = arg->vardecl;
508 if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) 513 if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
509 continue; 514 continue;
510 llvm::Value* a = vd->llvmValue; 515 llvm::Value* a = vd->irLocal->value;
511 assert(a); 516 assert(a);
512 std::string s(a->getName()); 517 std::string s(a->getName());
513 Logger::println("giving argument '%s' storage", s.c_str()); 518 Logger::println("giving argument '%s' storage", s.c_str());
514 s.append("_storage"); 519 s.append("_storage");
515 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint); 520 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
516 gIR->ir->CreateStore(a,v); 521 gIR->ir->CreateStore(a,v);
517 vd->llvmValue = v; 522 vd->irLocal->value = v;
518 } 523 }
519 else { 524 else {
520 Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0); 525 Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0);
521 } 526 }
522 } 527 }
525 if (global.params.symdebug) DtoDwarfFuncStart(fd); 530 if (global.params.symdebug) DtoDwarfFuncStart(fd);
526 531
527 llvm::Value* parentNested = NULL; 532 llvm::Value* parentNested = NULL;
528 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { 533 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
529 if (!fd->isStatic()) // huh? 534 if (!fd->isStatic()) // huh?
530 parentNested = fd2->llvmNested; 535 parentNested = fd2->irFunc->nestedVar;
531 } 536 }
532 537
533 // need result variable? (nested) 538 // need result variable? (nested)
534 if (fd->vresult && fd->vresult->nestedref) { 539 if (fd->vresult && fd->vresult->nestedref) {
535 Logger::println("nested vresult value: %s", fd->vresult->toChars()); 540 Logger::println("nested vresult value: %s", fd->vresult->toChars());
536 fd->llvmNestedVars.insert(fd->vresult); 541 fd->nestedVars.insert(fd->vresult);
537 } 542 }
538 543
539 // construct nested variables struct 544 // construct nested variables struct
540 if (!fd->llvmNestedVars.empty() || parentNested) { 545 if (!fd->nestedVars.empty() || parentNested) {
541 std::vector<const llvm::Type*> nestTypes; 546 std::vector<const llvm::Type*> nestTypes;
542 int j = 0; 547 int j = 0;
543 if (parentNested) { 548 if (parentNested) {
544 nestTypes.push_back(parentNested->getType()); 549 nestTypes.push_back(parentNested->getType());
545 j++; 550 j++;
546 } 551 }
547 for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) { 552 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
548 VarDeclaration* vd = *i; 553 VarDeclaration* vd = *i;
549 vd->llvmNestedIndex = j++; 554 if (!vd->irLocal)
555 vd->irLocal = new IrLocal(vd);
556 vd->irLocal->nestedIndex = j++;
550 if (vd->isParameter()) { 557 if (vd->isParameter()) {
551 assert(vd->llvmValue); 558
552 nestTypes.push_back(vd->llvmValue->getType()); 559 assert(vd->irLocal->value);
560 nestTypes.push_back(vd->irLocal->value->getType());
553 } 561 }
554 else { 562 else {
555 nestTypes.push_back(DtoType(vd->type)); 563 nestTypes.push_back(DtoType(vd->type));
556 } 564 }
557 } 565 }
558 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); 566 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
559 Logger::cout() << "nested var struct has type:" << *nestSType << '\n'; 567 Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
560 fd->llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint); 568 fd->irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
561 if (parentNested) { 569 if (parentNested) {
562 assert(fd->llvmThisVar); 570 assert(fd->irFunc->thisVar);
563 llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp"); 571 llvm::Value* ptr = gIR->ir->CreateBitCast(fd->irFunc->thisVar, parentNested->getType(), "tmp");
564 gIR->ir->CreateStore(ptr, DtoGEPi(fd->llvmNested, 0,0, "tmp")); 572 gIR->ir->CreateStore(ptr, DtoGEPi(fd->irFunc->nestedVar, 0,0, "tmp"));
565 } 573 }
566 for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) { 574 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
567 VarDeclaration* vd = *i; 575 VarDeclaration* vd = *i;
568 if (vd->isParameter()) { 576 if (vd->isParameter()) {
569 gIR->ir->CreateStore(vd->llvmValue, DtoGEPi(fd->llvmNested, 0, vd->llvmNestedIndex, "tmp")); 577 assert(vd->irLocal);
570 vd->llvmValue = fd->llvmNested; 578 gIR->ir->CreateStore(vd->irLocal->value, DtoGEPi(fd->irFunc->nestedVar, 0, vd->irLocal->nestedIndex, "tmp"));
579 vd->irLocal->value = fd->irFunc->nestedVar;
571 } 580 }
572 } 581 }
573 } 582 }
574 583
575 // copy _argptr to a memory location 584 // copy _argptr to a memory location
576 if (f->linkage == LINKd && f->varargs == 1) 585 if (f->linkage == LINKd && f->varargs == 1)
577 { 586 {
578 llvm::Value* argptrmem = new llvm::AllocaInst(fd->llvmArgPtr->getType(), "_argptrmem", gIR->topallocapoint()); 587 llvm::Value* argptrmem = new llvm::AllocaInst(fd->irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
579 new llvm::StoreInst(fd->llvmArgPtr, argptrmem, gIR->scopebb()); 588 new llvm::StoreInst(fd->irFunc->_argptr, argptrmem, gIR->scopebb());
580 fd->llvmArgPtr = argptrmem; 589 fd->irFunc->_argptr = argptrmem;
581 } 590 }
582 591
583 // output function body 592 // output function body
584 fd->fbody->toIR(gIR); 593 fd->fbody->toIR(gIR);
585 594