Ignore:
Timestamp:
Mar 22, 2016, 5:14:05 PM (3 years ago)
Author:
nmedfort
Message:

First attempt at dynamic segment size intergration.

File:
1 edited

Legend:

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

    r4985 r4986  
    1515#include <pablo/pablo_toolchain.h>
    1616
     17#include <llvm/Support/CommandLine.h>
     18
     19static cl::opt<unsigned> SegmentSize("segment-size", cl::desc("Segment Size"), cl::value_desc("positive integer"), cl::init(1));
    1720
    1821using namespace pablo;
     
    2326, iBuilder(b)
    2427, mBitBlockType(b->getBitBlockType())
    25 , mBlockSize(b->getBitBlockWidth()){
     28, mBlockSize(b->getBitBlockWidth()) {
    2629
    2730}
    2831
    29 PipelineBuilder::~PipelineBuilder(){
     32PipelineBuilder::~PipelineBuilder() {
    3033    delete mS2PKernel;
    3134    delete mICgrepKernel;
     
    3437
    3538void PipelineBuilder::CreateKernels(PabloFunction * function, bool isNameExpression){
    36     mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder);
    37     mICgrepKernel = new KernelBuilder("icgrep", mMod, iBuilder);
    38     mScanMatchKernel = new KernelBuilder("scanMatch", mMod, iBuilder);
    39 
     39    mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder, SegmentSize);
     40    mICgrepKernel = new KernelBuilder("icgrep", mMod, iBuilder, SegmentSize);
     41    mScanMatchKernel = new KernelBuilder("scanMatch", mMod, iBuilder, SegmentSize);
    4042    generateS2PKernel(mMod, iBuilder, mS2PKernel);
    41 
    4243    generateScanMatch(mMod, iBuilder, 64, mScanMatchKernel, isNameExpression);
    43 
    4444    pablo_function_passes(function);
    45 
    4645    PabloCompiler pablo_compiler(mMod, iBuilder);
    4746    try {
     
    5857}
    5958
    60 void PipelineBuilder::ExecuteKernels() {
    61     Type * T = iBuilder->getIntNTy(64);   
    62     Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
    63     Type * inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
    64     Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, T, S, T, nullptr));
     59Function * PipelineBuilder::ExecuteKernels() {
     60    Type * const int64ty = iBuilder->getInt64Ty();
     61    Type * const int8PtrTy = iBuilder->getInt8PtrTy();
     62    Type * const inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
     63
     64    Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, int64ty, int8PtrTy, int64ty, nullptr));
    6565    main->setCallingConv(CallingConv::C);
    6666    Function::arg_iterator args = main->arg_begin();
     
    6868    Value * const inputStream = args++;
    6969    inputStream->setName("input");
    70     Value* buffersize_param = args++;
    71     buffersize_param->setName("buffersize");   
    72     Value* filename_param = args++;
    73     filename_param->setName("filename");     
    74     Value* finalLineUnterminated_param = args++;
    75     finalLineUnterminated_param->setName("finalLineUnterminated");
     70    Value * const bufferSize = args++;
     71    bufferSize->setName("bufferSize");
     72    Value * const fileName = args++;
     73    fileName->setName("fileName");
     74    Value * const finalLineUnterminated = args++;
     75    finalLineUnterminated->setName("finalLineUnterminated");
    7676
    7777    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
    7878
    79     BasicBlock * entry_block = iBuilder->GetInsertBlock();
    80     BasicBlock * pipeline_test_block = BasicBlock::Create(mMod->getContext(), "pipeline_test_block", main, 0);
    81     BasicBlock * pipeline_do_block = BasicBlock::Create(mMod->getContext(), "pipeline_do_block", main, 0);
    82     BasicBlock * pipeline_final_block = BasicBlock::Create(mMod->getContext(), "pipeline_final_block", main, 0);
    83     BasicBlock * pipeline_partial_block = BasicBlock::Create(mMod->getContext(), "pipeline_partial_block", main, 0);
    84     BasicBlock * pipeline_empty_block = BasicBlock::Create(mMod->getContext(), "pipeline_empty_block", main, 0);
    85     BasicBlock * pipeline_end_block = BasicBlock::Create(mMod->getContext(), "pipeline_end_block", main, 0);
    86     BasicBlock * pipeline_Unterminated_block = BasicBlock::Create(mMod->getContext(), "pipeline_Unterminated_block", main, 0);
    87     BasicBlock * pipeline_return_block = BasicBlock::Create(mMod->getContext(), "pipeline_return_block", main, 0);
     79    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
     80    BasicBlock * segmentCondBlock = nullptr;
     81    BasicBlock * segmentBodyBlock = nullptr;
     82    const unsigned segmentSize = SegmentSize;
     83    if (segmentSize > 1) {
     84        segmentCondBlock = BasicBlock::Create(mMod->getContext(), "segmentCond", main, 0);
     85        segmentBodyBlock = BasicBlock::Create(mMod->getContext(), "segmentBody", main, 0);
     86    }
     87    BasicBlock * fullCondBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
     88    BasicBlock * fullBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
     89    BasicBlock * finalBlock = BasicBlock::Create(mMod->getContext(), "final", main, 0);
     90    BasicBlock * finalPartialBlock = BasicBlock::Create(mMod->getContext(), "partial", main, 0);
     91    BasicBlock * finalEmptyBlock = BasicBlock::Create(mMod->getContext(), "empty", main, 0);
     92    BasicBlock * endBlock = BasicBlock::Create(mMod->getContext(), "end", main, 0);
     93    BasicBlock * unterminatedBlock = BasicBlock::Create(mMod->getContext(), "unterminated", main, 0);
     94    BasicBlock * exitBlock = BasicBlock::Create(mMod->getContext(), "exit", main, 0);
    8895
    89     Instance * s2pInstance = mS2PKernel->instantiate();
    90     Instance * icGrepInstance = mICgrepKernel->instantiate();
    91     Instance * scanMatchInstance = mScanMatchKernel->instantiate();
     96    Instance * s2pInstance = mS2PKernel->instantiate(inputStream);
     97    Instance * icGrepInstance = mICgrepKernel->instantiate(s2pInstance->getOutputStreamSet());
     98    Instance * scanMatchInstance = mScanMatchKernel->instantiate(icGrepInstance->getOutputStreamSet());
     99
     100    Value * ptr = iBuilder->CreateBitCast(inputStream, int8PtrTy);
     101
     102    scanMatchInstance->setInternalState("FileBuf", ptr);
     103    scanMatchInstance->setInternalState("FileSize", bufferSize);
     104    scanMatchInstance->setInternalState("FileName", fileName);
     105
     106    // iBuilder->CallPrintInt("source", iBuilder->CreatePtrToInt(ptr, iBuilder->getInt64Ty()));
     107
     108    Value * initialBufferSize = nullptr;
     109    BasicBlock * initialBlock = nullptr;
     110
     111    if (segmentSize > 1) {
     112        iBuilder->CreateBr(segmentCondBlock);
     113        iBuilder->SetInsertPoint(segmentCondBlock);
     114        PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
     115        remainingBytes->addIncoming(bufferSize, entryBlock);
     116        Constant * const step = ConstantInt::get(int64ty, mBlockSize * segmentSize);
     117        Value * segmentCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
     118        iBuilder->CreateCondBr(segmentCondTest, fullCondBlock, segmentBodyBlock);
     119        iBuilder->SetInsertPoint(segmentBodyBlock);
     120        for (unsigned i = 0; i < segmentSize; ++i) {
     121            s2pInstance->CreateDoBlockCall();
     122        }
     123        for (unsigned i = 0; i < segmentSize; ++i) {
     124            icGrepInstance->CreateDoBlockCall();
     125        }
     126        for (unsigned i = 0; i < segmentSize; ++i) {
     127            scanMatchInstance->CreateDoBlockCall();
     128        }
     129        remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
     130        iBuilder->CreateBr(segmentCondBlock);
     131        initialBufferSize = remainingBytes;
     132        initialBlock = segmentCondBlock;
     133    } else {
     134        initialBufferSize = bufferSize;
     135        initialBlock = entryBlock;
     136        iBuilder->CreateBr(fullCondBlock);
     137    }
     138
     139    iBuilder->SetInsertPoint(fullCondBlock);
     140    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
     141    remainingBytes->addIncoming(initialBufferSize, initialBlock);
     142
     143    Constant * const step = ConstantInt::get(int64ty, mBlockSize);
     144    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
     145    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
     146
     147    iBuilder->SetInsertPoint(fullBodyBlock);
     148    s2pInstance->CreateDoBlockCall();
     149    icGrepInstance->CreateDoBlockCall();
     150    scanMatchInstance->CreateDoBlockCall();
     151
     152    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), fullBodyBlock);
     153    iBuilder->CreateBr(fullCondBlock);
     154
     155    iBuilder->SetInsertPoint(finalBlock);
     156    Value * const b4 = s2pInstance->getOutputStream(4);
     157    Value * const b6 = s2pInstance->getOutputStream(6);
     158    Value * emptyBlockCond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(int64ty, 0));
     159    iBuilder->CreateCondBr(emptyBlockCond, finalEmptyBlock, finalPartialBlock);
    92160
    93161
    94     Value * gep = scanMatchInstance->getInternalState("FileBuf");
    95     Value * filebuf = iBuilder->CreateBitCast(inputStream, S);
    96     iBuilder->CreateStore(filebuf, gep);
     162    iBuilder->SetInsertPoint(finalPartialBlock);
     163    s2pInstance->CreateDoBlockCall();
     164    iBuilder->CreateBr(endBlock);
    97165
    98     gep = scanMatchInstance->getInternalState("FileSize");
    99     iBuilder->CreateStore(buffersize_param, gep);
     166    iBuilder->SetInsertPoint(finalEmptyBlock);
     167    s2pInstance->clearOutputStream();
     168    iBuilder->CreateBr(endBlock);
    100169
    101     gep = scanMatchInstance->getInternalState("FileName");
    102     iBuilder->CreateStore(filename_param, gep);
    103 
    104     Value * basis_bits = s2pInstance->getOutputStreamSet();
    105 
    106     Value * results = icGrepInstance->getOutputStreamSet();
    107 
    108     iBuilder->CreateBr(pipeline_test_block);
    109 
    110     iBuilder->SetInsertPoint(pipeline_test_block);
    111     PHINode * blockNo = iBuilder->CreatePHI(T, 2, "blockNo");
    112     blockNo->addIncoming(iBuilder->getInt64(0), entry_block);
    113     PHINode * remainingBytes = iBuilder->CreatePHI(T, 2, "remainingBytes");
    114     remainingBytes->addIncoming(buffersize_param, entry_block);
    115 
    116     Constant * step = ConstantInt::get(T, mBlockSize * mS2PKernel->getSegmentBlocks());
    117 
    118     Value * final_block_cond = iBuilder->CreateICmpSLT(remainingBytes, step);
    119     iBuilder->CreateCondBr(final_block_cond, pipeline_final_block, pipeline_do_block);
    120 
    121     iBuilder->SetInsertPoint(pipeline_do_block);
    122 
    123     s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
    124 
    125     icGrepInstance->call(basis_bits);
    126     scanMatchInstance->call(results);
    127 
    128     blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), pipeline_do_block);
    129     Value * update_remaining = iBuilder->CreateSub(remainingBytes, step);
    130     remainingBytes->addIncoming(update_remaining, pipeline_do_block);
    131     iBuilder->CreateBr(pipeline_test_block);
    132 
    133     iBuilder->SetInsertPoint(pipeline_final_block);
    134 
    135     Value * empty_block_cond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(T, 0));
    136     iBuilder->CreateCondBr(empty_block_cond, pipeline_empty_block, pipeline_partial_block);
    137 
    138     iBuilder->SetInsertPoint(pipeline_partial_block);
    139 
    140     s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
    141 
    142     iBuilder->CreateBr(pipeline_end_block);
    143 
    144     iBuilder->SetInsertPoint(pipeline_empty_block);
    145 
    146     iBuilder->CreateMemSet(basis_bits, iBuilder->getInt8(0), mBlockSize, 4);
    147     iBuilder->CreateBr(pipeline_end_block);
    148 
    149     iBuilder->SetInsertPoint(pipeline_end_block);
    150 
    151     Value * return_block_cond = iBuilder->CreateICmpEQ(finalLineUnterminated_param, ConstantInt::get(T, 0));
    152     iBuilder->CreateCondBr(return_block_cond, pipeline_return_block, pipeline_Unterminated_block);
     170    iBuilder->SetInsertPoint(endBlock);
     171    Value * isFinalLineUnterminated = iBuilder->CreateICmpEQ(finalLineUnterminated, ConstantInt::get(int64ty, 0));
     172    iBuilder->CreateCondBr(isFinalLineUnterminated, exitBlock, unterminatedBlock);
    153173   
    154     iBuilder->SetInsertPoint(pipeline_Unterminated_block);
     174    iBuilder->SetInsertPoint(unterminatedBlock);
    155175
    156176    Value * remaining = iBuilder->CreateZExt(remainingBytes, iBuilder->getIntNTy(mBlockSize));
     
    158178    EOF_pos = iBuilder->CreateBitCast(EOF_pos, mBitBlockType);
    159179
    160     Value * gep_bits4 = s2pInstance->getOutputStream(4);
    161     Value * bits4 = iBuilder->CreateBlockAlignedLoad(gep_bits4);
    162     bits4 = iBuilder->CreateOr(bits4, EOF_pos);
    163     iBuilder->CreateBlockAlignedStore(bits4, gep_bits4);
    164180
    165     Value * gep_bits6 = s2pInstance->getOutputStream(6);
    166     Value * bits6 = iBuilder->CreateBlockAlignedLoad(gep_bits6);
    167     bits6 = iBuilder->CreateOr(bits6, EOF_pos);
    168     iBuilder->CreateBlockAlignedStore(bits6, gep_bits6);
     181    Value * b4val = iBuilder->CreateBlockAlignedLoad(b4);
     182    b4val = iBuilder->CreateOr(b4val, EOF_pos);
     183    iBuilder->CreateBlockAlignedStore(b4val, b4);
    169184
    170     iBuilder->CreateBr(pipeline_return_block);
     185    Value * b6val = iBuilder->CreateBlockAlignedLoad(b6);
     186    b6val = iBuilder->CreateOr(b6val, EOF_pos);
     187    iBuilder->CreateBlockAlignedStore(b6val, b6);
    171188
    172     iBuilder->SetInsertPoint(pipeline_return_block);
     189    iBuilder->CreateBr(exitBlock);
    173190
    174     icGrepInstance->call(basis_bits);
    175     scanMatchInstance->call(results);
     191    iBuilder->SetInsertPoint(exitBlock);
     192
     193    icGrepInstance->CreateDoBlockCall();
     194    scanMatchInstance->CreateDoBlockCall();
    176195    iBuilder->CreateRetVoid();
    177196
     197    return main;
    178198}
Note: See TracChangeset for help on using the changeset viewer.