comparison gen/arrays.cpp @ 203:e881c9b1c738 trunk

[svn r219] Fixed: the tango/lib/gc/basic garbage collector now compiles and links into an executable (change in tango/lib/llvmdc-posix.mak), closes #5 . Changed: removed the crappy realloc based dynamic memory runtime and started moving over to DMD style runtime support, part of moving to real GC. Fixed: dynamic arrays now use GC runtime for allocating memory. Fixed: new expression now use GC for allocating memory. Changed: revamped the dynamic array support routines related to dynamic memory. Fixed: assertions no longer create exsessive allocas. Changed: misc. minor cleanups.
author lindquist
date Tue, 13 May 2008 14:42:09 +0200
parents aca17e55b7a5
children 9d44ec83acd1
comparison
equal deleted inserted replaced
202:56e0c5b1d428 203:e881c9b1c738
60 60
61 ////////////////////////////////////////////////////////////////////////////////////////// 61 //////////////////////////////////////////////////////////////////////////////////////////
62 62
63 void DtoSetArrayToNull(llvm::Value* v) 63 void DtoSetArrayToNull(llvm::Value* v)
64 { 64 {
65 Logger::println("DtoSetArrayToNull");
66 LOG_SCOPE;
67
65 llvm::Value* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb()); 68 llvm::Value* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb());
66 llvm::Value* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false); 69 llvm::Value* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false);
67 new llvm::StoreInst(zerolen, len, gIR->scopebb()); 70 new llvm::StoreInst(zerolen, len, gIR->scopebb());
68 71
69 llvm::Value* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb()); 72 llvm::Value* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb());
74 77
75 ////////////////////////////////////////////////////////////////////////////////////////// 78 //////////////////////////////////////////////////////////////////////////////////////////
76 79
77 void DtoArrayAssign(llvm::Value* dst, llvm::Value* src) 80 void DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
78 { 81 {
82 Logger::println("DtoArrayAssign");
83 LOG_SCOPE;
84
79 assert(gIR); 85 assert(gIR);
80 if (dst->getType() == src->getType()) 86 if (dst->getType() == src->getType())
81 { 87 {
82 llvm::Value* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb()); 88 llvm::Value* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb());
83 llvm::Value* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); 89 llvm::Value* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb());
112 118
113 ////////////////////////////////////////////////////////////////////////////////////////// 119 //////////////////////////////////////////////////////////////////////////////////////////
114 120
115 void DtoArrayInit(llvm::Value* l, llvm::Value* r) 121 void DtoArrayInit(llvm::Value* l, llvm::Value* r)
116 { 122 {
123 Logger::println("DtoArrayInit");
124 LOG_SCOPE;
125
117 const llvm::PointerType* ptrty = isaPointer(l->getType()); 126 const llvm::PointerType* ptrty = isaPointer(l->getType());
118 const llvm::Type* t = ptrty->getContainedType(0); 127 const llvm::Type* t = ptrty->getContainedType(0);
119 const llvm::ArrayType* arrty = isaArray(t); 128 const llvm::ArrayType* arrty = isaArray(t);
120 if (arrty) 129 if (arrty)
121 { 130 {
149 return 0; 158 return 0;
150 } 159 }
151 160
152 void DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val) 161 void DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val)
153 { 162 {
163 Logger::println("DtoArrayInit");
164 LOG_SCOPE;
165
154 Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; 166 Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n';
155 const llvm::Type* pt = ptr->getType()->getContainedType(0); 167 const llvm::Type* pt = ptr->getType()->getContainedType(0);
156 const llvm::Type* t = val->getType(); 168 const llvm::Type* t = val->getType();
157 const llvm::Type* finalTy; 169 const llvm::Type* finalTy;
158 size_t aggrsz = 0; 170 size_t aggrsz = 0;
242 254
243 ////////////////////////////////////////////////////////////////////////////////////////// 255 //////////////////////////////////////////////////////////////////////////////////////////
244 256
245 void DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr) 257 void DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
246 { 258 {
247 Logger::cout() << "DtoSetArray(" << *arr << ", " << *dim << ", " << *ptr << ")\n"; 259 Logger::println("DtoSetArray");
260 LOG_SCOPE;
261
262 Logger::cout() << "arr = " << *arr << '\n';
263 Logger::cout() << "dim = " << *dim << '\n';
264 Logger::cout() << "ptr = " << *ptr << '\n';
265
248 const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0)); 266 const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0));
249 267
250 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 268 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
251 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); 269 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
252 270
253 llvm::Value* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb()); 271 llvm::Value* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb());
272 Logger::cout() << "arrdim = " << *arrdim << '\n';
254 new llvm::StoreInst(dim, arrdim, gIR->scopebb()); 273 new llvm::StoreInst(dim, arrdim, gIR->scopebb());
255 274
256 llvm::Value* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb()); 275 llvm::Value* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb());
276 Logger::cout() << "arrptr = " << *arrptr << '\n';
257 new llvm::StoreInst(ptr, arrptr, gIR->scopebb()); 277 new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
258 } 278 }
259 279
260 ////////////////////////////////////////////////////////////////////////////////////////// 280 //////////////////////////////////////////////////////////////////////////////////////////
261 llvm::Constant* DtoConstArrayInitializer(ArrayInitializer* arrinit) 281 llvm::Constant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
482 values.push_back(ptr); 502 values.push_back(ptr);
483 return llvm::ConstantStruct::get(type,values); 503 return llvm::ConstantStruct::get(type,values);
484 } 504 }
485 505
486 ////////////////////////////////////////////////////////////////////////////////////////// 506 //////////////////////////////////////////////////////////////////////////////////////////
487 llvm::Value* DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit) 507 DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
488 { 508 {
489 const llvm::Type* ty = DtoType(dty); 509 Logger::println("DtoNewDynArray : %s", arrayType->toChars());
490 assert(ty != llvm::Type::VoidTy); 510 LOG_SCOPE;
491 size_t sz = getABITypeSize(ty); 511
492 llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), sz, false); 512 bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
493 llvm::Value* bytesize = (sz == 1) ? dim : llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb()); 513 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
494 514
495 llvm::Value* nullptr = llvm::ConstantPointerNull::get(getPtrToType(ty)); 515 llvm::SmallVector<llvm::Value*,2> args;
496 516 args.push_back(DtoTypeInfoOf(arrayType));
497 llvm::Value* newptr = DtoRealloc(nullptr, bytesize); 517 assert(DtoType(dim->getType()) == DtoSize_t());
498 518 args.push_back(dim->getRVal());
499 if (doinit) { 519
520 llvm::Value* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem");
521 const llvm::Type* dstType = DtoType(arrayType)->getContainedType(1);
522 if (newptr->getType() != dstType)
523 newptr = DtoBitCast(newptr, dstType, ".gc_mem");
524
525 Logger::cout() << "final ptr = " << *newptr << '\n';
526
527 #if 0
528 if (defaultInit) {
500 DValue* e = dty->defaultInit()->toElem(gIR); 529 DValue* e = dty->defaultInit()->toElem(gIR);
501 DtoArrayInit(newptr,dim,e->getRVal()); 530 DtoArrayInit(newptr,dim,e->getRVal());
502 } 531 }
503 532 #endif
504 llvm::Value* lenptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); 533
505 new llvm::StoreInst(dim,lenptr,gIR->scopebb()); 534 return new DSliceValue(arrayType, args[1], newptr);
506 llvm::Value* ptrptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); 535 }
507 new llvm::StoreInst(newptr,ptrptr,gIR->scopebb()); 536
508 537 //////////////////////////////////////////////////////////////////////////////////////////
509 return newptr; 538 DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
510 } 539 {
511 540 Logger::println("DtoResizeDynArray : %s", arrayType->toChars());
512 ////////////////////////////////////////////////////////////////////////////////////////// 541 LOG_SCOPE;
513 llvm::Value* DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz) 542
514 { 543 assert(array);
515 llvm::Value* ptr = DtoGEPi(arr, 0, 1, "tmp", gIR->scopebb()); 544 assert(newdim);
516 llvm::Value* ptrld = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); 545 assert(arrayType);
517 546 assert(arrayType->toBasetype()->ty == Tarray);
518 size_t isz = getABITypeSize(ptrld->getType()->getContainedType(0)); 547
519 llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), isz, false); 548 bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
520 llvm::Value* bytesz = (isz == 1) ? sz : llvm::BinaryOperator::createMul(n,sz,"tmp",gIR->scopebb()); 549 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" );
521 550
522 llvm::Value* newptr = DtoRealloc(ptrld, bytesz); 551 llvm::SmallVector<llvm::Value*,4> args;
523 new llvm::StoreInst(newptr,ptr,gIR->scopebb()); 552 args.push_back(DtoTypeInfoOf(arrayType));
524 553 args.push_back(newdim->getRVal());
525 llvm::Value* len = DtoGEPi(arr, 0, 0, "tmp", gIR->scopebb()); 554 args.push_back(DtoArrayLen(array));
526 new llvm::StoreInst(sz,len,gIR->scopebb()); 555 llvm::Value* arrPtr = DtoArrayPtr(array);
527 556 Logger::cout() << "arrPtr = " << *arrPtr << '\n';
528 return newptr; 557 args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp"));
529 } 558
530 559 llvm::Value* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem");
531 ////////////////////////////////////////////////////////////////////////////////////////// 560 if (newptr->getType() != arrPtr->getType())
532 void DtoCatAssignElement(llvm::Value* arr, Expression* exp) 561 newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
533 { 562
534 llvm::Value* ptr = DtoGEPi(arr, 0, 0, "tmp"); 563 return new DSliceValue(arrayType, newdim->getRVal(), newptr);
535 llvm::Value* idx = DtoLoad(ptr); 564 }
536 llvm::Value* one = llvm::ConstantInt::get(idx->getType(),1,false); 565
537 llvm::Value* len = llvm::BinaryOperator::createAdd(idx, one, "tmp", gIR->scopebb()); 566 //////////////////////////////////////////////////////////////////////////////////////////
538 DtoResizeDynArray(arr,len); 567 DSliceValue* DtoCatAssignElement(DValue* array, Expression* exp)
539 568 {
540 ptr = DtoLoad(DtoGEPi(arr, 0, 1, "tmp")); 569 Logger::println("DtoCatAssignElement");
570 LOG_SCOPE;
571
572 assert(array);
573
574 llvm::Value* idx = DtoArrayLen(array);
575 llvm::Value* one = DtoConstSize_t(1);
576 llvm::Value* len = gIR->ir->CreateAdd(idx,one,"tmp");
577
578 DValue* newdim = new DImValue(Type::tsize_t, len);
579 DSliceValue* slice = DtoResizeDynArray(array->getType(), array, newdim);
580
581 llvm::Value* ptr = slice->ptr;
541 ptr = new llvm::GetElementPtrInst(ptr, idx, "tmp", gIR->scopebb()); 582 ptr = new llvm::GetElementPtrInst(ptr, idx, "tmp", gIR->scopebb());
542 583
543 DValue* dptr = new DVarValue(exp->type, ptr, true); 584 DValue* dptr = new DVarValue(exp->type, ptr, true);
544 585
545 gIR->exps.push_back(IRExp(0,exp,dptr)); 586 gIR->exps.push_back(IRExp(0,exp,dptr));
546 DValue* e = exp->toElem(gIR); 587 DValue* e = exp->toElem(gIR);
547 gIR->exps.pop_back(); 588 gIR->exps.pop_back();
548 589
549 if (!e->inPlace()) 590 if (!e->inPlace())
550 DtoAssign(dptr, e); 591 DtoAssign(dptr, e);
551 } 592
552 593 return slice;
553 ////////////////////////////////////////////////////////////////////////////////////////// 594 }
554 void DtoCatAssignArray(llvm::Value* arr, Expression* exp) 595
555 { 596 //////////////////////////////////////////////////////////////////////////////////////////
597 DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
598 {
599 Logger::println("DtoCatAssignArray");
600 LOG_SCOPE;
601
556 DValue* e = exp->toElem(gIR); 602 DValue* e = exp->toElem(gIR);
557 603
558 llvm::Value *len1, *len2, *src1, *src2, *res; 604 llvm::Value *len1, *len2, *src1, *src2, *res;
559 605
560 DValue* darr = new DVarValue(exp->type, arr, true); 606 len1 = DtoArrayLen(arr);
561
562 len1 = DtoArrayLen(darr);
563 len2 = DtoArrayLen(e); 607 len2 = DtoArrayLen(e);
564 res = gIR->ir->CreateAdd(len1,len2,"tmp"); 608 res = gIR->ir->CreateAdd(len1,len2,"tmp");
565 609
566 llvm::Value* mem = DtoResizeDynArray(arr,res); 610 DValue* newdim = new DImValue(Type::tsize_t, res);
567 611 DSliceValue* slice = DtoResizeDynArray(arr->getType(), arr, newdim);
568 src1 = DtoArrayPtr(darr); 612
613 src1 = slice->ptr;
569 src2 = DtoArrayPtr(e); 614 src2 = DtoArrayPtr(e);
570 615
571 mem = gIR->ir->CreateGEP(mem,len1,"tmp"); 616 // advance ptr
572 DtoMemCpy(mem,src2,len2); 617 src1 = gIR->ir->CreateGEP(src1,len1,"tmp");
573 } 618
574 619 // memcpy
575 ////////////////////////////////////////////////////////////////////////////////////////// 620 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src2->getType()->getContainedType(0)));
576 void DtoCatArrays(llvm::Value* arr, Expression* exp1, Expression* exp2) 621 llvm::Value* bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp");
577 { 622 DtoMemCpy(src1,src2,bytelen);
623
624 return slice;
625 }
626
627 //////////////////////////////////////////////////////////////////////////////////////////
628 DSliceValue* DtoCatArrays(Type* type, Expression* exp1, Expression* exp2)
629 {
630 Logger::println("DtoCatArrays");
631 LOG_SCOPE;
632
578 Type* t1 = DtoDType(exp1->type); 633 Type* t1 = DtoDType(exp1->type);
579 Type* t2 = DtoDType(exp2->type); 634 Type* t2 = DtoDType(exp2->type);
580 635
581 assert(t1->ty == Tarray); 636 assert(t1->ty == Tarray);
582 assert(t1->ty == t2->ty); 637 assert(t1->ty == t2->ty);
588 643
589 len1 = DtoArrayLen(e1); 644 len1 = DtoArrayLen(e1);
590 len2 = DtoArrayLen(e2); 645 len2 = DtoArrayLen(e2);
591 res = gIR->ir->CreateAdd(len1,len2,"tmp"); 646 res = gIR->ir->CreateAdd(len1,len2,"tmp");
592 647
593 llvm::Value* mem = DtoNewDynArray(arr, res, DtoDType(t1->next), false); 648 DValue* lenval = new DImValue(Type::tsize_t, res);
649 DSliceValue* slice = DtoNewDynArray(type, lenval, false);
650 llvm::Value* mem = slice->ptr;
594 651
595 src1 = DtoArrayPtr(e1); 652 src1 = DtoArrayPtr(e1);
596 src2 = DtoArrayPtr(e2); 653 src2 = DtoArrayPtr(e2);
597 654
598 DtoMemCpy(mem,src1,len1); 655 // first memcpy
656 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0)));
657 llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp");
658 DtoMemCpy(mem,src1,bytelen);
659
660 // second memcpy
599 mem = gIR->ir->CreateGEP(mem,len1,"tmp"); 661 mem = gIR->ir->CreateGEP(mem,len1,"tmp");
600 DtoMemCpy(mem,src2,len2); 662 bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp");
601 } 663 DtoMemCpy(mem,src2,bytelen);
602 664
603 ////////////////////////////////////////////////////////////////////////////////////////// 665 return slice;
604 void DtoCatArrayElement(llvm::Value* arr, Expression* exp1, Expression* exp2) 666 }
605 { 667
668 //////////////////////////////////////////////////////////////////////////////////////////
669 DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2)
670 {
671 Logger::println("DtoCatArrayElement");
672 LOG_SCOPE;
673
606 Type* t1 = DtoDType(exp1->type); 674 Type* t1 = DtoDType(exp1->type);
607 Type* t2 = DtoDType(exp2->type); 675 Type* t2 = DtoDType(exp2->type);
608 676
609 // handle reverse case
610 if (t2->next && t1 == DtoDType(t2->next))
611 {
612 Type* tmp = t1;
613 t1 = t2;
614 t2 = tmp;
615 Expression* e = exp1;
616 exp1 = exp2;
617 exp2 = e;
618 }
619
620 DValue* e1 = exp1->toElem(gIR); 677 DValue* e1 = exp1->toElem(gIR);
621 DValue* e2 = exp2->toElem(gIR); 678 DValue* e2 = exp2->toElem(gIR);
622 679
623 llvm::Value *len1, *src1, *res; 680 llvm::Value *len1, *src1, *res;
624 681
625 len1 = DtoArrayLen(e1); 682 // handle prefix case, eg. int~int[]
626 res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp"); 683 if (t2->next && t1 == DtoDType(t2->next))
627 684 {
628 llvm::Value* mem = DtoNewDynArray(arr, res, DtoDType(t1->next), false); 685 len1 = DtoArrayLen(e2);
629 686 res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
630 src1 = DtoArrayPtr(e1); 687
631 688 DValue* lenval = new DImValue(Type::tsize_t, res);
632 DtoMemCpy(mem,src1,len1); 689 DSliceValue* slice = DtoNewDynArray(type, lenval, false);
633 690 llvm::Value* mem = slice->ptr;
634 mem = gIR->ir->CreateGEP(mem,len1,"tmp"); 691
635 DVarValue* memval = new DVarValue(e2->getType(), mem, true); 692 DVarValue* memval = new DVarValue(e1->getType(), mem, true);
636 DtoAssign(memval, e2); 693 DtoAssign(memval, e1);
694
695 src1 = DtoArrayPtr(e2);
696
697 mem = gIR->ir->CreateGEP(mem,DtoConstSize_t(1),"tmp");
698
699 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0)));
700 llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp");
701 DtoMemCpy(mem,src1,bytelen);
702
703
704 return slice;
705 }
706 // handle suffix case, eg. int[]~int
707 else
708 {
709 len1 = DtoArrayLen(e1);
710 res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
711
712 DValue* lenval = new DImValue(Type::tsize_t, res);
713 DSliceValue* slice = DtoNewDynArray(type, lenval, false);
714 llvm::Value* mem = slice->ptr;
715
716 src1 = DtoArrayPtr(e1);
717
718 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0)));
719 llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp");
720 DtoMemCpy(mem,src1,bytelen);
721
722 mem = gIR->ir->CreateGEP(mem,len1,"tmp");
723 DVarValue* memval = new DVarValue(e2->getType(), mem, true);
724 DtoAssign(memval, e2);
725
726 return slice;
727 }
637 } 728 }
638 729
639 ////////////////////////////////////////////////////////////////////////////////////////// 730 //////////////////////////////////////////////////////////////////////////////////////////
640 // helper for eq and cmp 731 // helper for eq and cmp
641 static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti) 732 static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti)
864 ////////////////////////////////////////////////////////////////////////////////////////// 955 //////////////////////////////////////////////////////////////////////////////////////////
865 llvm::Value* DtoArrayLen(DValue* v) 956 llvm::Value* DtoArrayLen(DValue* v)
866 { 957 {
867 Logger::println("DtoArrayLen"); 958 Logger::println("DtoArrayLen");
868 LOG_SCOPE; 959 LOG_SCOPE;
960
869 Type* t = DtoDType(v->getType()); 961 Type* t = DtoDType(v->getType());
870 if (t->ty == Tarray) { 962 if (t->ty == Tarray) {
871 if (DSliceValue* s = v->isSlice()) { 963 if (DSliceValue* s = v->isSlice()) {
872 if (s->len) { 964 if (s->len) {
873 return s->len; 965 return s->len;
892 } 984 }
893 985
894 ////////////////////////////////////////////////////////////////////////////////////////// 986 //////////////////////////////////////////////////////////////////////////////////////////
895 llvm::Value* DtoArrayPtr(DValue* v) 987 llvm::Value* DtoArrayPtr(DValue* v)
896 { 988 {
989 Logger::println("DtoArrayPtr");
990 LOG_SCOPE;
991
897 Type* t = DtoDType(v->getType()); 992 Type* t = DtoDType(v->getType());
898 if (t->ty == Tarray) { 993 if (t->ty == Tarray) {
899 if (DSliceValue* s = v->isSlice()) { 994 if (DSliceValue* s = v->isSlice()) {
900 if (s->len) return s->ptr; 995 if (s->len) return s->ptr;
901 const llvm::Type* t = s->ptr->getType()->getContainedType(0); 996 const llvm::Type* t = s->ptr->getType()->getContainedType(0);