Mercurial > projects > ldc
comparison gen/arrays.cpp @ 1633:5c0cebff9be8
Improve array append performance.
Actually use the appropriate runtime function, instead of just
growing the array by one!
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 14 Feb 2010 10:11:05 +0100 |
parents | 8d086d552909 |
children | 0de4525a9ed6 |
comparison
equal
deleted
inserted
replaced
1632:8c37dcd7cfde | 1633:5c0cebff9be8 |
---|---|
472 const char* fnname = defaultInit ? (zeroInit ? "_d_newarraymT" : "_d_newarraymiT") : "_d_newarraymvT"; | 472 const char* fnname = defaultInit ? (zeroInit ? "_d_newarraymT" : "_d_newarraymiT") : "_d_newarraymvT"; |
473 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname); | 473 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname); |
474 | 474 |
475 // build dims | 475 // build dims |
476 LLValue* dimsArg = DtoArrayAlloca(Type::tsize_t, ndims, ".newdims"); | 476 LLValue* dimsArg = DtoArrayAlloca(Type::tsize_t, ndims, ".newdims"); |
477 LLValue* firstDim = NULL; | 477 LLValue* firstDim = NULL; |
478 for (size_t i=0; i<ndims; ++i) | 478 for (size_t i=0; i<ndims; ++i) |
479 { | 479 { |
480 LLValue* dim = dims[i]->getRVal(); | 480 LLValue* dim = dims[i]->getRVal(); |
481 if (!firstDim) firstDim = dim; | 481 if (!firstDim) firstDim = dim; |
482 DtoStore(dim, DtoGEPi1(dimsArg, i)); | 482 DtoStore(dim, DtoGEPi1(dimsArg, i)); |
530 | 530 |
531 return new DSliceValue(arrayType, newdim->getRVal(), newptr); | 531 return new DSliceValue(arrayType, newdim->getRVal(), newptr); |
532 } | 532 } |
533 | 533 |
534 ////////////////////////////////////////////////////////////////////////////////////////// | 534 ////////////////////////////////////////////////////////////////////////////////////////// |
535 DSliceValue* DtoCatAssignElement(DValue* array, Expression* exp) | 535 void DtoCatAssignElement(Type* arrayType, DValue* array, Expression* exp) |
536 { | 536 { |
537 Logger::println("DtoCatAssignElement"); | 537 Logger::println("DtoCatAssignElement"); |
538 LOG_SCOPE; | 538 LOG_SCOPE; |
539 | 539 |
540 assert(array); | 540 assert(array); |
541 | 541 |
542 LLValue* idx = DtoArrayLen(array); | 542 DValue *expVal = exp->toElem(gIR); |
543 LLValue* one = DtoConstSize_t(1); | 543 LLValue *valueToAppend; |
544 LLValue* len = gIR->ir->CreateAdd(idx,one,"tmp"); | 544 if (expVal->isLVal()) |
545 | 545 valueToAppend = expVal->getLVal(); |
546 DValue* newdim = new DImValue(Type::tsize_t, len); | 546 else { |
547 DSliceValue* slice = DtoResizeDynArray(array->getType(), array, newdim); | 547 valueToAppend = DtoAlloca(expVal->getType(), ".appendingElementOnStack"); |
548 | 548 DtoStore(expVal->getRVal(), valueToAppend); |
549 LLValue* ptr = slice->ptr; | 549 } |
550 ptr = llvm::GetElementPtrInst::Create(ptr, idx, "tmp", gIR->scopebb()); | 550 |
551 | 551 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT"); |
552 DValue* dptr = new DVarValue(exp->type, ptr); | 552 LLSmallVector<LLValue*,3> args; |
553 | 553 args.push_back(DtoTypeInfoOf(arrayType)); |
554 DValue* e = exp->toElem(gIR); | 554 args.push_back(DtoBitCast(array->getLVal(), getVoidPtrType())); |
555 | 555 args.push_back(DtoBitCast(valueToAppend, getVoidPtrType())); |
556 DtoAssign(exp->loc, dptr, e); | 556 |
557 | 557 gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray"); |
558 return slice; | |
559 } | 558 } |
560 | 559 |
561 ////////////////////////////////////////////////////////////////////////////////////////// | 560 ////////////////////////////////////////////////////////////////////////////////////////// |
562 DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp) | 561 DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp) |
563 { | 562 { |
978 isslice = true; | 977 isslice = true; |
979 } | 978 } |
980 else if (totype->ty == Tsarray) { | 979 else if (totype->ty == Tsarray) { |
981 if (Logger::enabled()) | 980 if (Logger::enabled()) |
982 Logger::cout() << "to sarray" << '\n'; | 981 Logger::cout() << "to sarray" << '\n'; |
983 | 982 |
984 size_t tosize = ((TypeSArray*)totype)->dim->toInteger(); | 983 size_t tosize = ((TypeSArray*)totype)->dim->toInteger(); |
985 | 984 |
986 if (fromtype->ty == Tsarray) { | 985 if (fromtype->ty == Tsarray) { |
987 LLValue* uval = u->getRVal(); | 986 LLValue* uval = u->getRVal(); |
988 | 987 |
1002 } | 1001 } |
1003 else { | 1002 else { |
1004 size_t i = (tosize * totype->nextOf()->size() - 1) / fromtype->nextOf()->size(); | 1003 size_t i = (tosize * totype->nextOf()->size() - 1) / fromtype->nextOf()->size(); |
1005 DConstValue index(Type::tsize_t, DtoConstSize_t(i)); | 1004 DConstValue index(Type::tsize_t, DtoConstSize_t(i)); |
1006 DtoArrayBoundsCheck(loc, u, &index, false); | 1005 DtoArrayBoundsCheck(loc, u, &index, false); |
1007 | 1006 |
1008 rval = DtoArrayPtr(u); | 1007 rval = DtoArrayPtr(u); |
1009 rval = DtoBitCast(rval, getPtrToType(tolltype)); | 1008 rval = DtoBitCast(rval, getPtrToType(tolltype)); |
1010 } | 1009 } |
1011 } | 1010 } |
1012 else if (totype->ty == Tbool) { | 1011 else if (totype->ty == Tbool) { |
1013 // return (arr.ptr !is null) | 1012 // return (arr.ptr !is null) |
1014 LLValue* ptr = DtoArrayPtr(u); | 1013 LLValue* ptr = DtoArrayPtr(u); |