Ignore:
Timestamp:
Feb 3, 2017, 1:25:53 PM (3 years ago)
Author:
nmedfort
Message:

Partial removal of BlockNo?

File:
1 edited

Legend:

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

    r5292 r5297  
    55
    66#include "kernel.h"
    7 #include <llvm/IR/Value.h>               // for Value
    8 #include <llvm/Support/ErrorHandling.h>  // for report_fatal_error
    9 #include <toolchain.h>                   // for BufferSegments, SegmentSize
    10 #include <kernels/streamset.h>           // for StreamSetBuffer
    11 #include <llvm/ADT/StringRef.h>          // for StringRef, operator==
    12 #include <llvm/IR/CallingConv.h>         // for ::C
    13 #include <llvm/IR/Constant.h>            // for Constant
    14 #include <llvm/IR/Constants.h>           // for ConstantInt
    15 #include <llvm/IR/Function.h>            // for Function, Function::arg_iter...
    16 #include <llvm/IR/Instructions.h>        // for LoadInst (ptr only), PHINode
     7#include <toolchain.h>
     8#include <kernels/streamset.h>
     9#include <IR_Gen/types/streamtype.h>
     10#include <llvm/IR/Constants.h>
     11#include <llvm/IR/Function.h>
     12#include <llvm/IR/Instructions.h>
    1713#include <llvm/IR/Module.h>
    18 #include <llvm/Support/Compiler.h>       // for LLVM_UNLIKELY
    1914#include <llvm/Support/raw_ostream.h>
    20 namespace llvm { class BasicBlock; }
    21 namespace llvm { class Type; }
    2215
    2316static const auto BLOCK_NO_SCALAR = "blockNo";
     
    4235using namespace kernel;
    4336using namespace parabix;
     37
     38using StreamType = IDISA::StreamType;
    4439
    4540unsigned KernelBuilder::addScalar(Type * const type, const std::string & name) {
     
    8479        throw std::runtime_error(out.str());
    8580    }
    86     int streamSetNo = 0;
    8781    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    8882        if ((mStreamSetInputBuffers[i]->getBufferSize() > 0) && (mStreamSetInputBuffers[i]->getBufferSize() < codegen::SegmentSize + (blockSize + mLookAheadPositions - 1)/blockSize)) {
    8983             llvm::report_fatal_error("Kernel preparation: Buffer size too small " + mStreamSetInputs[i].name);
    9084        }
    91         mScalarInputs.push_back(Binding{mStreamSetInputBuffers[i]->getStreamBufferPointerType(), mStreamSetInputs[i].name + BUFFER_PTR_SUFFIX});
    92         mStreamSetNameMap.emplace(mStreamSetInputs[i].name, streamSetNo);
     85        mScalarInputs.push_back(Binding{mStreamSetInputBuffers[i]->getPointerType(), mStreamSetInputs[i].name + BUFFER_PTR_SUFFIX});
     86        mStreamSetNameMap.emplace(mStreamSetInputs[i].name, i);
    9387        addScalar(iBuilder->getSizeTy(), mStreamSetInputs[i].name + PROCESSED_ITEM_COUNT_SUFFIX);
    94         streamSetNo++;
    9588    }
    9689    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    97         mScalarInputs.push_back(Binding{mStreamSetOutputBuffers[i]->getStreamBufferPointerType(), mStreamSetOutputs[i].name + BUFFER_PTR_SUFFIX});
    98         mStreamSetNameMap.emplace(mStreamSetOutputs[i].name, streamSetNo);
     90        mScalarInputs.push_back(Binding{mStreamSetOutputBuffers[i]->getPointerType(), mStreamSetOutputs[i].name + BUFFER_PTR_SUFFIX});
     91        mStreamSetNameMap.emplace(mStreamSetOutputs[i].name, mStreamSetInputs.size() + i);
    9992        addScalar(iBuilder->getSizeTy(), mStreamSetOutputs[i].name + PRODUCED_ITEM_COUNT_SUFFIX);
    100         streamSetNo++;
    10193    }
    10294    for (auto binding : mScalarInputs) {
     
    112104    addScalar(iBuilder->getSizeTy(), LOGICAL_SEGMENT_NO_SCALAR);
    113105    addScalar(iBuilder->getInt1Ty(), TERMINATION_SIGNAL);
    114     mKernelStateType = StructType::create(iBuilder->getContext(), mKernelFields, mKernelName);
     106    mKernelStateType = StructType::create(iBuilder->getContext(), mKernelFields, getName());
    115107}
    116108
     
    118110    auto saveModule = iBuilder->getModule();
    119111    auto savePoint = iBuilder->saveIP();
    120     auto module = make_unique<Module>(mKernelName + "_" + iBuilder->getBitBlockTypeName(), iBuilder->getContext());
     112    auto module = make_unique<Module>(getName() + "_" + iBuilder->getBitBlockTypeName(), iBuilder->getContext());
    121113    iBuilder->setModule(module.get());
    122114    generateKernel(inputs, outputs);
     
    150142void KernelBuilder::callGenerateDoSegmentMethod() {
    151143    mCurrentFunction = getDoSegmentFunction();
    152     iBuilder->SetInsertPoint(CreateBasicBlock(mKernelName + "_entry"));
     144    iBuilder->SetInsertPoint(CreateBasicBlock(getName() + "_entry"));
    153145    auto args = mCurrentFunction->arg_begin();
    154146    mSelf = &*(args++);
     
    247239
    248240Value * KernelBuilder::getBlockNo() const {
    249     Value * ptr = iBuilder->CreateGEP(mSelf, {iBuilder->getInt32(0), getScalarIndex(BLOCK_NO_SCALAR)});
    250     return iBuilder->CreateLoad(ptr);
     241    return getScalarField(mSelf, BLOCK_NO_SCALAR);
    251242}
    252243
    253244void KernelBuilder::setBlockNo(Value * value) const {
    254     Value * ptr = iBuilder->CreateGEP(mSelf, {iBuilder->getInt32(0), getScalarIndex(BLOCK_NO_SCALAR)});
    255     iBuilder->CreateStore(value, ptr);
     245    setScalarField(mSelf, BLOCK_NO_SCALAR, value);
     246}
     247
     248llvm::Value * KernelBuilder::getInputStream(const std::string & name, llvm::Value * index) const {
     249    Value * ic = getProcessedItemCount(name);
     250    const StreamSetBuffer * buf = getStreamSetBuffer(name);
     251    ic = iBuilder->CreateUDiv(ic, iBuilder->getSize(iBuilder->getBitBlockWidth()));
     252    return buf->getStream(getStreamSetBufferPtr(name), ic, index);
     253}
     254
     255llvm::Value * KernelBuilder::getInputStream(const std::string & name, llvm::Value * index1, llvm::Value * index2) const {
     256    Value * ic = getProcessedItemCount(name);
     257    const StreamSetBuffer * buf = getStreamSetBuffer(name);
     258    ic = iBuilder->CreateUDiv(ic, iBuilder->getSize(iBuilder->getBitBlockWidth()));
     259    return buf->getStream(getStreamSetBufferPtr(name), ic, index1, index2);
     260}
     261
     262llvm::Value * KernelBuilder::getOutputStream(const std::string & name, llvm::Value * index) const {
     263    Value * ic = getProducedItemCount(name);
     264    const StreamSetBuffer * buf = getStreamSetBuffer(name);
     265    ic = iBuilder->CreateUDiv(ic, iBuilder->getSize(iBuilder->getBitBlockWidth()));
     266    return buf->getStream(getStreamSetBufferPtr(name), ic, index);
     267}
     268
     269llvm::Value * KernelBuilder::getOutputStream(const std::string & name, llvm::Value * index1, llvm::Value * index2) const {
     270    Value * ic = getProducedItemCount(name);
     271    const StreamSetBuffer * buf = getStreamSetBuffer(name);
     272    ic = iBuilder->CreateUDiv(ic, iBuilder->getSize(iBuilder->getBitBlockWidth()));
     273    return buf->getStream(getStreamSetBufferPtr(name), ic, index1, index2);
     274}
     275
     276Value * KernelBuilder::getStreamView(llvm::Type * type, const std::string & name, Value * blockNo, Value * index) const {
     277    return getStreamSetBuffer(name)->getStreamView(type, getStreamSetBufferPtr(name), blockNo, index);
    256278}
    257279
     
    273295}
    274296
    275 inline Value * KernelBuilder::getStreamSetBufferPtr(llvm::Value * instance, const std::string & name) const {
    276     return getScalarField(instance, name + BUFFER_PTR_SUFFIX);
    277 }
    278 
    279 inline Value * KernelBuilder::getStreamSetBufferPtr(llvm::Value * instance, llvm::Value * index) const {
    280     return getScalarField(instance, index);
     297inline Value * KernelBuilder::getStreamSetBufferPtr(const std::string & name) const {
     298    return getScalarField(getSelf(), name + BUFFER_PTR_SUFFIX);
     299}
     300
     301inline Value * KernelBuilder::getStreamSetBufferPtr(llvm::Value * index) const {
     302    return getScalarField(getSelf(), index);
    281303}
    282304
     
    302324}
    303325
    304 Value * KernelBuilder::getStream(const std::string & name, Value * blockNo, Value * index) const {
    305     return getStreamSetBuffer(name)->getStream(getStreamSetBufferPtr(name), blockNo, index);
    306 }
    307 
    308 Value * KernelBuilder::getStream(const std::string & name, Value * blockNo, Value * index1, Value * index2) const {
    309     assert (index1->getType() == index2->getType());
    310     return getStreamSetBuffer(name)->getStream(getStreamSetBufferPtr(name), blockNo, index1, index2);
    311 }
    312 
    313 Value * KernelBuilder::getStreamView(const std::string & name, Value * blockNo, Value * index) const {
    314     return getStreamSetBuffer(name)->getStreamView(getStreamSetBufferPtr(name), blockNo, index);
    315 }
    316 
    317 Value * KernelBuilder::getStreamView(llvm::Type * type, const std::string & name, Value * blockNo, Value * index) const {
    318     return getStreamSetBuffer(name)->getStreamView(type, getStreamSetBufferPtr(name), blockNo, index);
    319 }
    320 
    321326BasicBlock * KernelBuilder::CreateBasicBlock(std::string && name) const {
    322327    return BasicBlock::Create(iBuilder->getContext(), name, mCurrentFunction);
     
    343348
    344349//  The default finalBlock method simply dispatches to the doBlock routine.
    345 void BlockOrientedKernel::generateFinalBlockMethod(Value * remainingBytes, Value * blockNo) {
     350void BlockOrientedKernel::generateFinalBlockMethod(Value * remainingBytes) {
    346351//    std::vector<Value *> args = {self};
    347352//    for (Argument & arg : function->getArgumentList()){
     
    353358//  The default doSegment method dispatches to the doBlock routine for
    354359//  each block of the given number of blocksToDo, and then updates counts.
    355 void BlockOrientedKernel::generateDoSegmentMethod(Value * doFinal, const std::vector<Value *> &producerPos) {
     360void BlockOrientedKernel::generateDoSegmentMethod(Value * doFinal, const std::vector<Value *> & producerPos) {
    356361
    357362    BasicBlock * const entryBlock = iBuilder->GetInsertBlock();
    358     BasicBlock * const strideLoopCond = CreateBasicBlock(mKernelName + "_strideLoopCond");
    359     BasicBlock * const strideLoopBody = CreateBasicBlock(mKernelName + "_strideLoopBody");
    360     BasicBlock * const stridesDone = CreateBasicBlock(mKernelName + "_stridesDone");
    361     BasicBlock * const doFinalBlock = CreateBasicBlock(mKernelName + "_doFinalBlock");
    362     BasicBlock * const segmentDone = CreateBasicBlock(mKernelName + "_segmentDone");
     363    BasicBlock * const strideLoopCond = CreateBasicBlock(getName() + "_strideLoopCond");
     364    BasicBlock * const strideLoopBody = CreateBasicBlock(getName() + "_strideLoopBody");
     365    BasicBlock * const stridesDone = CreateBasicBlock(getName() + "_stridesDone");
     366    BasicBlock * const doFinalBlock = CreateBasicBlock(getName() + "_doFinalBlock");
     367    BasicBlock * const segmentDone = CreateBasicBlock(getName() + "_segmentDone");
    363368
    364369    ConstantInt * stride = iBuilder->getSize(iBuilder->getStride());
     
    370375        availablePos = iBuilder->CreateSelect(iBuilder->CreateICmpULT(availablePos, p), availablePos, p);
    371376    }
     377
    372378    Value * processed = getProcessedItemCount(mStreamSetInputs[0].name);
    373379    Value * itemsAvail = iBuilder->CreateSub(availablePos, processed);
     
    378384    PHINode * stridesRemaining = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2, "stridesRemaining");
    379385    stridesRemaining->addIncoming(stridesToDo, entryBlock);
    380     Value * notDone = iBuilder->CreateICmpUGT(stridesRemaining, iBuilder->getSize(0));
     386    Value * notDone = iBuilder->CreateICmpNE(stridesRemaining, iBuilder->getSize(0));
    381387    iBuilder->CreateCondBr(notDone, strideLoopBody, stridesDone);
    382388
     
    387393
    388394    setBlockNo(iBuilder->CreateAdd(blockNo, strideBlocks));
     395
     396    // Update counts
     397
     398    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
     399        Value * processed = getProcessedItemCount(mStreamSetInputs[i].name);
     400        processed = iBuilder->CreateAdd(processed, stride);
     401        setProcessedItemCount(mStreamSetInputs[i].name, processed);
     402    }
     403
     404    if (!mDoBlockUpdatesProducedItemCountsAttribute) {
     405        for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
     406            Value * produced = getProducedItemCount(mStreamSetOutputs[i].name);
     407            produced = iBuilder->CreateAdd(produced, stride);
     408            setProducedItemCount(mStreamSetOutputs[i].name, produced);
     409        }
     410    }
     411
    389412    stridesRemaining->addIncoming(iBuilder->CreateSub(stridesRemaining, iBuilder->getSize(1)), strideLoopBody);
    390413    iBuilder->CreateBr(strideLoopCond);
    391414
    392415    iBuilder->SetInsertPoint(stridesDone);
    393     // Update counts for the full strides processed.
    394     Value * segmentItemsProcessed = iBuilder->CreateMul(stridesToDo, stride);
    395     for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    396         Value * preProcessed = getProcessedItemCount(mStreamSetInputs[i].name);
    397         setProcessedItemCount(mStreamSetInputs[i].name, iBuilder->CreateAdd(preProcessed, segmentItemsProcessed));
    398     }
    399     if (!mDoBlockUpdatesProducedItemCountsAttribute) {
    400         for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    401             Value * preProduced = getProducedItemCount(mStreamSetOutputs[i].name);
    402             setProducedItemCount(mStreamSetOutputs[i].name, iBuilder->CreateAdd(preProduced, segmentItemsProcessed));
    403         }
    404     }
    405416
    406417    // Now conditionally perform the final block processing depending on the doFinal parameter.
     
    441452    mSelf = &(*args);
    442453    iBuilder->SetInsertPoint(CreateBasicBlock("entry"));
    443     generateDoBlockMethod(getBlockNo()); // must be implemented by the KernelBuilder subtype
     454    generateDoBlockMethod(); // must be implemented by the KernelBuilder subtype
    444455    iBuilder->CreateRetVoid();
    445456}
     
    452463    Value * const remainingBytes = &(*args);
    453464    iBuilder->SetInsertPoint(CreateBasicBlock("entry"));
    454     generateFinalBlockMethod(remainingBytes, getBlockNo()); // possibly overridden by the KernelBuilder subtype
     465    generateFinalBlockMethod(remainingBytes); // possibly overridden by the KernelBuilder subtype
    455466    iBuilder->CreateRetVoid();
    456467}
    457468
    458469Function * BlockOrientedKernel::getDoBlockFunction() const {
    459     const auto name = mKernelName + DO_BLOCK_SUFFIX;
     470    const auto name = getName() + DO_BLOCK_SUFFIX;
    460471    Function * const f = iBuilder->getModule()->getFunction(name);
    461472    if (LLVM_UNLIKELY(f == nullptr)) {
     
    470481
    471482Function * BlockOrientedKernel::getDoFinalBlockFunction() const {
    472     const auto name = mKernelName + FINAL_BLOCK_SUFFIX;
     483    const auto name = getName() + FINAL_BLOCK_SUFFIX;
    473484    Function * const f = iBuilder->getModule()->getFunction(name);
    474485    if (LLVM_UNLIKELY(f == nullptr)) {
     
    485496    // Create the doBlock and finalBlock function prototypes
    486497    FunctionType * const doBlockType = FunctionType::get(iBuilder->getVoidTy(), {selfType}, false);
    487     Function * const doBlock = Function::Create(doBlockType, GlobalValue::ExternalLinkage, mKernelName + DO_BLOCK_SUFFIX, m);
     498    Function * const doBlock = Function::Create(doBlockType, GlobalValue::ExternalLinkage, getName() + DO_BLOCK_SUFFIX, m);
    488499    doBlock->setCallingConv(CallingConv::C);
    489500    doBlock->setDoesNotThrow();
     
    491502    auto args = doBlock->arg_begin();
    492503    args->setName("self");
     504    assert ((++args) == doBlock->arg_end());
    493505
    494506    FunctionType * const finalBlockType = FunctionType::get(iBuilder->getVoidTy(), {selfType, iBuilder->getSizeTy()}, false);
    495     Function * const finalBlock = Function::Create(finalBlockType, GlobalValue::ExternalLinkage, mKernelName + FINAL_BLOCK_SUFFIX, m);
     507    Function * const finalBlock = Function::Create(finalBlockType, GlobalValue::ExternalLinkage, getName() + FINAL_BLOCK_SUFFIX, m);
    496508    finalBlock->setCallingConv(CallingConv::C);
    497509    finalBlock->setDoesNotThrow();
    498510    finalBlock->setDoesNotCapture(1);
    499511    args = finalBlock->arg_begin();
    500     args++->setName("self");
    501     args->setName("remainingBytes");
     512    args->setName("self");
     513    (++args)->setName("remainingBytes");
     514    assert ((++args) == finalBlock->arg_end());
    502515}
    503516
Note: See TracChangeset for help on using the changeset viewer.