Ignore:
Timestamp:
Mar 1, 2017, 4:17:24 PM (2 years ago)
Author:
nmedfort
Message:

Progress on parenthesis matching example

Location:
icGREP/icgrep-devel/icgrep/kernels
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/alignedprint.cpp

    r5340 r5353  
    245245            i->addIncoming(iBuilder->CreateAdd(i, ONE), iBuilder->GetInsertBlock());
    246246            iBuilder->CreateBr(cond);
     247
    247248            // -------------------------------------------------------------------------
    248249            iBuilder->SetInsertPoint(exit);
     
    250251        }
    251252    }
     253
     254
     255
    252256}
    253257
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5351 r5353  
    473473    PHINode * stridesRemaining = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2, "stridesRemaining");
    474474    stridesRemaining->addIncoming(stridesToDo, entryBlock);
     475    // NOTE: stridesRemaining may go to a negative number in the final block if the generateFinalBlockMethod(...)
     476    // calls CreateDoBlockMethodCall(). Do *not* replace the comparator with an unsigned one!
    475477    Value * notDone = iBuilder->CreateICmpSGT(stridesRemaining, iBuilder->getSize(0));
    476478    iBuilder->CreateLikelyCondBr(notDone, mStrideLoopBody, stridesDone);
     
    544546}
    545547
    546 void BlockOrientedKernel::writeDoBlockMethod() {
     548inline void BlockOrientedKernel::writeDoBlockMethod() {
    547549
    548550    Value * const self = mSelf;
     
    603605}
    604606
    605 void BlockOrientedKernel::writeFinalBlockMethod(Value * remainingItems) {
     607inline void BlockOrientedKernel::writeFinalBlockMethod(Value * remainingItems) {
    606608
    607609    Value * const self = mSelf;
     
    639641
    640642//  The default finalBlock method simply dispatches to the doBlock routine.
    641 void BlockOrientedKernel::generateFinalBlockMethod(Value * remainingItems) {
     643void BlockOrientedKernel::generateFinalBlockMethod(Value * /* remainingItems */) {
    642644    CreateDoBlockMethodCall();
    643645}
  • icGREP/icgrep-devel/icgrep/kernels/streamset.cpp

    r5347 r5353  
    2727
    2828void StreamSetBuffer::allocateBuffer() {
    29     mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferBlocks));
     29    Type * const ty = getType();
     30    ConstantInt * blocks = iBuilder->getSize(mBufferBlocks);
     31    mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(ty, iBuilder->getSize(mBufferBlocks));
     32    Constant * width = ConstantExpr::getMul(ConstantExpr::getSizeOf(ty), blocks);
     33    iBuilder->CreateMemZero(mStreamSetBufferPtr, width, iBuilder->getCacheAlignment());
    3034}
    3135
    3236Value * StreamSetBuffer::getStreamBlockPtr(Value * self, Value * streamIndex, Value * blockIndex, const bool /* readOnly */) const {
     37    iBuilder->CreateAssert(iBuilder->CreateICmpULT(streamIndex, getStreamSetCount(self)), "StreamSetBuffer: out-of-bounds stream access");
    3338    return iBuilder->CreateGEP(getStreamSetBlockPtr(self, blockIndex), {iBuilder->getInt32(0), streamIndex});
    3439}
    3540
    3641Value * StreamSetBuffer::getStreamPackPtr(Value * self, Value * streamIndex, Value * blockIndex, Value * packIndex, const bool /* readOnly */) const {
     42    iBuilder->CreateAssert(iBuilder->CreateICmpULT(streamIndex, getStreamSetCount(self)), "StreamSetBuffer: out-of-bounds stream access");
    3743    return iBuilder->CreateGEP(getStreamSetBlockPtr(self, blockIndex), {iBuilder->getInt32(0), streamIndex, packIndex});
     44}
     45
     46inline bool StreamSetBuffer::isCapacityGuaranteed(const llvm::Value * const index, const size_t capacity) const {
     47    if (LLVM_UNLIKELY(isa<ConstantInt>(index))) {
     48        if (LLVM_LIKELY(cast<ConstantInt>(index)->getLimitedValue() < capacity)) {
     49            return true;
     50        }
     51    }
     52    return false;
    3853}
    3954
     
    4459    }
    4560    return iBuilder->getSize(count);
     61}
     62
     63inline llvm::Value * StreamSetBuffer::modByBufferBlocks(llvm::Value * const offset) const {
     64    assert (offset->getType()->isIntegerTy());
     65    if (isCapacityGuaranteed(offset, mBufferBlocks)) {
     66        return offset;
     67    } else if (mBufferBlocks == 1) {
     68        return ConstantInt::getNullValue(iBuilder->getSizeTy());
     69    } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
     70        return iBuilder->CreateAnd(offset, ConstantInt::get(offset->getType(), mBufferBlocks - 1));
     71    } else {
     72        return iBuilder->CreateURem(offset, ConstantInt::get(offset->getType(), mBufferBlocks));
     73    }
    4674}
    4775
     
    115143
    116144Value * CircularBuffer::getStreamSetBlockPtr(Value * self, Value * blockIndex) const {
    117     assert (blockIndex->getType()->isIntegerTy());
    118     Value * offset = nullptr;
    119     if (mBufferBlocks == 1) {
    120         offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
    121     } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
    122         offset = iBuilder->CreateAnd(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks - 1));
    123     } else {
    124         offset = iBuilder->CreateURem(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks));
    125     }
    126     return iBuilder->CreateGEP(self, offset);
    127 }
    128 
     145    return iBuilder->CreateGEP(self, modByBufferBlocks(blockIndex));
     146}
    129147
    130148// CircularCopybackBuffer Buffer
     
    169187
    170188Value * CircularCopybackBuffer::getStreamSetBlockPtr(Value * self, Value * blockIndex) const {
    171     assert (blockIndex->getType()->isIntegerTy());
    172    
    173     Value * offset = nullptr;
    174     if (mBufferBlocks == 1) {
    175         offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
    176     } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
    177         offset = iBuilder->CreateAnd(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks - 1));
    178     } else {
    179         offset = iBuilder->CreateURem(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks));
    180     }
    181     return iBuilder->CreateGEP(self, offset);
    182 }
    183 
    184 
     189    return iBuilder->CreateGEP(self, modByBufferBlocks(blockIndex));
     190}
    185191
    186192// Expandable Buffer
     
    200206}
    201207
    202 inline bool ExpandableBuffer::isGuaranteedCapacity(const llvm::Value * const index) const {
    203     if (LLVM_UNLIKELY(isa<ConstantInt>(index))) {
    204         if (LLVM_LIKELY(cast<ConstantInt>(index)->getLimitedValue() < mInitialCapacity)) {
    205             return true;
    206         }
    207     }
    208     return false;
    209 }
    210 
    211208std::pair<Value *, Value *> ExpandableBuffer::getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, Value * blockIndex, const bool readOnly) const {
    212 
    213     // MDNode *Weights = MDBuilder(Ctx).createBranchWeights(42, 13);
    214209
    215210    // ENTRY
     
    218213    Value * const streamSetPtr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    219214    Value * const streamSet = iBuilder->CreateLoad(streamSetPtr);
     215    blockIndex = modByBufferBlocks(blockIndex);
     216
     217    assert (streamIndex->getType() == capacity->getType());
     218    Value * const cond = iBuilder->CreateICmpULT(streamIndex, capacity);
    220219
    221220    // Are we guaranteed that we can access this stream?
    222     if (isGuaranteedCapacity(streamIndex)) {
    223         return {streamSet, capacity};
    224     } else if (readOnly) {
    225         iBuilder->CreateAssert(iBuilder->CreateICmpULT(streamIndex, capacity), "ExpandableBuffer: out-of-bounds readonly stream access!");
    226         return {streamSet, capacity};
     221    if (readOnly || isCapacityGuaranteed(streamIndex, mInitialCapacity)) {
     222        iBuilder->CreateAssert(cond, "ExpandableBuffer: out-of-bounds stream access");
     223        Value * offset = iBuilder->CreateAdd(iBuilder->CreateMul(blockIndex, capacity), streamIndex);
     224        return {streamSet, offset};
    227225    }
    228226
     
    231229    BasicBlock * const resume = BasicBlock::Create(iBuilder->getContext(), "resume", entry->getParent());
    232230
    233     assert (streamIndex->getType() == capacity->getType());
    234     Value * cond = iBuilder->CreateICmpULT(streamIndex, capacity);
    235     iBuilder->CreateCondBr(cond, resume, expand);
     231    iBuilder->CreateLikelyCondBr(cond, resume, expand);
     232
    236233    // EXPAND
    237234    iBuilder->SetInsertPoint(expand);
    238     /// TODO: this should call a function rather than be inlined into the block. REVISIT once tested.
    239     Constant * vectorWidth = ConstantExpr::getIntegerCast(ConstantExpr::getSizeOf(streamSet->getType()->getPointerElementType()), capacity->getType(), false);
    240     Value * newCapacity = iBuilder->CreateMul(streamIndex, iBuilder->getSize(2));
     235
     236    Type * elementType = getType()->getStructElementType(1)->getPointerElementType();
     237    Constant * const vectorWidth = ConstantExpr::getIntegerCast(ConstantExpr::getSizeOf(elementType), capacity->getType(), false);
     238    Value * newCapacity = iBuilder->CreateMul(iBuilder->CreateAdd(streamIndex, iBuilder->getSize(1)), iBuilder->getSize(2), "newCapacity");
     239
     240    std::string tmp;
     241    raw_string_ostream out(tmp);
     242    out << "__expand";
     243    elementType->print(out);
     244    std::string name = out.str();
     245
     246    Module * const m = iBuilder->getModule();
     247    Function * expandFunction = m->getFunction(name);
     248
     249    if (expandFunction == nullptr) {
     250
     251        const auto ip = iBuilder->saveIP();
     252
     253        FunctionType * fty = FunctionType::get(elementType->getPointerTo(), {elementType->getPointerTo(), iBuilder->getSizeTy(), iBuilder->getSizeTy()}, false);
     254        expandFunction = Function::Create(fty, GlobalValue::PrivateLinkage, name, m);
     255
     256        auto args = expandFunction->arg_begin();
     257        Value * streamSet = &*args++;
     258        Value * capacity = &*args++;
     259        Value * newCapacity = &*args;
     260
     261        BasicBlock * entry = BasicBlock::Create(iBuilder->getContext(), "entry", expandFunction);
     262        iBuilder->SetInsertPoint(entry);
     263
     264        Value * size = iBuilder->CreateMul(newCapacity, iBuilder->getSize(mBufferBlocks));
     265        Value * newStreamSet = iBuilder->CreateAlignedMalloc(elementType, size, iBuilder->getCacheAlignment());
     266        Value * const diffCapacity = iBuilder->CreateMul(iBuilder->CreateSub(newCapacity, capacity), vectorWidth);
     267
     268        const auto alignment = elementType->getPrimitiveSizeInBits() / 8;
     269        for (unsigned i = 0; i < mBufferBlocks; ++i) {
     270            ConstantInt * const offset = iBuilder->getSize(i);
     271            Value * srcOffset = iBuilder->CreateMul(capacity, offset);
     272            Value * srcPtr = iBuilder->CreateGEP(streamSet, srcOffset);
     273            Value * destOffset = iBuilder->CreateMul(newCapacity, offset);
     274            Value * destPtr = iBuilder->CreateGEP(newStreamSet, destOffset);
     275            iBuilder->CreateMemCpy(destPtr, srcPtr, iBuilder->CreateMul(capacity, vectorWidth), alignment);
     276            Value * destZeroOffset = iBuilder->CreateAdd(destOffset, capacity);
     277            Value * destZeroPtr = iBuilder->CreateGEP(newStreamSet, destZeroOffset);
     278            iBuilder->CreateMemZero(destZeroPtr, diffCapacity, alignment);
     279        }
     280
     281        iBuilder->CreateAlignedFree(streamSet);
     282
     283        iBuilder->CreateRet(newStreamSet);
     284
     285        iBuilder->restoreIP(ip);
     286    }
     287
     288    Value * newStreamSet = iBuilder->CreateCall(expandFunction, {streamSet, capacity, newCapacity});
     289    iBuilder->CreateStore(newStreamSet, streamSetPtr);
    241290    iBuilder->CreateStore(newCapacity, capacityPtr);
    242     Type * bufferType = getType()->getStructElementType(1)->getPointerElementType();
    243     Value * size = iBuilder->CreateMul(newCapacity, iBuilder->getSize(mBufferBlocks));
    244     Value * newStreamSet = iBuilder->CreateAlignedMalloc(bufferType, size, iBuilder->getCacheAlignment());
    245     iBuilder->CreateStore(newStreamSet, streamSetPtr);
    246     Value * const diffCapacity = iBuilder->CreateMul(iBuilder->CreateSub(newCapacity, capacity), vectorWidth);
    247     const auto alignment = bufferType->getPrimitiveSizeInBits() / 8;
    248     for (unsigned i = 0; i < mBufferBlocks; ++i) {
    249         ConstantInt * const offset = iBuilder->getSize(i);
    250         Value * srcOffset = iBuilder->CreateMul(capacity, offset);
    251         Value * srcPtr = iBuilder->CreateGEP(streamSet, srcOffset);
    252         Value * destOffset = iBuilder->CreateMul(newCapacity, offset);
    253         Value * destPtr = iBuilder->CreateGEP(newStreamSet, destOffset);
    254         iBuilder->CreateMemCpy(destPtr, srcPtr, iBuilder->CreateMul(capacity, vectorWidth), alignment);
    255         Value * destZeroOffset = iBuilder->CreateAdd(destOffset, capacity);
    256         Value * destZeroPtr = iBuilder->CreateGEP(newStreamSet, destZeroOffset);
    257         iBuilder->CreateMemZero(destZeroPtr, diffCapacity, alignment);
    258     }
    259 
    260     iBuilder->CreateAlignedFree(streamSet);
     291
    261292    iBuilder->CreateBr(resume);
     293
    262294    // RESUME
    263295    iBuilder->SetInsertPoint(resume);
  • icGREP/icgrep-devel/icgrep/kernels/streamset.h

    r5340 r5353  
    6464    // Get the buffer pointer for a given block of the stream.
    6565    virtual llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const = 0;
     66
     67    bool isCapacityGuaranteed(const llvm::Value * const index, const size_t capacity) const;
     68
     69    llvm::Value * modByBufferBlocks(llvm::Value * const offset) const;
    6670
    6771protected:
     
    175179private:
    176180
    177     bool isGuaranteedCapacity(const llvm::Value * const index) const;
    178 
    179181    std::pair<llvm::Value *, llvm::Value *> getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
    180182
Note: See TracChangeset for help on using the changeset viewer.