Ignore:
Timestamp:
Sep 18, 2017, 8:37:23 AM (20 months ago)
Author:
cameron
Message:

Modularizing copyBack support

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

Legend:

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

    r5640 r5641  
    11/*
    2  *  Copyright (c) 2016 International Characters.
     2 *  Copyright (c) 2016-7 International Characters.
    33 *  This software is licensed to the public under the Open Software License 3.0.
    44 */
     
    338338}
    339339
     340   
    340341
    341342// Default kernel signature: generate the IR and emit as byte code.
     
    652653    std::vector<Value *> priorProduced;
    653654    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    654         if (isa<CircularCopybackBuffer>(mStreamSetOutputBuffers[i]) || isa<SwizzledCopybackBuffer>(mStreamSetOutputBuffers[i]))  {
     655        if (mStreamSetOutputBuffers[i]->supportsCopyBack())  {
    655656            priorProduced.push_back(idb->getProducedItemCount(mStreamSetOutputs[i].name));
    656657        }
     
    661662    unsigned priorIdx = 0;
    662663    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    663         Value * log2BlockSize = idb->getSize(std::log2(idb->getBitBlockWidth()));
    664         if (SwizzledCopybackBuffer * const cb = dyn_cast<SwizzledCopybackBuffer>(mStreamSetOutputBuffers[i]))  {
    665             BasicBlock * copyBack = idb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBack");
    666             BasicBlock * done = idb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBackDone");
    667             Value * newlyProduced = idb->CreateSub(idb->getProducedItemCount(mStreamSetOutputs[i].name), priorProduced[priorIdx]);
    668             Value * priorBlock = idb->CreateLShr(priorProduced[priorIdx], log2BlockSize);
    669             Value * priorOffset = idb->CreateAnd(priorProduced[priorIdx], idb->getSize(idb->getBitBlockWidth() - 1));
    670             Value * instance = idb->getStreamSetBufferPtr(mStreamSetOutputs[i].name);
    671             Value * accessibleBlocks = idb->getLinearlyAccessibleBlocks(mStreamSetOutputs[i].name, priorBlock);
    672             Value * accessible = idb->CreateSub(idb->CreateShl(accessibleBlocks, log2BlockSize), priorOffset);
    673             Value * wraparound = idb->CreateICmpULT(accessible, newlyProduced);
    674             idb->CreateCondBr(wraparound, copyBack, done);
    675             idb->SetInsertPoint(copyBack);
    676             Value * copyItems = idb->CreateSub(newlyProduced, accessible);
    677             cb->createCopyBack(idb.get(), instance, copyItems);
    678             idb->CreateBr(done);
    679             idb->SetInsertPoint(done);
    680             priorIdx++;
    681         }
    682         if (CircularCopybackBuffer * const cb = dyn_cast<CircularCopybackBuffer>(mStreamSetOutputBuffers[i]))  {
    683             BasicBlock * copyBack = idb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBack");
    684             BasicBlock * done = idb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBackDone");
    685             Value * instance = idb->getStreamSetBufferPtr(mStreamSetOutputs[i].name);
    686             Value * newlyProduced = idb->CreateSub(idb->getProducedItemCount(mStreamSetOutputs[i].name), priorProduced[priorIdx]);
    687             Value * accessible = idb->getLinearlyAccessibleItems(mStreamSetOutputs[i].name, priorProduced[priorIdx]);
    688             Value * wraparound = idb->CreateICmpULT(accessible, newlyProduced);
    689             idb->CreateCondBr(wraparound, copyBack, done);
    690             idb->SetInsertPoint(copyBack);
    691             Value * copyItems = idb->CreateSub(newlyProduced, accessible);
    692             cb->createCopyBack(idb.get(), instance, copyItems);
    693             idb->CreateBr(done);
    694             idb->SetInsertPoint(done);
     664        if (mStreamSetOutputBuffers[i]->supportsCopyBack()) {
     665            Value * newProduced = idb->getProducedItemCount(mStreamSetOutputs[i].name);
     666            Value * handle = idb->getStreamSetBufferPtr(mStreamSetOutputs[i].name);
     667            mStreamSetOutputBuffers[i]->genCopyBackLogic(idb.get(), handle, priorProduced[priorIdx], newProduced, mStreamSetOutputs[i].name);
    695668            priorIdx++;
    696669        }
     
    982955
    983956    // Do copybacks if necessary.
    984     unsigned priorIdx = 0;
    985     for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {       
    986         if (auto cb = dyn_cast<SwizzledCopybackBuffer>(mStreamSetOutputBuffers[i]))  {
    987             Value * log2BlockSize = kb->getSize(std::log2(kb->getBitBlockWidth()));
    988             BasicBlock * copyBack = kb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBack");
    989             BasicBlock * done = kb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBackDone");
    990             Value * newlyProduced = kb->CreateSub(kb->getProducedItemCount(mStreamSetOutputs[i].name), producedItemCount[i]);
    991             Value * priorBlock = kb->CreateLShr(producedItemCount[i], log2BlockSize);
    992             Value * priorOffset = kb->CreateAnd(producedItemCount[i], kb->getSize(kb->getBitBlockWidth() - 1));
    993             Value * instance = kb->getStreamSetBufferPtr(mStreamSetOutputs[i].name);
    994             Value * accessibleBlocks = kb->getLinearlyAccessibleBlocks(mStreamSetOutputs[i].name, priorBlock);
    995             Value * accessible = kb->CreateSub(kb->CreateShl(accessibleBlocks, log2BlockSize), priorOffset);
    996             Value * wraparound = kb->CreateICmpULT(accessible, newlyProduced);
    997             kb->CreateCondBr(wraparound, copyBack, done);
    998             kb->SetInsertPoint(copyBack);
    999             Value * copyItems = kb->CreateSub(newlyProduced, accessible);
    1000             cb->createCopyBack(kb.get(), instance, copyItems);
    1001             kb->CreateBr(done);
    1002             kb->SetInsertPoint(done);
    1003             priorIdx++;
    1004         }
    1005         if (auto cb = dyn_cast<CircularCopybackBuffer>(mStreamSetOutputBuffers[i]))  {
    1006             BasicBlock * copyBack = kb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBack");
    1007             BasicBlock * done = kb->CreateBasicBlock(mStreamSetOutputs[i].name + "_copyBackDone");
    1008             Value * instance = kb->getStreamSetBufferPtr(mStreamSetOutputs[i].name);
    1009             Value * newlyProduced = kb->CreateSub(kb->getProducedItemCount(mStreamSetOutputs[i].name), producedItemCount[i]);
    1010             Value * accessible = kb->getLinearlyAccessibleItems(mStreamSetOutputs[i].name, producedItemCount[i]);
    1011             Value * wraparound = kb->CreateICmpULT(accessible, newlyProduced);
    1012             kb->CreateCondBr(wraparound, copyBack, done);
    1013             kb->SetInsertPoint(copyBack);
    1014             Value * copyItems = kb->CreateSub(newlyProduced, accessible);
    1015             cb->createCopyBack(kb.get(), instance, copyItems);
    1016             kb->CreateBr(done);
    1017             kb->SetInsertPoint(done);
    1018             priorIdx++;
     957    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
     958        if (mStreamSetOutputBuffers[i]->supportsCopyBack()) {
     959            Value * newProduced = kb->getProducedItemCount(mStreamSetOutputs[i].name);
     960            Value * handle = mStreamSetOutputBuffers[i]->getStreamSetHandle();
     961            mStreamSetOutputBuffers[i]->genCopyBackLogic(kb.get(), handle, producedItemCount[i], newProduced, mStreamSetOutputs[i].name);
    1019962        }
    1020963    }
  • icGREP/icgrep-devel/icgrep/kernels/streamset.cpp

    r5639 r5641  
    215215}
    216216
     217void StreamSetBuffer::genCopyBackLogic(IDISA::IDISA_Builder * const b, Value * handle, Value * priorProduced, Value * newProduced, const std::string Name) {
     218    report_fatal_error("Copy back not supported for this buffer type:" + Name);
     219}
     220
    217221// Source File Buffer
    218222
     
    328332}
    329333
    330 void CircularCopybackBuffer::createCopyBack(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * overFlowItems) const {
    331     Value * overFlowAreaPtr = iBuilder->CreateGEP(self, iBuilder->getSize(mBufferBlocks));
    332     createBlockAlignedCopy(iBuilder, self, overFlowAreaPtr, overFlowItems);
    333 }
    334 
    335334Value * CircularCopybackBuffer::getLinearlyWritableItems(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromPosition, bool reverse) const {
    336335    Value * accessibleItems = getLinearlyAccessibleItems(iBuilder, self, fromPosition, reverse);
     
    344343    return iBuilder->CreateAdd(accessibleBlocks, iBuilder->getSize(mOverflowBlocks));
    345344}
     345
     346void CircularCopybackBuffer::genCopyBackLogic(IDISA::IDISA_Builder * const b, Value * handle, Value * priorProduced, Value * newProduced, const std::string Name) {
     347    Constant * bufSize = b->getSize(mBufferBlocks * b->getBitBlockWidth());
     348    Value * priorBufPos = b->CreateURem(priorProduced, bufSize);
     349    Value * newBufPos = b->CreateURem(newProduced, bufSize);
     350    BasicBlock * copyBack = b->CreateBasicBlock(Name + "_copyBack");
     351    BasicBlock * done = b->CreateBasicBlock(Name + "_copyBackDone");
     352    Value * wraparound = b->CreateICmpUGT(priorBufPos, newBufPos);
     353    b->CreateCondBr(wraparound, copyBack, done);
     354    b->SetInsertPoint(copyBack);
     355    Value * overFlowAreaPtr = b->CreateGEP(handle, b->getSize(mBufferBlocks));
     356    createBlockAlignedCopy(b, handle, overFlowAreaPtr, newBufPos);
     357    b->CreateBr(done);
     358    b->SetInsertPoint(done);
     359}
     360
    346361
    347362// SwizzledCopybackBuffer Buffer
     
    392407}
    393408
    394 void SwizzledCopybackBuffer::createCopyBack(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * overFlowItems) const {
    395     Value * overFlowAreaPtr = iBuilder->CreateGEP(self, iBuilder->getSize(mBufferBlocks));
    396     createBlockAlignedCopy(iBuilder, self, overFlowAreaPtr, overFlowItems);
    397 }
    398 
    399409Value * SwizzledCopybackBuffer::getStreamSetBlockPtr(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * blockIndex) const {
    400410    return iBuilder->CreateGEP(getBaseAddress(iBuilder, self), modByBufferBlocks(iBuilder, blockIndex));
     
    411421    if (reverse) return accessibleBlocks;
    412422    return iBuilder->CreateAdd(accessibleBlocks, iBuilder->getSize(mOverflowBlocks));
     423}
     424void SwizzledCopybackBuffer::genCopyBackLogic(IDISA::IDISA_Builder * const b, Value * handle, Value * priorProduced, Value * newProduced, const std::string Name) {
     425    Constant * bufSize = b->getSize(mBufferBlocks * b->getBitBlockWidth());
     426    Value * priorBufPos = b->CreateURem(priorProduced, bufSize);
     427    Value * newBufPos = b->CreateURem(newProduced, bufSize);
     428    BasicBlock * copyBack = b->CreateBasicBlock(Name + "_copyBack");
     429    BasicBlock * done = b->CreateBasicBlock(Name + "_copyBackDone");
     430    Value * wraparound = b->CreateICmpUGT(priorBufPos, newBufPos);
     431    b->CreateCondBr(wraparound, copyBack, done);
     432    b->SetInsertPoint(copyBack);
     433    Value * overFlowAreaPtr = b->CreateGEP(handle, b->getSize(mBufferBlocks));
     434    createBlockAlignedCopy(b, handle, overFlowAreaPtr, newBufPos);
     435    b->CreateBr(done);
     436    b->SetInsertPoint(done);
    413437}
    414438
     
    600624: CircularBuffer(BufferKind::CircularCopybackBuffer, b, type, bufferBlocks, AddressSpace)
    601625, mOverflowBlocks(overflowBlocks) {
     626    if (bufferBlocks < 2 * overflowBlocks) {
     627        report_fatal_error("CircularCopybackBuffer: bufferBlocks < 2 * overflowBlocks");
     628    }
    602629    mUniqueID = "CC" + std::to_string(bufferBlocks);
    603630    if (mOverflowBlocks != 1) mUniqueID += "_" + std::to_string(mOverflowBlocks);
     
    615642: StreamSetBuffer(BufferKind::SwizzledCopybackBuffer, type, resolveStreamSetType(b, type), bufferBlocks, AddressSpace), mOverflowBlocks(overflowBlocks), mFieldWidth(fieldwidth) {
    616643    mUniqueID = "SW" + std::to_string(fieldwidth) + ":" + std::to_string(bufferBlocks);
     644    if (bufferBlocks < 2 * overflowBlocks) {
     645        report_fatal_error("SwizzledCopybackBuffer: bufferBlocks < 2 * overflowBlocks");
     646    }
    617647    if (mOverflowBlocks != 1) {
    618648        mUniqueID += "_" + std::to_string(mOverflowBlocks);
     
    683713}
    684714
    685 
     715void DynamicBuffer::genCopyBackLogic(IDISA::IDISA_Builder * const b, Value * handle, Value * priorProducedCount, Value * newProducedCount, const std::string Name) {
     716    Value * workingBlocks = b->CreateLoad(b->CreateGEP(handle, {b->getInt32(0), b->getInt32(int(DynamicBuffer::Field::WorkingBlocks))}));
     717    Value * bufSize = b->CreateMul(workingBlocks, b->getSize(b->getBitBlockWidth()));
     718    Value * priorBufPos = b->CreateURem(priorProducedCount, bufSize);
     719    Value * newBufPos = b->CreateURem(newProducedCount, bufSize);
     720    BasicBlock * copyBack = b->CreateBasicBlock(Name + "_copyBack");
     721    BasicBlock * done = b->CreateBasicBlock(Name + "_copyBackDone");
     722    Value * wraparound = b->CreateICmpUGT(priorBufPos, newBufPos);
     723    b->CreateCondBr(wraparound, copyBack, done);
     724    b->SetInsertPoint(copyBack);
     725    Value * bufBasePtrField = b->CreateGEP(handle, {b->getInt32(0), b->getInt32(int(DynamicBuffer::Field::BaseAddress))});
     726    Value * bufBasePtr = b->CreateLoad(bufBasePtrField);
     727    Value * overFlowAreaPtr = b->CreateGEP(bufBasePtr, workingBlocks);
     728    createBlockAlignedCopy(b, bufBasePtr, overFlowAreaPtr, newBufPos);
     729    b->CreateBr(done);
     730    b->SetInsertPoint(done);
     731}
    686732
    687733void DynamicBuffer::allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & b) {
     
    812858, mOverflowBlocks(overflow)
    813859{
     860    if (initialCapacity * b->getBitBlockWidth() < 2 * overflow) {
     861        report_fatal_error("DynamicBuffer: initialCapacity * b->getBitBlockWidth() < 2 * overflow");
     862    }
    814863    mUniqueID = "DB";
    815864    if (swizzle != 1) {
  • icGREP/icgrep-devel/icgrep/kernels/streamset.h

    r5639 r5641  
    5757        return mStreamSetBufferPtr;
    5858    }
    59 
     59   
    6060    virtual llvm::Type * getStreamSetBlockType() const;
    6161   
     
    9494   
    9595    virtual llvm::Value * getLinearlyWritableBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false) const;
     96   
     97    virtual bool supportsCopyBack() const {
     98        return false;  // Overridden to return true by buffer types that support copyback.
     99    }
     100    virtual void genCopyBackLogic(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * priorProduced, llvm::Value * newProduced, const std::string);
    96101   
    97102    virtual ~StreamSetBuffer() = 0;
     
    227232    CircularCopybackBuffer(const std::unique_ptr<kernel::KernelBuilder> & b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace = 0);
    228233   
    229     // Generate copyback code for the given number of overflowItems.
    230     void createCopyBack(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * overflowItems) const;
    231        
    232234    llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const override;
    233235   
     
    236238    void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override;
    237239
     240    bool supportsCopyBack() const override {
     241        return mOverflowBlocks > 0; 
     242    }
     243   
     244    void genCopyBackLogic(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * priorProduced, llvm::Value * newProduced, const std::string) override;
     245   
     246   
    238247private:
    239248    size_t mOverflowBlocks;
     
    249258    void createBlockAlignedCopy(IDISA::IDISA_Builder * const iBuilder, llvm::Value * targetBlockPtr, llvm::Value * sourceBlockPtr, llvm::Value * itemsToCopy) const override;
    250259
    251     // Generate copyback code for the given number of overflowItems.
    252     void createCopyBack(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * overflowItems) const;
    253    
    254260    llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const override;
    255261   
     
    257263   
    258264    void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override;
     265
     266    bool supportsCopyBack() const override {
     267        return mOverflowBlocks > 0; 
     268    }
     269   
     270    void genCopyBackLogic(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * priorProduced, llvm::Value * newProduced, const std::string) override;
    259271
    260272protected:
     
    314326    llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false) const override;
    315327
    316     virtual llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const;
     328    llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const override;
    317329   
    318330    void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & b) override;
     
    326338    void doubleCapacity(IDISA::IDISA_Builder * const b, llvm::Value * handle);
    327339
     340    bool supportsCopyBack() const override {
     341        return mOverflowBlocks > 0; 
     342    }
     343       
     344    void genCopyBackLogic(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * priorProduced, llvm::Value * newProduced, const std::string) override;
    328345
    329346protected:
Note: See TracChangeset for help on using the changeset viewer.