Changeset 6018


Ignore:
Timestamp:
May 6, 2018, 1:46:57 PM (5 months ago)
Author:
cameron
Message:

PEXTFieldCompressKernel

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

Legend:

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

    r6014 r6018  
    118118}
    119119
     120void PEXTFieldCompressKernel::generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & kb, llvm::Value * const numOfBlocks) {
     121    Type * fieldTy = kb->getIntNTy(mPEXTWidth);
     122    Type * fieldPtrTy = PointerType::get(fieldTy, 0);
     123    Constant * PEXT_func = nullptr;
     124    Constant * popc_func = Intrinsic::getDeclaration(getModule(), Intrinsic::ctpop, fieldTy);
     125    if (mPEXTWidth == 64) {
     126        PEXT_func = Intrinsic::getDeclaration(kb->getModule(), Intrinsic::x86_bmi_pext_64);
     127    } else if (mPEXTWidth == 32) {
     128        PEXT_func = Intrinsic::getDeclaration(kb->getModule(), Intrinsic::x86_bmi_pext_32);
     129    }
     130    BasicBlock * entry = kb->GetInsertBlock();
     131    BasicBlock * processBlock = kb->CreateBasicBlock("processBlock");
     132    BasicBlock * done = kb->CreateBasicBlock("done");
     133    Constant * const ZERO = kb->getSize(0);
     134    const unsigned fieldsPerBlock = kb->getBitBlockWidth()/mPEXTWidth;
     135    kb->CreateBr(processBlock);
     136    kb->SetInsertPoint(processBlock);
     137    PHINode * blockOffsetPhi = kb->CreatePHI(kb->getSizeTy(), 2);
     138    blockOffsetPhi->addIncoming(ZERO, entry);
     139    std::vector<Value *> mask(fieldsPerBlock);
     140    Value * extractionMaskPtr = kb->getInputStreamBlockPtr("extractionMask", ZERO, blockOffsetPhi);
     141    extractionMaskPtr = kb->CreatePointerCast(extractionMaskPtr, fieldPtrTy);
     142    Value * unitCountPtr = kb->getOutputStreamBlockPtr("unitCounts", ZERO, blockOffsetPhi);
     143    unitCountPtr = kb->CreatePointerCast(unitCountPtr, fieldPtrTy);
     144    for (unsigned i = 0; i < fieldsPerBlock; i++) {
     145        mask[i] = kb->CreateLoad(kb->CreateGEP(extractionMaskPtr, kb->getInt32(i)));
     146        Value * popc = kb->CreateCall(popc_func, mask[i]);
     147        kb->CreateStore(popc, kb->CreateGEP(unitCountPtr, kb->getInt32(i)));
     148    }
     149    for (unsigned j = 0; j < mStreamCount; ++j) {
     150        Value * inputPtr = kb->getInputStreamBlockPtr("inputStreamSet", kb->getInt32(j), blockOffsetPhi);
     151        inputPtr = kb->CreatePointerCast(inputPtr, fieldPtrTy);
     152        Value * outputPtr = kb->getOutputStreamBlockPtr("outputStreamSet", kb->getInt32(j), blockOffsetPhi);
     153        outputPtr = kb->CreatePointerCast(outputPtr, fieldPtrTy);
     154        for (unsigned i = 0; i < fieldsPerBlock; i++) {
     155            Value * field = kb->CreateLoad(kb->CreateGEP(inputPtr, kb->getInt32(i)));
     156            Value * compressed = kb->CreateCall(PEXT_func, {field, mask[i]});
     157            kb->CreateStore(compressed, kb->CreateGEP(outputPtr, kb->getInt32(i)));
     158        }
     159    }
     160    Value * nextBlk = kb->CreateAdd(blockOffsetPhi, kb->getSize(1));
     161    blockOffsetPhi->addIncoming(nextBlk, processBlock);
     162    Value * moreToDo = kb->CreateICmpNE(nextBlk, numOfBlocks);
     163    kb->CreateCondBr(moreToDo, processBlock, done);
     164    kb->SetInsertPoint(done);
     165}
     166
     167PEXTFieldCompressKernel::PEXTFieldCompressKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, const unsigned fieldWidth, const unsigned streamCount)
     168: MultiBlockKernel("PEXTfieldCompress" + std::to_string(fieldWidth) + "_" + std::to_string(streamCount),
     169                   {Binding{kb->getStreamSetTy(streamCount), "inputStreamSet"},
     170                       Binding{kb->getStreamSetTy(), "extractionMask"}},
     171                   {Binding{kb->getStreamSetTy(streamCount), "outputStreamSet"},
     172                       Binding{kb->getStreamSetTy(), "unitCounts", FixedRate(), RoundUpTo(kb->getBitBlockWidth())}},
     173                   {}, {}, {})
     174, mPEXTWidth(fieldWidth)
     175, mStreamCount(streamCount) {
     176    if ((fieldWidth != 32) && (fieldWidth != 64)) llvm::report_fatal_error("Unsupported PEXT width for PEXTFieldCompressKernel");
     177}
     178   
    120179StreamCompressKernel::StreamCompressKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, const unsigned fieldWidth, const unsigned streamCount)
    121180: MultiBlockKernel("streamCompress" + std::to_string(fieldWidth) + "_" + std::to_string(streamCount),
  • icGREP/icgrep-devel/icgrep/kernels/deletion.h

    r6013 r6018  
    4444private:
    4545    const unsigned mCompressFieldWidth;
     46    const unsigned mStreamCount;
     47};
     48
     49class PEXTFieldCompressKernel final : public MultiBlockKernel {
     50public:
     51    PEXTFieldCompressKernel(const std::unique_ptr<kernel::KernelBuilder> & b, unsigned fw, unsigned streamCount);
     52    bool isCachable() const override { return true; }
     53    bool hasSignature() const override { return false; }
     54protected:
     55    void generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & kb, llvm::Value * const numOfStrides) override;
     56private:
     57    const unsigned mPEXTWidth;
    4658    const unsigned mStreamCount;
    4759};
Note: See TracChangeset for help on using the changeset viewer.