comparison gen/llvmhelpers.cpp @ 486:a34078905d01

Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in. Reimplemented support for nested functions/class using a new approach. Added error on taking address of intrinsic. Fixed problems with the ->syntaxCopy of TypeFunction delegate exp. Removed DtoDType and replaced all uses with ->toBasetype() instead. Removed unused inplace stuff. Fixed a bunch of issues in the runtime unittests, not complete yet. Added mini tests.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 10 Aug 2008 08:37:38 +0200
parents d86af825e8d9
children a3d6c9eedcb6 837af2a63564
comparison
equal deleted inserted replaced
485:50f6e2337a6b 486:a34078905d01
347 /****************************************************************************************/ 347 /****************************************************************************************/
348 /*//////////////////////////////////////////////////////////////////////////////////////// 348 /*////////////////////////////////////////////////////////////////////////////////////////
349 // NESTED VARIABLE HELPERS 349 // NESTED VARIABLE HELPERS
350 ////////////////////////////////////////////////////////////////////////////////////////*/ 350 ////////////////////////////////////////////////////////////////////////////////////////*/
351 351
352 /* 352 DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
353 353 {
354 got: 354 Dsymbol* vdparent = vd->toParent2();
355 355 assert(vdparent);
356 context pointer of 'this' function 356
357 357 IrFunction* irfunc = gIR->func();
358 declaration for target context's function 358
359 359 // is the nested variable in this scope?
360 want: 360 if (vdparent == irfunc->decl)
361 361 {
362 context pointer of target function in call chain 362 LLValue* val = vd->ir.getIrValue();
363 363 return new DVarValue(astype, vd, val, true);
364 */ 364 }
365 365
366 static LLValue* dive_into_nested(Dsymbol* from, LLValue* val) 366 // get it from the nested context
367 { 367 LLValue* ctx = 0;
368 from = from->toParent2(); 368 if (irfunc->decl->isMember2())
369 369 {
370 // parent is a function 370 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
371 if (FuncDeclaration* f = from->isFuncDeclaration()) 371 LLValue* val = DtoLoad(irfunc->thisArg);
372 { 372 ctx = DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis"));
373 IrFunction* irfunc = f->ir.irFunc; 373 }
374 // parent has nested var struct 374 else
375 if (irfunc->nestedVar) 375 ctx = irfunc->nestArg;
376 { 376 assert(ctx);
377 return DtoBitCast(val, irfunc->nestedVar->getType()); 377
378 } 378 assert(vd->ir.irLocal);
379 // parent has this argument 379 LLValue* val = DtoBitCast(ctx, getPtrToType(getVoidPtrType()));
380 else if (irfunc->thisVar) 380 val = DtoGEPi1(val, vd->ir.irLocal->nestedIndex);
381 { 381 val = DtoLoad(val);
382 return DtoBitCast(val, irfunc->thisVar->getType()->getContainedType(0)); 382 assert(vd->ir.irLocal->value);
383 } 383 val = DtoBitCast(val, vd->ir.irLocal->value->getType(), vd->toChars());
384 // none of the above, means no context is required, dummy. 384 return new DVarValue(astype, vd, val, true);
385 else 385 }
386 { 386
387 LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
388 {
389 Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
390 LOG_SCOPE;
391
392 IrFunction* irfunc = gIR->func();
393
394 if (irfunc->nestedVar)
395 return irfunc->nestedVar;
396 else if (irfunc->nestArg)
397 return irfunc->nestArg;
398 else if (irfunc->thisArg)
399 {
400 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
401 assert(cd);
402 if (!cd->vthis)
387 return getNullPtr(getVoidPtrType()); 403 return getNullPtr(getVoidPtrType());
388 } 404 LLValue* val = DtoLoad(irfunc->thisArg);
389 } 405 return DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis"));
390 // parent is a class 406 }
391 else if (ClassDeclaration* c = from->isClassDeclaration())
392 {
393 return DtoBitCast(DtoLoad(val), DtoType(c->type));
394 }
395 // parent is not valid
396 else 407 else
397 { 408 {
398 assert(0 && "!(class|function)"); 409 if (irfunc->decl->isStatic())
399 } 410 {
400 } 411 irfunc->decl->error("is static and cannot access nested %s %s", sym->kind(), sym->toChars());
401 412 fatal();
402 LLValue* DtoNestedContext(FuncDeclaration* func) 413 }
403 { 414 return getNullPtr(getVoidPtrType());
404 Logger::println("listing context frame list for funcdecl '%s'", func->toPrettyChars()); 415 }
405 LOG_SCOPE;
406
407 int level = 0;
408
409 IrFunction* irfunc = gIR->func();
410 Dsymbol* current = irfunc->decl;
411
412 // this context ?
413 if (current == func)
414 {
415 return irfunc->nestedVar;
416 }
417
418 // otherwise use the context argument
419 LLValue* val = dive_into_nested(current, irfunc->thisVar);
420 current = current->toParent2();
421 assert(val);
422
423 for (;;)
424 {
425 Logger::cout() << "context: " << *val << '\n';
426 Logger::println("(%d) looking in: %s (%s)", level, current->toPrettyChars(), current->kind());
427 if (FuncDeclaration* f = current->isFuncDeclaration())
428 {
429 if (f == func)
430 {
431 Logger::println("-> found <-");
432 Logger::cout() << "-> val: " << *val << '\n';
433 return val;
434 }
435 else
436 {
437 val = DtoLoad(DtoGEPi(val,0,0));
438 }
439 }
440 else if (ClassDeclaration* c = current->isClassDeclaration())
441 {
442 val = DtoLoad(DtoGEPi(val, 0, 2+c->vthis->ir.irField->index));
443 val = dive_into_nested(current, val);
444 }
445 else
446 {
447 Logger::cout() << "val: " << *val << '\n';
448 assert(0 && "!(class|function)");
449 }
450 current = current->toParent2();
451 ++level;
452 }
453
454 assert(0);
455 return val;
456 }
457
458 DValue* DtoNestedVariable(Type* astype, VarDeclaration* vd)
459 {
460 IrFunction* irfunc = gIR->func();
461
462 // var parent (the scope we're looking for)
463 Dsymbol* varParent = vd->toParent2();
464
465 // on level 0
466 if (varParent == irfunc->decl)
467 {
468 LLValue* nest = irfunc->nestedVar;
469 LLValue* v = DtoGEPi(nest, 0, vd->ir.irLocal->nestedIndex, "tmp");
470 // references must be loaded to get the variable address
471 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)))
472 v = DtoLoad(v);
473 return new DVarValue(astype, vd, v, true);
474 }
475
476 // on level n != 0
477 FuncDeclaration* varFunc = varParent->isFuncDeclaration();
478 assert(varFunc);
479
480 // get context of variable
481 LLValue* ctx = DtoNestedContext(varFunc);
482
483 // if no local var, it's the context itself (class this)
484 if (!vd->ir.irLocal)
485 return new DImValue(astype, ctx);
486
487 // extract variable
488 IrLocal* local = vd->ir.irLocal;
489 assert(local);
490 assert(local->nestedIndex >= 0);
491 LLValue* val = DtoGEPi(ctx, 0, local->nestedIndex);
492
493 // references must be loaded to get the variable address
494 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)))
495 val = DtoLoad(val);
496
497 Logger::cout() << "value: " << *val << '\n';
498
499 return new DVarValue(astype, vd, val, true);
500 } 416 }
501 417
502 /****************************************************************************************/ 418 /****************************************************************************************/
503 /*//////////////////////////////////////////////////////////////////////////////////////// 419 /*////////////////////////////////////////////////////////////////////////////////////////
504 // ASSIGNMENT HELPER (store this in that) 420 // ASSIGNMENT HELPER (store this in that)
507 void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) 423 void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
508 { 424 {
509 Logger::cout() << "DtoAssign(...);\n"; 425 Logger::cout() << "DtoAssign(...);\n";
510 LOG_SCOPE; 426 LOG_SCOPE;
511 427
512 Type* t = DtoDType(lhs->getType()); 428 Type* t = lhs->getType()->toBasetype();
513 Type* t2 = DtoDType(rhs->getType()); 429 Type* t2 = rhs->getType()->toBasetype();
514 430
515 if (t->ty == Tstruct) { 431 if (t->ty == Tstruct) {
516 if (!t->equals(t2)) { 432 if (!t->equals(t2)) {
517 // TODO: fix this, use 'rhs' for something 433 // TODO: fix this, use 'rhs' for something
518 DtoAggrZeroInit(lhs->getLVal()); 434 DtoAggrZeroInit(lhs->getLVal());
519 } 435 }
520 else if (!rhs->inPlace()) { 436 else {
521 DtoAggrCopy(lhs->getLVal(), rhs->getRVal()); 437 DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
522 } 438 }
523 } 439 }
524 else if (t->ty == Tarray) { 440 else if (t->ty == Tarray) {
525 // lhs is slice 441 // lhs is slice
557 } 473 }
558 } 474 }
559 else if (t->ty == Tdelegate) { 475 else if (t->ty == Tdelegate) {
560 if (rhs->isNull()) 476 if (rhs->isNull())
561 DtoAggrZeroInit(lhs->getLVal()); 477 DtoAggrZeroInit(lhs->getLVal());
562 else if (!rhs->inPlace()) { 478 else {
563 LLValue* l = lhs->getLVal(); 479 LLValue* l = lhs->getLVal();
564 LLValue* r = rhs->getRVal(); 480 LLValue* r = rhs->getRVal();
565 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; 481 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
566 DtoAggrCopy(l, r); 482 DtoAggrCopy(l, r);
567 } 483 }
663 579
664 DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to) 580 DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to)
665 { 581 {
666 const LLType* tolltype = DtoType(_to); 582 const LLType* tolltype = DtoType(_to);
667 583
668 Type* to = DtoDType(_to); 584 Type* to = _to->toBasetype();
669 Type* from = DtoDType(val->getType()); 585 Type* from = val->getType()->toBasetype();
670 assert(from->isintegral()); 586 assert(from->isintegral());
671 587
672 size_t fromsz = from->size(); 588 size_t fromsz = from->size();
673 size_t tosz = to->size(); 589 size_t tosz = to->size();
674 590
718 634
719 DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to) 635 DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to)
720 { 636 {
721 const LLType* tolltype = DtoType(to); 637 const LLType* tolltype = DtoType(to);
722 638
723 Type* totype = DtoDType(to); 639 Type* totype = to->toBasetype();
724 Type* fromtype = DtoDType(val->getType()); 640 Type* fromtype = val->getType()->toBasetype();
725 assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction); 641 assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction);
726 642
727 LLValue* rval; 643 LLValue* rval;
728 644
729 if (totype->ty == Tpointer || totype->ty == Tclass) { 645 if (totype->ty == Tpointer || totype->ty == Tclass) {
747 if (val->getType() == to) 663 if (val->getType() == to)
748 return val; 664 return val;
749 665
750 const LLType* tolltype = DtoType(to); 666 const LLType* tolltype = DtoType(to);
751 667
752 Type* totype = DtoDType(to); 668 Type* totype = to->toBasetype();
753 Type* fromtype = DtoDType(val->getType()); 669 Type* fromtype = val->getType()->toBasetype();
754 assert(fromtype->isfloating()); 670 assert(fromtype->isfloating());
755 671
756 size_t fromsz = fromtype->size(); 672 size_t fromsz = fromtype->size();
757 size_t tosz = totype->size(); 673 size_t tosz = totype->size();
758 674
812 return new DImValue(to, res); 728 return new DImValue(to, res);
813 } 729 }
814 730
815 DValue* DtoCast(Loc& loc, DValue* val, Type* to) 731 DValue* DtoCast(Loc& loc, DValue* val, Type* to)
816 { 732 {
817 Type* fromtype = DtoDType(val->getType()); 733 Type* fromtype = val->getType()->toBasetype();
818 Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); 734 Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars());
819 if (fromtype->isintegral()) { 735 if (fromtype->isintegral()) {
820 return DtoCastInt(loc, val, to); 736 return DtoCastInt(loc, val, to);
821 } 737 }
822 else if (fromtype->iscomplex()) { 738 else if (fromtype->iscomplex()) {
877 llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend); 793 llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend);
878 LLValue* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); 794 LLValue* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
879 gIR->ir->CreateCondBr(cond, initbb, endinitbb); 795 gIR->ir->CreateCondBr(cond, initbb, endinitbb);
880 gIR->scope() = IRScope(initbb,endinitbb); 796 gIR->scope() = IRScope(initbb,endinitbb);
881 DValue* ie = DtoInitializer(gvar, init); 797 DValue* ie = DtoInitializer(gvar, init);
882 if (!ie->inPlace()) { 798
883 DValue* dst = new DVarValue(t, gvar, true); 799 DVarValue dst(t, gvar, true);
884 DtoAssign(init->loc, dst, ie); 800 DtoAssign(init->loc, &dst, ie);
885 } 801
886 gIR->ir->CreateStore(DtoConstBool(true), gflag); 802 gIR->ir->CreateStore(DtoConstBool(true), gflag);
887 gIR->ir->CreateBr(endinitbb); 803 gIR->ir->CreateBr(endinitbb);
888 gIR->scope() = IRScope(endinitbb,oldend); 804 gIR->scope() = IRScope(endinitbb,oldend);
889 } 805 }
890 806
999 else { 915 else {
1000 _init = DtoConstInitializer(vd->type, vd->init); 916 _init = DtoConstInitializer(vd->type, vd->init);
1001 } 917 }
1002 918
1003 const LLType* _type = DtoType(vd->type); 919 const LLType* _type = DtoType(vd->type);
1004 Type* t = DtoDType(vd->type); 920 Type* t = vd->type->toBasetype();
1005 921
1006 //Logger::cout() << "initializer: " << *_init << '\n'; 922 //Logger::cout() << "initializer: " << *_init << '\n';
1007 if (_type != _init->getType()) { 923 if (_type != _init->getType()) {
1008 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; 924 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
1009 // zero initalizer 925 // zero initalizer
1216 1132
1217 // referenced by nested delegate? 1133 // referenced by nested delegate?
1218 if (vd->nestedref) { 1134 if (vd->nestedref) {
1219 Logger::println("has nestedref set"); 1135 Logger::println("has nestedref set");
1220 assert(vd->ir.irLocal); 1136 assert(vd->ir.irLocal);
1221 vd->ir.irLocal->value = gIR->func()->decl->ir.irFunc->nestedVar; 1137
1222 assert(vd->ir.irLocal->value); 1138 // alloca as usual is no value already
1139 if (!vd->ir.irLocal->value)
1140 {
1141 vd->ir.irLocal->value = DtoAlloca(DtoType(vd->type), vd->toChars());
1142 }
1143
1144 // store the address into the nested vars array
1145
1223 assert(vd->ir.irLocal->nestedIndex >= 0); 1146 assert(vd->ir.irLocal->nestedIndex >= 0);
1147 LLValue* gep = DtoGEPi(gIR->func()->decl->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex);
1148
1149 assert(isaPointer(vd->ir.irLocal->value));
1150 LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());
1151
1152 DtoStore(val, gep);
1153
1224 } 1154 }
1225 // normal stack variable, allocate storage on the stack if it has not already been done 1155 // normal stack variable, allocate storage on the stack if it has not already been done
1226 else if(!vd->ir.irLocal) { 1156 else if(!vd->ir.irLocal) {
1227 const LLType* lltype = DtoType(vd->type); 1157 const LLType* lltype = DtoType(vd->type);
1228 1158
1238 1168
1239 if (global.params.symdebug) 1169 if (global.params.symdebug)
1240 { 1170 {
1241 DtoDwarfLocalVariable(allocainst, vd); 1171 DtoDwarfLocalVariable(allocainst, vd);
1242 } 1172 }
1173 }
1174 else
1175 {
1176 assert(vd->ir.irLocal->value);
1243 } 1177 }
1244 1178
1245 Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n'; 1179 Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
1246 DValue* ie = DtoInitializer(vd->ir.irLocal->value, vd->init); 1180 DValue* ie = DtoInitializer(vd->ir.irLocal->value, vd->init);
1247 } 1181 }