Changeset 5086


Ignore:
Timestamp:
Jul 15, 2016, 10:04:55 PM (3 years ago)
Author:
cameron
Message:

Initial doSegment support; pipeline generation

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

Legend:

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

    r5076 r5086  
    105105        finalBlockArg->setName(outputSet.ssName);
    106106    }
     107   
     108    // Create the doSegment function prototype.
     109    std::vector<Type *> doSegmentParameters = {selfType, iBuilder->getInt64Ty()};
     110    FunctionType * doSegmentFunctionType = FunctionType::get(mDoBlockReturnType, doSegmentParameters, false);
     111    std::string doSegmentName = mKernelName + doSegment_suffix;
     112    Function * doSegmentFn = Function::Create(doSegmentFunctionType, GlobalValue::ExternalLinkage, doSegmentName, client);
     113    doSegmentFn->setCallingConv(CallingConv::C);
     114    doSegmentFn->setDoesNotThrow();
     115    for (int i = 1; i <= doBlockParameters.size(); i++) {
     116        doSegmentFn->setDoesNotCapture(i);
     117    }
    107118    iBuilder->setModule(saveModule);
    108119    iBuilder->restoreIP(savePoint);
     
    129140}
    130141
     142Value * KernelInterface::createInstance(std::vector<Value *> args,
     143                                        std::vector<StreamSetBuffer *> inputBuffers,
     144                                        std::vector<StreamSetBuffer *> outputBuffers) {
     145    Value * kernelInstance = iBuilder->CreateAlloca(mKernelStateType);
     146    Module * m = iBuilder->getModule();
     147    std::vector<Value *> init_args = {kernelInstance};
     148    for (auto a : args) {
     149        init_args.push_back(a);
     150    }
     151    for (auto b : inputBuffers) {
     152        init_args.push_back(b->getStreamSetBufferPtr());
     153        init_args.push_back(iBuilder->getInt64(b->getSegmentSize() - 1));
     154    }
     155    for (auto b : outputBuffers) {
     156        init_args.push_back(b->getStreamSetBufferPtr());
     157        init_args.push_back(iBuilder->getInt64(b->getSegmentSize() - 1));
     158    }
     159    std::string initFnName = mKernelName + init_suffix;
     160    Function * initMethod = m->getFunction(initFnName);
     161    if (!initMethod) {
     162        throw std::runtime_error("Cannot find " + initFnName);
     163    }
     164    iBuilder->CreateCall(initMethod, init_args);
     165    return kernelInstance;
     166}
     167
     168
     169
     170
    131171Value * KernelInterface::createDoBlockCall(Value * self, std::vector<Value *> streamSets) {
    132172    Module * m = iBuilder->getModule();
     
    157197}
    158198
     199Value * KernelInterface::createDoSegmentCall(Value * self, Value * blksToDo) {
     200    Module * m = iBuilder->getModule();
     201    std::string fnName = mKernelName + doSegment_suffix;
     202    Function * method = m->getFunction(fnName);
     203    if (!method) {
     204        throw std::runtime_error("Cannot find " + fnName);
     205    }
     206    std::vector<Value *> args = {self, blksToDo};
     207    return iBuilder->CreateCall(method, args);
     208}
     209
    159210Value * KernelInterface::createGetAccumulatorCall(Value * self, std::string accumName) {
    160211    Module * m = iBuilder->getModule();
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5076 r5086  
    1414#include "streamset.h"
    1515
     16   
    1617struct ScalarBinding {
    1718    llvm::Type * scalarType;
     
    2627const std::string init_suffix = "_Init";
    2728const std::string doBlock_suffix = "_DoBlock";
     29const std::string doSegment_suffix = "_DoSegment";
    2830const std::string finalBlock_suffix = "_FinalBlock";
    2931const std::string accumulator_infix = "_get_";
     
    5456   
    5557    llvm::Value * createInstance(std::vector<llvm::Value *> initialParameters);
     58    llvm::Value * createInstance(std::vector<llvm::Value *> initialParameters, std::vector<kernel::StreamSetBuffer *> inputs, std::vector<kernel::StreamSetBuffer *> outputBuffers);
    5659    llvm::Value * createDoBlockCall(llvm::Value * kernelInstance, std::vector<Value *> streamSets);
     60    llvm::Value * createDoSegmentCall(llvm::Value * kernelInstance, llvm::Value * blkCount);
    5761    llvm::Value * createFinalBlockCall(llvm::Value * kernelInstance, llvm::Value * remainingBytes, std::vector<llvm::Value *> streamSets);
    5862    llvm::Value * createGetAccumulatorCall(llvm::Value * kernelInstance, std::string accumName);
    5963   
    60 protected:
     64//protected:
    6165   
    6266    IDISA::IDISA_Builder * iBuilder;
     
    7074    llvm::Type * mKernelStateType;
    7175};
    72 
    7376#endif
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5076 r5086  
    3737void KernelBuilder::prepareKernel() {
    3838    if (!mDoBlockReturnType) mDoBlockReturnType = iBuilder->getVoidTy();
     39    addScalar(iBuilder->getInt64Ty(), blockNoScalar);
     40    for (auto sSet : mStreamSetInputs) {
     41        mScalarInputs.push_back(ScalarBinding{PointerType::get(sSet.ssType.getStreamSetBlockType(iBuilder), 0), sSet.ssName + basePtrSuffix});
     42        mScalarInputs.push_back(ScalarBinding{iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix});
     43        //Or possibly add as internal state, with code in init function:  addScalar(iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix);
     44    }
     45    for (auto sSet : mStreamSetOutputs) {
     46        mScalarInputs.push_back(ScalarBinding{PointerType::get(sSet.ssType.getStreamSetBlockType(iBuilder), 0), sSet.ssName + basePtrSuffix});
     47        mScalarInputs.push_back(ScalarBinding{iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix});
     48        //Or possibly add as internal state, with code in init function:  addScalar(iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix);
     49    }
    3950    for (auto binding : mScalarInputs) {
    4051        addScalar(binding.scalarType, binding.scalarName);
     
    6980    generateDoBlockMethod();     // must be implemented by the KernelBuilder subtype
    7081    generateFinalBlockMethod();  // possibly overriden by the KernelBuilder subtype
     82    generateDoSegmentMethod();
    7183
    7284    // Implement the accumulator get functions
     
    121133}
    122134
     135//  The default doSegment method simply dispatches to the doBlock routine.
     136void KernelBuilder::generateDoSegmentMethod() {
     137    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     138    Module * m = iBuilder->getModule();
     139    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
     140    Function * doSegmentFunction = m->getFunction(mKernelName + doSegment_suffix);
     141    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doSegmentFunction, 0));
     142    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
     143    BasicBlock * blockLoop = BasicBlock::Create(iBuilder->getContext(), "blockLoop", doSegmentFunction, 0);
     144    BasicBlock * blocksDone = BasicBlock::Create(iBuilder->getContext(), "blocksDone", doSegmentFunction, 0);
     145
     146   
     147    Function::arg_iterator args = doSegmentFunction->arg_begin();
     148    Value * self = &*(args++);
     149    Value * blocksToDo = &*(args);
     150   
     151    std::vector<Value *> basePtrs;
     152    std::vector<Value *> blockMasks;
     153    for (auto sSet : mStreamSetInputs) {
     154        basePtrs.push_back(getScalarField(self, sSet.ssName + basePtrSuffix));
     155        blockMasks.push_back(getScalarField(self, sSet.ssName + blkMaskSuffix));
     156    }
     157    for (auto sSet : mStreamSetOutputs) {
     158        basePtrs.push_back(getScalarField(self, sSet.ssName + basePtrSuffix));
     159        blockMasks.push_back(getScalarField(self, sSet.ssName + blkMaskSuffix));
     160    }
     161   
     162    iBuilder->CreateBr(blockLoop);
     163   
     164    iBuilder->SetInsertPoint(blockLoop);
     165    PHINode * blocksRemaining = iBuilder->CreatePHI(iBuilder->getInt64Ty(), 2, "blocksRemaining");
     166    blocksRemaining->addIncoming(blocksToDo, entryBlock);
     167   
     168    Value * blockNo = getScalarField(self, blockNoScalar);
     169    std::vector<Value *> doBlockArgs = {self};
     170
     171    for (unsigned i = 0; i < basePtrs.size(); i++) {
     172        doBlockArgs.push_back(iBuilder->CreateGEP(basePtrs[i], iBuilder->CreateAnd(blockNo, blockMasks[i])));
     173    }
     174    Value * rslt = iBuilder->CreateCall(doBlockFunction, doBlockArgs);
     175    setScalarField(self, blockNoScalar, iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)));
     176    blocksToDo = iBuilder->CreateSub(blocksRemaining, iBuilder->getInt64(1));
     177    blocksRemaining->addIncoming(blocksToDo, blockLoop);
     178    Value * notDone = iBuilder->CreateICmpUGT(blocksToDo, iBuilder->getInt64(0));
     179    iBuilder->CreateCondBr(notDone, blockLoop, blocksDone);
     180   
     181    iBuilder->SetInsertPoint(blocksDone);
     182    if (mDoBlockReturnType->isVoidTy()) {
     183        iBuilder->CreateRetVoid();
     184    }
     185    else {
     186        iBuilder->CreateRet(rslt);
     187    }
     188    iBuilder->restoreIP(savePoint);
     189}
     190
     191
     192
    123193Value * KernelBuilder::getScalarIndex(std::string fieldName) {
    124194    const auto f = mInternalStateNameMap.find(fieldName);
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5076 r5086  
    1313#include <IDISA/idisa_builder.h>
    1414#include <boost/container/flat_map.hpp>
     15
     16const std::string blockNoScalar = "blockNo";
     17const std::string basePtrSuffix = "_basePtr";
     18const std::string blkMaskSuffix = "_blkMask";
    1519
    1620
     
    3741    void generateKernel();
    3842   
    39 protected:
     43//protected:
    4044    //
    4145    // Kernel builder subtypes define their logic of kernel construction
     
    6468    virtual void generateFinalBlockMethod();
    6569   
     70    void generateDoSegmentMethod();
     71   
    6672    // Add an additional scalar field to the KernelState struct.
    6773    // Must occur before any call to addKernelDeclarations or createKernelModule.
     
    8793    llvm::Value * getParameter(llvm::Function * f, std::string paramName);
    8894
    89 protected:
     95//protected:
    9096
    9197    std::vector<llvm::Type *>  mKernelFields;
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp

    r5075 r5086  
    99#include "utf_encoding.h"
    1010
    11 #include <kernels/scanmatchgen.h>
     11#include <IDISA/idisa_builder.h>
     12
     13#include <kernels/interface.h>
     14#include <kernels/kernel.h>
    1215#include <kernels/s2p_kernel.h>
    1316
    14 #include <pablo/function.h>
    15 #include <pablo/pablo_kernel.h>
    16 #include <pablo/pablo_toolchain.h>
    1717
    18 #include <llvm/IR/Intrinsics.h>
    19 #include "llvm/Support/SourceMgr.h"
    20 #include "llvm/IRReader/IRReader.h"
    21 #include "llvm/Linker/Linker.h"
     18using namespace kernel;
    2219
    2320
     21void generatePipelineLoop(IDISA::IDISA_Builder * iBuilder, std::vector<KernelBuilder *> kernels, std::vector<Value *> instances, Value * fileSize) {
     22   
     23    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
     24    Function * main = entryBlock->getParent();
     25       
     26    const unsigned segmentSize = codegen::SegmentSize;
     27    Type * const int64ty = iBuilder->getInt64Ty();
    2428
    25 using namespace pablo;
    26 using namespace kernel;
    27 
    28 PipelineBuilder::PipelineBuilder(Module * m, IDISA::IDISA_Builder * b)
    29 : mMod(m)
    30 , iBuilder(b)
    31 , mBitBlockType(b->getBitBlockType())
    32 , mBlockSize(b->getBitBlockWidth()) {
    33 
    34 }
    35 
    36 PipelineBuilder::~PipelineBuilder() {
    37 }
    38 
    39 inline Value * generatePopcount(IDISA::IDISA_Builder * iBuilder, Value * bits) {
    40     Value * ctpopFunc = Intrinsic::getDeclaration(iBuilder->getModule(), Intrinsic::ctpop, bits->getType());
    41     return iBuilder->CreateCall(ctpopFunc, {bits});
    42 }
    43 
    44 inline Value * Cal_Count(Value * match_ptr, IDISA::IDISA_Builder * iBuilder) {
    45     Value * matches = iBuilder->CreateLoad(match_ptr, false, "match");
    46     return generatePopcount(iBuilder, matches);
    47 }
    48 
    49 Function * PipelineBuilder::ExecuteKernels(PabloFunction * function, bool isNameExpression, bool CountOnly, bool UTF_16) {
    50    
    51     s2pKernel  s2pk(iBuilder);
    52     scanMatchKernel scanMatchK(iBuilder, 64, false);
    53 
    54     s2pk.generateKernel();
    55     scanMatchK.generateKernel();
    56    
    57     //std::unique_ptr<Module> s2pM = s2pk.createKernelModule();
    58     //std::unique_ptr<Module> scanMatchM = scanMatchK.createKernelModule();
    59    
    60     //s2pk.addKernelDeclarations(mMod);
    61     //scanMatchK.addKernelDeclarations(mMod);
    62 
    63     pablo_function_passes(function);
    64     PabloKernel  icgrepK(iBuilder, "icgrep", function, {"matchedLineCount"});
    65     icgrepK.generateKernel();
    66 
    67     //std::unique_ptr<Module> icgrepM = icgrepK.createKernelModule();
    68     //icgrepK.addKernelDeclarations(mMod);
    69    
    70     Type * const int64ty = iBuilder->getInt64Ty();
    71     Type * const int8PtrTy = iBuilder->getInt8PtrTy();
    72     Type * const inputType = PointerType::get(ArrayType::get(ArrayType::get(mBitBlockType, (UTF_16 ? 16 : 8)), 1), 0);
    73     Type * const resultTy = CountOnly ? int64ty : iBuilder->getVoidTy();
    74     Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", resultTy, inputType, int64ty, int64ty, nullptr));
    75     main->setCallingConv(CallingConv::C);
    76     Function::arg_iterator args = main->arg_begin();
    77 
    78     Value * const inputStream = &*(args++);
    79     inputStream->setName("input");
    80     Value * const bufferSize = &*(args++);
    81     bufferSize->setName("bufferSize");
    82     Value * const fileIdx = &*(args++);
    83     fileIdx->setName("fileIdx");
    84 
    85     iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
    86     BasicBlock * entryBlock = iBuilder->GetInsertBlock();
     29    // Create the basic blocks for the loop.
    8730    BasicBlock * segmentCondBlock = nullptr;
    8831    BasicBlock * segmentBodyBlock = nullptr;
    89     const unsigned segmentSize = codegen::SegmentSize;
     32    if (segmentSize > 1) {
     33        segmentCondBlock = BasicBlock::Create(iBuilder->getContext(), "segmentCond", main, 0);
     34        segmentBodyBlock = BasicBlock::Create(iBuilder->getContext(), "segmentBody", main, 0);
     35    }
     36    BasicBlock * fullCondBlock = BasicBlock::Create(iBuilder->getContext(), "fullCond", main, 0);
     37    BasicBlock * fullBodyBlock = BasicBlock::Create(iBuilder->getContext(), "fullBody", main, 0);
     38    BasicBlock * finalBlock = BasicBlock::Create(iBuilder->getContext(), "final", main, 0);
    9039   
    91     if (segmentSize > 1) {
    92         segmentCondBlock = BasicBlock::Create(mMod->getContext(), "segmentCond", main, 0);
    93         segmentBodyBlock = BasicBlock::Create(mMod->getContext(), "segmentBody", main, 0);
    94     }
    95     BasicBlock * fullCondBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
    96     BasicBlock * fullBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
    97     BasicBlock * finalBlock = BasicBlock::Create(mMod->getContext(), "final", main, 0);
    98 
    99    
    100     StreamSetBuffer ByteStream(iBuilder, StreamSetType(1, (UTF_16 ? 16 : 8)), 0);
    101     StreamSetBuffer BasisBits(iBuilder, StreamSetType((UTF_16 ? 16 : 8), 1), segmentSize);
    102     StreamSetBuffer MatchResults(iBuilder, StreamSetType(2, 1), segmentSize);
    103    
    104     ByteStream.setStreamSetBuffer(inputStream);
    105     BasisBits.allocateBuffer();
    106     MatchResults.allocateBuffer();
    107    
    108     Value * s2pInstance = s2pk.createInstance({});
    109     Value * icgrepInstance = icgrepK.createInstance({});
    110     Value * scanMatchInstance = nullptr;
    111     if (!CountOnly) {
    112         scanMatchInstance = scanMatchK.createInstance({iBuilder->CreateBitCast(inputStream, int8PtrTy), bufferSize, fileIdx});
    113     }
    114 
    11540   
    11641    Value * initialBufferSize = nullptr;
    11742    Value * initialBlockNo = nullptr;
    11843    BasicBlock * initialBlock = nullptr;
    119 
     44   
    12045    if (segmentSize > 1) {
    12146        iBuilder->CreateBr(segmentCondBlock);
    12247        iBuilder->SetInsertPoint(segmentCondBlock);
    12348        PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
    124         remainingBytes->addIncoming(bufferSize, entryBlock);
     49        remainingBytes->addIncoming(fileSize, entryBlock);
    12550        PHINode * blockNo = iBuilder->CreatePHI(int64ty, 2, "blockNo");
    12651        blockNo->addIncoming(iBuilder->getInt64(0), entryBlock);
    127 
    128         Constant * const step = ConstantInt::get(int64ty, mBlockSize * segmentSize);
     52       
     53        Constant * const step = ConstantInt::get(int64ty, iBuilder->getBitBlockWidth() * segmentSize);
    12954        Value * segmentCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
    13055        iBuilder->CreateCondBr(segmentCondTest, fullCondBlock, segmentBodyBlock);
     56       
    13157        iBuilder->SetInsertPoint(segmentBodyBlock);
    132         for (unsigned i = 0; i < segmentSize; ++i) {
    133             Value * blkNo = iBuilder->CreateAdd(blockNo, iBuilder->getInt64(i));
    134             s2pk.createDoBlockCall(s2pInstance, {ByteStream.getBlockPointer(blkNo), BasisBits.getBlockPointer(blkNo)});
    135         }
    136         for (unsigned i = 0; i < segmentSize; ++i) {
    137             Value * blkNo = iBuilder->CreateAdd(blockNo, iBuilder->getInt64(i));
    138             icgrepK.createDoBlockCall(icgrepInstance, {BasisBits.getBlockPointer(blkNo), MatchResults.getBlockPointer(blkNo)});
    139         }
    140         if (!CountOnly) {
    141             for (unsigned i = 0; i < segmentSize; ++i) {
    142                 Value * blkNo = iBuilder->CreateAdd(blockNo, iBuilder->getInt64(i));
    143                 scanMatchK.createDoBlockCall(scanMatchInstance, {MatchResults.getBlockPointer(blkNo)});
    144             }
     58        Value * segBlocks = ConstantInt::get(int64ty, segmentSize);
     59        for (unsigned i = 0; i < kernels.size(); i++) {
     60            kernels[i]->createDoSegmentCall(instances[i], segBlocks);
    14561        }
    14662        remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
    147         blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(segmentSize)), segmentBodyBlock);
    148 
     63        blockNo->addIncoming(iBuilder->CreateAdd(blockNo, segBlocks), segmentBodyBlock);
     64       
    14965        iBuilder->CreateBr(segmentCondBlock);
    15066        initialBufferSize = remainingBytes;
     
    15268        initialBlock = segmentCondBlock;
    15369    } else {
    154         initialBufferSize = bufferSize;
    155         initialBlockNo = iBuilder->getInt64(0);
     70        initialBufferSize = fileSize;
     71        initialBlockNo = ConstantInt::get(int64ty, 0);
    15672        initialBlock = entryBlock;
    15773        iBuilder->CreateBr(fullCondBlock);
    15874    }
    159 
     75   
    16076    iBuilder->SetInsertPoint(fullCondBlock);
    16177    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
     
    16480    blockNo->addIncoming(initialBlockNo, initialBlock);
    16581   
    166     Constant * const step = ConstantInt::get(int64ty, mBlockSize * (UTF_16 ? 2 : 1));
     82    Constant * const step = ConstantInt::get(int64ty, iBuilder->getBitBlockWidth());
    16783    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
    16884    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
    169 
     85   
    17086    // Full Block Pipeline loop
    17187    iBuilder->SetInsertPoint(fullBodyBlock);
    17288   
    173     Value * byteStreamPtr = ByteStream.getBlockPointer(blockNo);
    174     Value * basisBitsPtr = BasisBits.getBlockPointer(blockNo);
    175     Value * matchResultsPtr = MatchResults.getBlockPointer(blockNo);
    176     s2pk.createDoBlockCall(s2pInstance, {byteStreamPtr, basisBitsPtr});
    177     icgrepK.createDoBlockCall(icgrepInstance, {basisBitsPtr, matchResultsPtr});
    178     if (!CountOnly) {
    179 
    180         scanMatchK.createDoBlockCall(scanMatchInstance, {matchResultsPtr});
     89    for (unsigned i = 0; i < kernels.size(); i++) {
     90        kernels[i]->createDoSegmentCall(instances[i], ConstantInt::get(int64ty, 1));
    18191    }
     92   
    18293    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), fullBodyBlock);
    18394    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), fullBodyBlock);
    18495    iBuilder->CreateBr(fullCondBlock);
    185 
     96   
    18697    iBuilder->SetInsertPoint(finalBlock);
    187     byteStreamPtr = ByteStream.getBlockPointer(blockNo);
    188     basisBitsPtr = BasisBits.getBlockPointer(blockNo);
    189     matchResultsPtr = MatchResults.getBlockPointer(blockNo);
    190     s2pk.createFinalBlockCall(s2pInstance, remainingBytes, {byteStreamPtr, basisBitsPtr});
    191     icgrepK.createFinalBlockCall(icgrepInstance, remainingBytes, {basisBitsPtr, matchResultsPtr});
    192     if (CountOnly) {
    193         Value * matchCount = icgrepK.createGetAccumulatorCall(icgrepInstance, "matchedLineCount");
    194         iBuilder->CreateRet(matchCount);
     98   
     99    for (unsigned i = 0; i < kernels.size(); i++) {
     100        std::vector<Value *> basePtrs;
     101        std::vector<Value *> blockMasks;
     102        for (auto sSet : kernels[i]->mStreamSetInputs) {
     103            basePtrs.push_back(kernels[i]->getScalarField(instances[i], sSet.ssName + basePtrSuffix));
     104            blockMasks.push_back(kernels[i]->getScalarField(instances[i], sSet.ssName + blkMaskSuffix));
     105        }
     106        for (auto sSet : kernels[i]->mStreamSetOutputs) {
     107            basePtrs.push_back(kernels[i]->getScalarField(instances[i], sSet.ssName + basePtrSuffix));
     108            blockMasks.push_back(kernels[i]->getScalarField(instances[i], sSet.ssName + blkMaskSuffix));
     109        }
     110        std::vector<Value *> args;
     111        for (unsigned i = 0; i < basePtrs.size(); i++) {
     112            args.push_back(iBuilder->CreateGEP(basePtrs[i], iBuilder->CreateAnd(blockNo, blockMasks[i])));
     113        }
     114        kernels[i]->createFinalBlockCall(instances[i], remainingBytes, args);
    195115    }
    196     else {
    197         scanMatchK.createFinalBlockCall(scanMatchInstance, remainingBytes, {matchResultsPtr});
    198         iBuilder->CreateRetVoid();
    199     }
    200    
    201     //Linker L(*mMod);
    202     //L.linkInModule(std::move(s2pM));
    203     //L.linkInModule(std::move(scanMatchM));
    204     //L.linkInModule(std::move(icgrepM));
    205 
    206 
    207     return main;
    208116}
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.h

    r5063 r5086  
    77
    88#include <IDISA/idisa_builder.h>
     9#include <kernels/interface.h>
    910#include <kernels/kernel.h>
    1011
    11 namespace llvm {
    12     class Module;
    13     class Function;
    14     class Type;
    15 }
     12void generatePipelineLoop(IDISA::IDISA_Builder * iBuilder, std::vector<kernel::KernelBuilder *> kernels, std::vector<llvm::Value *> instances, llvm::Value * totalBytes);
    1613
    17 namespace pablo {
    18     class PabloFunction;
    19     class PabloBlock;
    20     class PabloKernel;
    21 }
    22 
    23 using namespace llvm;
    24 
    25 namespace kernel {
    26 
    27 class PipelineBuilder {
    28 public:
    29     PipelineBuilder(llvm::Module * m, IDISA::IDISA_Builder * b);
    30 
    31     ~PipelineBuilder();
    32 
    33     llvm::Function * ExecuteKernels(pablo::PabloFunction * function, bool isNameExpression, bool CountOnly, bool UTF_16);
    34 
    35 private:
    36     llvm::Module *                      mMod;
    37     IDISA::IDISA_Builder *              iBuilder;
    38     llvm::Type *                        mBitBlockType;
    39     int                                 mBlockSize;
    40 };
    41 
    42 }
    4314
    4415#endif // PIPELINE_H
Note: See TracChangeset for help on using the changeset viewer.