Ignore:
Timestamp:
May 3, 2017, 6:56:45 PM (2 years ago)
Author:
cameron
Message:

createBlockAlignedCopy as a general utility

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

Legend:

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

    r5431 r5432  
    143143}
    144144
    145 // Single Block Buffer
    146 
    147 // For a single block buffer, the block pointer is always the buffer base pointer.
    148 Value * SingleBlockBuffer::getStreamSetBlockPtr(IDISA_Builder * const, Value * self, Value *) const {
    149     return self;
    150 }
    151 
    152 // Source File Buffer
    153 Value * SourceBuffer::getBufferedSize(IDISA_Builder * const iBuilder, Value * self) const {
    154     Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    155     return iBuilder->CreateLoad(ptr);
    156 }
    157 
    158 void SourceBuffer::setBufferedSize(IDISA_Builder * const iBuilder, Value * self, llvm::Value * size) const {
    159     Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    160     iBuilder->CreateStore(size, ptr);
    161 }
    162 
    163 void SourceBuffer::setBaseAddress(IDISA_Builder * const iBuilder, Value * self, Value * addr) const {
    164     Value * const ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(0)});
    165     iBuilder->CreateStore(iBuilder->CreatePointerCast(addr, ptr->getType()->getPointerElementType()), ptr);
    166 }
    167 
    168 Value * SourceBuffer::getBaseAddress(IDISA_Builder * const iBuilder, Value * const self) const {
    169     Value * const ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(0)});
    170     Value * const addr = iBuilder->CreateLoad(ptr);
    171     return addr;
    172 }
    173 
    174 Value * SourceBuffer::getStreamSetBlockPtr(IDISA_Builder * const iBuilder, Value * self, Value * blockIndex) const {
    175     return iBuilder->CreateGEP(getBaseAddress(iBuilder, self), blockIndex);
    176 }
    177 
    178 Value * SourceBuffer::getLinearlyAccessibleItems(IDISA_Builder * const iBuilder, Value * self, Value *) const {
    179     report_fatal_error("External buffers: getLinearlyAccessibleItems is not supported.");
    180 }
    181 
    182 // External File Buffer
    183 void ExternalBuffer::allocateBuffer(IDISA_Builder * const iBuilder) {
    184     report_fatal_error("External buffers cannot be allocated.");
    185 }
    186 
    187 Value * ExternalBuffer::getStreamSetBlockPtr(IDISA_Builder * const iBuilder, Value * self, Value * blockIndex) const {
    188     return iBuilder->CreateGEP(getBaseAddress(iBuilder, self), blockIndex);
    189 }
    190 
    191 Value * ExternalBuffer::getLinearlyAccessibleItems(IDISA_Builder * const iBuilder, Value *, Value *) const {
    192     report_fatal_error("External buffers: getLinearlyAccessibleItems is not supported.");
    193 }
    194 
    195 // Circular Buffer
    196 Value * CircularBuffer::getStreamSetBlockPtr(IDISA_Builder * const iBuilder, Value * const self, Value * const blockIndex) const {
    197     return iBuilder->CreateGEP(getBaseAddress(iBuilder, self), modByBufferBlocks(iBuilder, blockIndex));
    198 }
    199 
    200 // CircularCopybackBuffer Buffer
    201 void CircularCopybackBuffer::allocateBuffer(IDISA_Builder * const iBuilder) {
    202     mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferBlocks + mOverflowBlocks));
    203 }
    204 
    205 void CircularCopybackBuffer::createCopyBack(IDISA_Builder * const iBuilder, Value * self, Value * overFlowItems) const {
     145void StreamSetBuffer::createBlockAlignedCopy(IDISA_Builder * const iBuilder, Value * targetBlockPtr, Value * sourceBlockPtr, Value * itemsToCopy) const {
    206146    Type * size_ty = iBuilder->getSizeTy();
    207147    Type * i8ptr = iBuilder->getInt8PtrTy();
     
    210150    BasicBlock * wholeBlockCopy = BasicBlock::Create(iBuilder->getContext(), "wholeBlockCopy", f, 0);
    211151    BasicBlock * partialBlockCopy = BasicBlock::Create(iBuilder->getContext(), "partialBlockCopy", f, 0);
    212     BasicBlock * copyBackDone = BasicBlock::Create(iBuilder->getContext(), "copyBackDone", f, 0);
     152    BasicBlock * copyDone = BasicBlock::Create(iBuilder->getContext(), "copyDone", f, 0);
    213153    unsigned numStreams = getType()->getArrayNumElements();
    214154    auto elemTy = getType()->getArrayElementType();
    215155    unsigned fieldWidth = isa<ArrayType>(elemTy) ? elemTy->getArrayNumElements() : 1;
    216     Value * overFlowAreaPtr = iBuilder->CreateGEP(self, iBuilder->getSize(mBufferBlocks));
    217     Value * overFlowBlocks = iBuilder->CreateUDiv(overFlowItems, blockSize);
    218     Value * partialItems = iBuilder->CreateURem(overFlowItems, blockSize);
    219     Value * partialBlockTargetPtr = iBuilder->CreateGEP(self, overFlowBlocks);
    220     Value * partialBlockSourcePtr = iBuilder->CreateGEP(overFlowAreaPtr, overFlowBlocks);
    221     iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(overFlowBlocks, iBuilder->getSize(0)), wholeBlockCopy, partialBlockCopy);
     156    Value * blocksToCopy = iBuilder->CreateUDiv(itemsToCopy, blockSize);
     157    Value * partialItems = iBuilder->CreateURem(itemsToCopy, blockSize);
     158    Value * partialBlockTargetPtr = iBuilder->CreateGEP(targetBlockPtr, blocksToCopy);
     159    Value * partialBlockSourcePtr = iBuilder->CreateGEP(sourceBlockPtr, blocksToCopy);
     160    iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(blocksToCopy, iBuilder->getSize(0)), wholeBlockCopy, partialBlockCopy);
    222161    iBuilder->SetInsertPoint(wholeBlockCopy);
    223162    unsigned alignment = iBuilder->getBitBlockWidth() / 8;
    224     Value * copyLength = iBuilder->CreateSub(iBuilder->CreatePtrToInt(partialBlockTargetPtr, size_ty), iBuilder->CreatePtrToInt(self, size_ty));
    225     iBuilder->CreateMemMove(iBuilder->CreateBitCast(self, i8ptr), iBuilder->CreateBitCast(overFlowAreaPtr, i8ptr), copyLength, alignment);
    226     iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(partialItems, iBuilder->getSize(0)), partialBlockCopy, copyBackDone);
     163    Value * copyLength = iBuilder->CreateSub(iBuilder->CreatePtrToInt(partialBlockTargetPtr, size_ty), iBuilder->CreatePtrToInt(targetBlockPtr, size_ty));
     164    iBuilder->CreateMemMove(iBuilder->CreateBitCast(targetBlockPtr, i8ptr), iBuilder->CreateBitCast(sourceBlockPtr, i8ptr), copyLength, alignment);
     165    iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(partialItems, iBuilder->getSize(0)), partialBlockCopy, copyDone);
    227166    iBuilder->SetInsertPoint(partialBlockCopy);
    228     Value * copyBits = iBuilder->CreateMul(overFlowItems, iBuilder->getSize(fieldWidth));
     167    Value * copyBits = iBuilder->CreateMul(itemsToCopy, iBuilder->getSize(fieldWidth));
    229168    Value * copyBytes = iBuilder->CreateLShr(iBuilder->CreateAdd(copyBits, iBuilder->getSize(7)), iBuilder->getSize(3));
    230169    for (unsigned strm = 0; strm < numStreams; strm++) {
     
    233172        iBuilder->CreateMemMove(iBuilder->CreateBitCast(strmTargetPtr, i8ptr), iBuilder->CreateBitCast(strmSourcePtr, i8ptr), copyBytes, alignment);
    234173    }
    235     iBuilder->CreateBr(copyBackDone);
    236     iBuilder->SetInsertPoint(copyBackDone);
     174    iBuilder->CreateBr(copyDone);
     175    iBuilder->SetInsertPoint(copyDone);
     176}
     177
     178
     179
     180// Single Block Buffer
     181
     182// For a single block buffer, the block pointer is always the buffer base pointer.
     183Value * SingleBlockBuffer::getStreamSetBlockPtr(IDISA_Builder * const, Value * self, Value *) const {
     184    return self;
     185}
     186
     187// Source File Buffer
     188Value * SourceBuffer::getBufferedSize(IDISA_Builder * const iBuilder, Value * self) const {
     189    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
     190    return iBuilder->CreateLoad(ptr);
     191}
     192
     193void SourceBuffer::setBufferedSize(IDISA_Builder * const iBuilder, Value * self, llvm::Value * size) const {
     194    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
     195    iBuilder->CreateStore(size, ptr);
     196}
     197
     198void SourceBuffer::setBaseAddress(IDISA_Builder * const iBuilder, Value * self, Value * addr) const {
     199    Value * const ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(0)});
     200    iBuilder->CreateStore(iBuilder->CreatePointerCast(addr, ptr->getType()->getPointerElementType()), ptr);
     201}
     202
     203Value * SourceBuffer::getBaseAddress(IDISA_Builder * const iBuilder, Value * const self) const {
     204    Value * const ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(0)});
     205    Value * const addr = iBuilder->CreateLoad(ptr);
     206    return addr;
     207}
     208
     209Value * SourceBuffer::getStreamSetBlockPtr(IDISA_Builder * const iBuilder, Value * self, Value * blockIndex) const {
     210    return iBuilder->CreateGEP(getBaseAddress(iBuilder, self), blockIndex);
     211}
     212
     213Value * SourceBuffer::getLinearlyAccessibleItems(IDISA_Builder * const iBuilder, Value * self, Value *) const {
     214    report_fatal_error("External buffers: getLinearlyAccessibleItems is not supported.");
     215}
     216
     217// External File Buffer
     218void ExternalBuffer::allocateBuffer(IDISA_Builder * const iBuilder) {
     219    report_fatal_error("External buffers cannot be allocated.");
     220}
     221
     222Value * ExternalBuffer::getStreamSetBlockPtr(IDISA_Builder * const iBuilder, Value * self, Value * blockIndex) const {
     223    return iBuilder->CreateGEP(getBaseAddress(iBuilder, self), blockIndex);
     224}
     225
     226Value * ExternalBuffer::getLinearlyAccessibleItems(IDISA_Builder * const iBuilder, Value *, Value *) const {
     227    report_fatal_error("External buffers: getLinearlyAccessibleItems is not supported.");
     228}
     229
     230// Circular Buffer
     231Value * CircularBuffer::getStreamSetBlockPtr(IDISA_Builder * const iBuilder, Value * const self, Value * const blockIndex) const {
     232    return iBuilder->CreateGEP(getBaseAddress(iBuilder, self), modByBufferBlocks(iBuilder, blockIndex));
     233}
     234
     235// CircularCopybackBuffer Buffer
     236void CircularCopybackBuffer::allocateBuffer(IDISA_Builder * const iBuilder) {
     237    mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferBlocks + mOverflowBlocks));
     238}
     239
     240void CircularCopybackBuffer::createCopyBack(IDISA_Builder * const iBuilder, Value * self, Value * overFlowItems) const {
     241    Value * overFlowAreaPtr = iBuilder->CreateGEP(self, iBuilder->getSize(mBufferBlocks));
     242    createBlockAlignedCopy(iBuilder, self, overFlowAreaPtr, overFlowItems);
    237243}
    238244
     
    247253}
    248254
    249 void SwizzledCopybackBuffer::createCopyBack(IDISA_Builder * const iBuilder, Value * self, Value * overFlowItems) const {
     255void SwizzledCopybackBuffer::createBlockAlignedCopy(IDISA_Builder * const iBuilder, Value * targetBlockPtr, Value * sourceBlockPtr, Value * itemsToCopy) const {
    250256    Type * size_ty = iBuilder->getSizeTy();
    251257    Type * i8ptr = iBuilder->getInt8PtrTy();
     
    254260    BasicBlock * wholeBlockCopy = BasicBlock::Create(iBuilder->getContext(), "wholeBlockCopy", f, 0);
    255261    BasicBlock * partialBlockCopy = BasicBlock::Create(iBuilder->getContext(), "partialBlockCopy", f, 0);
    256     BasicBlock * copyBackDone = BasicBlock::Create(iBuilder->getContext(), "copyBackDone", f, 0);
     262    BasicBlock * copyDone = BasicBlock::Create(iBuilder->getContext(), "copyDone", f, 0);
    257263    unsigned numStreams = getType()->getArrayNumElements();
    258264    unsigned swizzleFactor = iBuilder->getBitBlockWidth()/mFieldWidth;
    259265    auto elemTy = getType()->getArrayElementType();
    260266    unsigned fieldWidth = isa<ArrayType>(elemTy) ? elemTy->getArrayNumElements() : 1;
    261     Value * overFlowAreaPtr = iBuilder->CreateGEP(self, iBuilder->getSize(mBufferBlocks));
    262     Value * overFlowBlocks = iBuilder->CreateUDiv(overFlowItems, blockSize);
    263     Value * partialItems = iBuilder->CreateURem(overFlowItems, blockSize);
    264     Value * partialBlockTargetPtr = iBuilder->CreateGEP(self, overFlowBlocks);
    265     Value * partialBlockSourcePtr = iBuilder->CreateGEP(overFlowAreaPtr, overFlowBlocks);
    266     iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(overFlowBlocks, iBuilder->getSize(0)), wholeBlockCopy, partialBlockCopy);
     267    Value * blocksToCopy = iBuilder->CreateUDiv(itemsToCopy, blockSize);
     268    Value * partialItems = iBuilder->CreateURem(itemsToCopy, blockSize);
     269    Value * partialBlockTargetPtr = iBuilder->CreateGEP(targetBlockPtr, blocksToCopy);
     270    Value * partialBlockSourcePtr = iBuilder->CreateGEP(sourceBlockPtr, blocksToCopy);
     271    iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(blocksToCopy, iBuilder->getSize(0)), wholeBlockCopy, partialBlockCopy);
    267272    iBuilder->SetInsertPoint(wholeBlockCopy);
    268273    unsigned alignment = iBuilder->getBitBlockWidth() / 8;
    269     Value * copyLength = iBuilder->CreateSub(iBuilder->CreatePtrToInt(partialBlockTargetPtr, size_ty), iBuilder->CreatePtrToInt(self, size_ty));
    270     iBuilder->CreateMemMove(iBuilder->CreateBitCast(self, i8ptr), iBuilder->CreateBitCast(overFlowAreaPtr, i8ptr), copyLength, alignment);
    271     iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(partialItems, iBuilder->getSize(0)), partialBlockCopy, copyBackDone);
     274    Value * copyLength = iBuilder->CreateSub(iBuilder->CreatePtrToInt(partialBlockTargetPtr, size_ty), iBuilder->CreatePtrToInt(targetBlockPtr, size_ty));
     275    iBuilder->CreateMemMove(iBuilder->CreateBitCast(targetBlockPtr, i8ptr), iBuilder->CreateBitCast(sourceBlockPtr, i8ptr), copyLength, alignment);
     276    iBuilder->CreateCondBr(iBuilder->CreateICmpUGT(partialItems, iBuilder->getSize(0)), partialBlockCopy, copyDone);
    272277    iBuilder->SetInsertPoint(partialBlockCopy);
    273     Value * copyBits = iBuilder->CreateMul(overFlowItems, iBuilder->getSize(fieldWidth * swizzleFactor));
     278    Value * copyBits = iBuilder->CreateMul(itemsToCopy, iBuilder->getSize(fieldWidth * swizzleFactor));
    274279    Value * copyBytes = iBuilder->CreateLShr(iBuilder->CreateAdd(copyBits, iBuilder->getSize(7)), iBuilder->getSize(3));
    275280    for (unsigned strm = 0; strm < numStreams; strm += swizzleFactor) {
     
    278283        iBuilder->CreateMemMove(iBuilder->CreateBitCast(strmTargetPtr, i8ptr), iBuilder->CreateBitCast(strmSourcePtr, i8ptr), copyBytes, alignment);
    279284    }
    280     iBuilder->CreateBr(copyBackDone);
    281     iBuilder->SetInsertPoint(copyBackDone);
     285    iBuilder->CreateBr(copyDone);
     286    iBuilder->SetInsertPoint(copyDone);
     287}
     288
     289void SwizzledCopybackBuffer::createCopyBack(IDISA_Builder * const iBuilder, Value * self, Value * overFlowItems) const {
     290    Value * overFlowAreaPtr = iBuilder->CreateGEP(self, iBuilder->getSize(mBufferBlocks));
     291    createBlockAlignedCopy(iBuilder, self, overFlowAreaPtr, overFlowItems);
    282292}
    283293
  • icGREP/icgrep-devel/icgrep/kernels/streamset.h

    r5431 r5432  
    7979
    8080    virtual llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock) const;
     81   
     82    virtual void createBlockAlignedCopy(IDISA::IDISA_Builder * const iBuilder, llvm::Value * targetBlockPtr, llvm::Value * sourceBlockPtr, llvm::Value * itemsToCopy) const;
    8183
    8284    virtual void reserveBytes(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * requested) const;
     
    227229    void allocateBuffer(IDISA::IDISA_Builder * const iBuilder) override;
    228230   
     231    void createBlockAlignedCopy(IDISA::IDISA_Builder * const iBuilder, llvm::Value * targetBlockPtr, llvm::Value * sourceBlockPtr, llvm::Value * itemsToCopy) const override;
     232
    229233    // Generate copyback code for the given number of overflowItems.
    230234    void createCopyBack(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * overflowItems) const;
     235   
    231236protected:
    232237    llvm::Value * getStreamSetBlockPtr(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * blockIndex) const override;
Note: See TracChangeset for help on using the changeset viewer.