Ignore:
Timestamp:
Apr 28, 2018, 3:54:43 PM (13 months ago)
Author:
nmedfort
Message:

Added temporary buffer functionality to the pipeline for single stream source buffers. Fixed memory leak from UCD::UnicodeBreakRE()

File:
1 edited

Legend:

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

    r5993 r5998  
    296296    Constant * const overflowSize = ConstantExpr::getSizeOf(buf->getType());
    297297    CreateMemCpy(target, source, overflowSize, getBitBlockWidth() / 8);
     298}
     299
     300/** ------------------------------------------------------------------------------------------------------------- *
     301 * @brief AcquireTemporaryBuffer
     302 ** ------------------------------------------------------------------------------------------------------------- */
     303std::pair<Value *, Value *> KernelBuilder::AcquireTemporaryBuffer(const std::string & name, Value * offset, Value * itemsToCopy) {
     304    const StreamSetBuffer * const buf = mKernel->getAnyStreamSetBuffer(name);
     305    const auto itemWidth = getItemWidth(buf->getBaseType());
     306    const Binding & binding = mKernel->getBinding(name);
     307    if (LLVM_UNLIKELY(!binding.getRate().isFixed())) {
     308        Constant * const BIT_BLOCK_WIDTH = ConstantInt::get(offset->getType(), getBitBlockWidth());
     309        Value * const alignedOffset = CreateAnd(offset, CreateNeg(BIT_BLOCK_WIDTH));
     310        itemsToCopy = CreateAdd(itemsToCopy, CreateSub(offset, alignedOffset));
     311        offset = alignedOffset;
     312    }
     313    Value * bytesToCopy = itemsToCopy;
     314    if (itemWidth < 8) {
     315        bytesToCopy = CreateCeilUDiv(itemsToCopy, getSize(8 / itemWidth));
     316    } else if (itemWidth > 8) {
     317        bytesToCopy = CreateMul(itemsToCopy, getSize(itemWidth / 8));
     318    }
     319    Constant * const baseSize = ConstantExpr::getTrunc(ConstantExpr::getSizeOf(buf->getStreamSetBlockType()), getSizeTy());
     320    Constant * const itemsConsumedPerIteration = getSize(std::max(ceiling(mKernel->getUpperBound(binding.getRate())), 1U));
     321    Constant * const paddedSize =  ConstantExpr::getMul(baseSize, itemsConsumedPerIteration);
     322
     323    // one is added to bytes to copy to ensure that the stream is "zero-extended" by one block to properly handle any
     324    // final block processing.o
     325    Value * const size = CreateRoundUp(CreateAdd(bytesToCopy, getSize(1)), paddedSize);
     326    Value * const handle = getStreamHandle(name);
     327    Value * const base = buf->getBaseAddress(this, handle);
     328    Value * const buffer = CreateAlignedMalloc(size, getCacheAlignment());
     329    // TODO: handle split copy? currently no SourceBuffers could support it and I'm not sure how useful it'd be to do so.
     330    Value * const from = buf->getRawItemPointer(this, handle, offset);
     331    CreateMemCpy(buffer, from, bytesToCopy, 1);
     332    CreateMemZero(CreateGEP(buffer, bytesToCopy), CreateSub(size, bytesToCopy), 1);
     333    // get the difference between our base and from position then compute an offsetted temporary buffer address
     334    Value * const diff = CreatePtrDiff(CreatePointerCast(base, from->getType()), from);
     335    Value * const offsettedBuffer = CreatePointerCast(CreateGEP(buffer, diff), base->getType());
     336    buf->setBaseAddress(this, handle, offsettedBuffer);
     337    Value * const tempBuffer = CreatePointerCast(buffer, base->getType());
     338    return std::make_pair(base, tempBuffer);
    298339}
    299340
Note: See TracChangeset for help on using the changeset viewer.