Mercurial > projects > ldc
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); |