source: icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp @ 4981

Last change on this file since 4981 was 4976, checked in by cameron, 3 years ago

Experimental s2p implementation using the s2p_ideal algorithm

File size: 7.0 KB
RevLine 
[4929]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#include "pipeline.h"
7#include "toolchain.h"
8#include "utf_encoding.h"
9
10#include <kernels/scanmatchgen.h>
11#include <kernels/s2p_kernel.h>
[4974]12#include <kernels/instance.h>
[4929]13
14#include <pablo/function.h>
15#include <pablo/pablo_compiler.h>
16
[4974]17
[4959]18using namespace pablo;
[4974]19using namespace kernel;
[4929]20
21PipelineBuilder::PipelineBuilder(Module * m, IDISA::IDISA_Builder * b)
22: mMod(m)
23, iBuilder(b)
24, mBitBlockType(b->getBitBlockType())
25, mBlockSize(b->getBitBlockWidth()){
26
27}
[4959]28
[4929]29PipelineBuilder::~PipelineBuilder(){
[4959]30    delete mS2PKernel;
31    delete mICgrepKernel;
32    delete mScanMatchKernel;
[4929]33}
34
[4959]35void PipelineBuilder::CreateKernels(PabloFunction * function, bool isNameExpression){
[4929]36    mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder);
37    mICgrepKernel = new KernelBuilder("icgrep", mMod, iBuilder);
38    mScanMatchKernel = new KernelBuilder("scanMatch", mMod, iBuilder);
39
40    generateS2PKernel(mMod, iBuilder, mS2PKernel);
[4970]41
[4939]42    generateScanMatch(mMod, iBuilder, 64, mScanMatchKernel, isNameExpression);
[4929]43
44    pablo_function_passes(function);
[4959]45
46    PabloCompiler pablo_compiler(mMod, iBuilder);
[4929]47    try {
48        pablo_compiler.setKernel(mICgrepKernel);
49        pablo_compiler.compile(function);
50        delete function;
51        releaseSlabAllocatorMemory();
52    } catch (std::runtime_error e) {
53        delete function;
54        releaseSlabAllocatorMemory();
55        std::cerr << "Runtime error: " << e.what() << std::endl;
56        exit(1);
57    }
58}
59
[4970]60void PipelineBuilder::ExecuteKernels() {
[4929]61    Type * T = iBuilder->getIntNTy(64);   
62    Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
[4959]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));
65    main->setCallingConv(CallingConv::C);
66    Function::arg_iterator args = main->arg_begin();
[4929]67
[4974]68    Value * const inputStream = args++;
69    inputStream->setName("input");
[4929]70    Value* buffersize_param = args++;
71    buffersize_param->setName("buffersize");   
72    Value* filename_param = args++;
[4931]73    filename_param->setName("filename");     
74    Value* finalLineUnterminated_param = args++;
75    finalLineUnterminated_param->setName("finalLineUnterminated");
[4929]76
[4959]77    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
[4929]78
79    BasicBlock * entry_block = iBuilder->GetInsertBlock();
[4959]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);
[4929]88
[4974]89    Instance * s2pInstance = mS2PKernel->instantiate();
90    Instance * icGrepInstance = mICgrepKernel->instantiate();
91    Instance * scanMatchInstance = mScanMatchKernel->instantiate();
[4931]92
[4968]93
[4974]94    Value * gep = scanMatchInstance->getInternalState("FileBuf");
95    Value * filebuf = iBuilder->CreateBitCast(inputStream, S);
[4959]96    iBuilder->CreateStore(filebuf, gep);
[4968]97
[4974]98    gep = scanMatchInstance->getInternalState("FileSize");
[4959]99    iBuilder->CreateStore(buffersize_param, gep);
[4968]100
[4974]101    gep = scanMatchInstance->getInternalState("FileName");
[4959]102    iBuilder->CreateStore(filename_param, gep);
[4931]103
[4974]104    Value * basis_bits = s2pInstance->getOutputStreamSet();
105
106    Value * results = icGrepInstance->getOutputStreamSet();
107
[4929]108    iBuilder->CreateBr(pipeline_test_block);
109
110    iBuilder->SetInsertPoint(pipeline_test_block);
[4974]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);
[4929]115
[4970]116    Constant * step = ConstantInt::get(T, mBlockSize * mS2PKernel->getSegmentBlocks());
117
[4974]118    Value * final_block_cond = iBuilder->CreateICmpSLT(remainingBytes, step);
[4931]119    iBuilder->CreateCondBr(final_block_cond, pipeline_final_block, pipeline_do_block);
[4929]120
121    iBuilder->SetInsertPoint(pipeline_do_block);
122
[4974]123    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
[4929]124
[4974]125    icGrepInstance->call(basis_bits);
126    scanMatchInstance->call(results);
[4929]127
[4974]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);
[4929]131    iBuilder->CreateBr(pipeline_test_block);
132
[4931]133    iBuilder->SetInsertPoint(pipeline_final_block);
134
[4974]135    Value * empty_block_cond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(T, 0));
[4931]136    iBuilder->CreateCondBr(empty_block_cond, pipeline_empty_block, pipeline_partial_block);
137
[4929]138    iBuilder->SetInsertPoint(pipeline_partial_block);
[4931]139
[4974]140    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
141
[4931]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
[4934]151    Value * return_block_cond = iBuilder->CreateICmpEQ(finalLineUnterminated_param, ConstantInt::get(T, 0));
[4931]152    iBuilder->CreateCondBr(return_block_cond, pipeline_return_block, pipeline_Unterminated_block);
153   
154    iBuilder->SetInsertPoint(pipeline_Unterminated_block);
155
[4974]156    Value * remaining = iBuilder->CreateZExt(remainingBytes, iBuilder->getIntNTy(mBlockSize));
[4940]157    Value * EOF_pos = iBuilder->CreateShl(ConstantInt::get(iBuilder->getIntNTy(mBlockSize), 1), remaining);
[4931]158    EOF_pos = iBuilder->CreateBitCast(EOF_pos, mBitBlockType);
159
[4974]160    Value * gep_bits4 = s2pInstance->getOutputStream(4);
161    Value * bits4 = iBuilder->CreateBlockAlignedLoad(gep_bits4);
[4931]162    bits4 = iBuilder->CreateOr(bits4, EOF_pos);
[4974]163    iBuilder->CreateBlockAlignedStore(bits4, gep_bits4);
[4931]164
[4974]165    Value * gep_bits6 = s2pInstance->getOutputStream(6);
166    Value * bits6 = iBuilder->CreateBlockAlignedLoad(gep_bits6);
[4931]167    bits6 = iBuilder->CreateOr(bits6, EOF_pos);
[4974]168    iBuilder->CreateBlockAlignedStore(bits6, gep_bits6);
169
[4931]170    iBuilder->CreateBr(pipeline_return_block);
171
172    iBuilder->SetInsertPoint(pipeline_return_block);
173
[4974]174    icGrepInstance->call(basis_bits);
175    scanMatchInstance->call(results);
[4929]176    iBuilder->CreateRetVoid();
177
178}
Note: See TracBrowser for help on using the repository browser.