Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Changeset 1633:5c0cebff9be8

Show
Ignore:
Timestamp:
02/14/10 04:11:05 (2 years ago)
Author:
Christian Kamm <kamm incasoftware de>
branch:
default
Message:

Improve array append performance.

Actually use the appropriate runtime function, instead of just
growing the array by one!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gen/arrays.cpp

    r1571 r1633  
    475475    // build dims 
    476476    LLValue* dimsArg = DtoArrayAlloca(Type::tsize_t, ndims, ".newdims"); 
    477     LLValue* firstDim = NULL;  
     477    LLValue* firstDim = NULL; 
    478478    for (size_t i=0; i<ndims; ++i) 
    479479    { 
     
    533533 
    534534////////////////////////////////////////////////////////////////////////////////////////// 
    535 DSliceValue* DtoCatAssignElement(DValue* array, Expression* exp) 
     535void DtoCatAssignElement(Type* arrayType, DValue* array, Expression* exp) 
    536536{ 
    537537    Logger::println("DtoCatAssignElement"); 
     
    540540    assert(array); 
    541541 
    542     LLValue* idx = DtoArrayLen(array); 
    543     LLValue* one = DtoConstSize_t(1); 
    544     LLValue* len = gIR->ir->CreateAdd(idx,one,"tmp"); 
    545  
    546     DValue* newdim = new DImValue(Type::tsize_t, len); 
    547     DSliceValue* slice = DtoResizeDynArray(array->getType(), array, newdim); 
    548  
    549     LLValue* ptr = slice->ptr; 
    550     ptr = llvm::GetElementPtrInst::Create(ptr, idx, "tmp", gIR->scopebb()); 
    551  
    552     DValue* dptr = new DVarValue(exp->type, ptr); 
    553  
    554     DValue* e = exp->toElem(gIR); 
    555  
    556     DtoAssign(exp->loc, dptr, e); 
    557  
    558     return slice; 
     542    DValue *expVal = exp->toElem(gIR); 
     543    LLValue *valueToAppend; 
     544    if (expVal->isLVal()) 
     545        valueToAppend = expVal->getLVal(); 
     546    else { 
     547        valueToAppend = DtoAlloca(expVal->getType(), ".appendingElementOnStack"); 
     548        DtoStore(expVal->getRVal(), valueToAppend); 
     549    } 
     550 
     551    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT"); 
     552    LLSmallVector<LLValue*,3> args; 
     553    args.push_back(DtoTypeInfoOf(arrayType)); 
     554    args.push_back(DtoBitCast(array->getLVal(), getVoidPtrType())); 
     555    args.push_back(DtoBitCast(valueToAppend, getVoidPtrType())); 
     556 
     557    gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray"); 
    559558} 
    560559 
     
    981980        if (Logger::enabled()) 
    982981            Logger::cout() << "to sarray" << '\n'; 
    983          
     982 
    984983        size_t tosize = ((TypeSArray*)totype)->dim->toInteger(); 
    985984 
     
    10051004            DConstValue index(Type::tsize_t, DtoConstSize_t(i)); 
    10061005            DtoArrayBoundsCheck(loc, u, &index, false); 
    1007              
     1006 
    10081007            rval = DtoArrayPtr(u); 
    1009             rval = DtoBitCast(rval, getPtrToType(tolltype));             
     1008            rval = DtoBitCast(rval, getPtrToType(tolltype)); 
    10101009        } 
    10111010    } 
  • gen/arrays.h

    r1228 r1633  
    2525DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim); 
    2626 
    27 DSliceValue* DtoCatAssignElement(DValue* arr, Expression* exp); 
     27void DtoCatAssignElement(Type* type, DValue* arr, Expression* exp); 
    2828DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp); 
    2929DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2); 
  • gen/runtime.cpp

    r1572 r1633  
    327327    } 
    328328 
     329    // void* _d_arrayappendcT(TypeInfo ti, void* array, void* element) 
     330    { 
     331        llvm::StringRef fname("_d_arrayappendcT"); 
     332        std::vector<const LLType*> types; 
     333        types.push_back(typeInfoTy); 
     334        types.push_back(voidPtrTy); 
     335        types.push_back(voidPtrTy); 
     336        const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); 
     337        llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); 
     338    } 
     339 
    329340    // Object _d_allocclass(ClassInfo ci) 
    330341    { 
  • gen/toir.cpp

    r1595 r1633  
    625625    if ((t1->ty == Tarray || t1->ty == Tsarray) && 
    626626        (t2->ty == Tarray || t2->ty == Tsarray) 
    627        )  
     627       ) 
    628628    { 
    629629        base->error("Array operation %s not recognized", base->toChars()); 
     
    10141014    } 
    10151015    else if ( 
    1016         e1->op == TOKstructliteral ||  
     1016        e1->op == TOKstructliteral || 
    10171017        e1->op == TOKslice) 
    10181018    { 
     
    11391139        // 
    11401140        bool vtbllookup = fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual()); 
    1141          
     1141 
    11421142        // even virtual functions are looked up directly if super or DotTypeExp 
    11431143        // are used, thus we need to walk through the this expression and check 
     
    11511151                break; 
    11521152        } 
    1153          
     1153 
    11541154        // 
    11551155        // look up function 
     
    12381238    } 
    12391239    else if (e1type->ty == Tsarray) { 
    1240         if(global.params.useArrayBounds)  
     1240        if(global.params.useArrayBounds) 
    12411241            DtoArrayBoundsCheck(loc, l, r, false); 
    12421242        arrptr = DtoGEP(l->getRVal(), zero, r->getRVal()); 
    12431243    } 
    12441244    else if (e1type->ty == Tarray) { 
    1245         if(global.params.useArrayBounds)  
     1245        if(global.params.useArrayBounds) 
    12461246            DtoArrayBoundsCheck(loc, l, r, false); 
    12471247        arrptr = DtoArrayPtr(l); 
     
    17701770    // class invariants 
    17711771    if( 
    1772         global.params.useInvariants &&  
     1772        global.params.useInvariants && 
    17731773        condty->ty == Tclass && 
    17741774        !((TypeClass*)condty)->sym->isInterfaceDeclaration()) 
     
    17811781    // struct invariants 
    17821782    else if( 
    1783         global.params.useInvariants &&  
     1783        global.params.useInvariants && 
    17841784        condty->ty == Tpointer && condty->nextOf()->ty == Tstruct && 
    17851785        (invdecl = ((TypeStruct*)condty->nextOf())->sym->inv) != NULL) 
     
    22352235 
    22362236    if (e2type == elemtype) { 
    2237         DSliceValue* slice = DtoCatAssignElement(l,e2); 
    2238         DtoAssign(loc, l, slice); 
     2237        DtoCatAssignElement(e1type, l, e2); 
    22392238    } 
    22402239    else if (e1type == e2type) { 
Copyright © 2008, LDC Development Team.