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

Last change on this file since 4931 was 4931, checked in by lindanl, 4 years ago

Add final block processing.

File size: 7.8 KB
Line 
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>
12
13#include <pablo/function.h>
14#include <pablo/pablo_compiler.h>
15
16
17PipelineBuilder::PipelineBuilder(Module * m, IDISA::IDISA_Builder * b)
18: mMod(m)
19, iBuilder(b)
20, mFilePosIdx(2)
21, mBitBlockType(b->getBitBlockType())
22, mBlockSize(b->getBitBlockWidth()){
23
24}
25PipelineBuilder::~PipelineBuilder(){
26}
27
28void PipelineBuilder::CreateKernels(pablo::PabloFunction * function){
29    mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder);
30    mICgrepKernel = new KernelBuilder("icgrep", mMod, iBuilder);
31    mScanMatchKernel = new KernelBuilder("scanMatch", mMod, iBuilder);
32
33
34    generateS2PKernel(mMod, iBuilder, mS2PKernel);
35    generateScanMatch(mMod, iBuilder, 64, mScanMatchKernel);
36
37    pablo_function_passes(function);
38         
39    pablo::PabloCompiler pablo_compiler(mMod, iBuilder);
40    try {
41        pablo_compiler.setKernel(mICgrepKernel);
42        pablo_compiler.compile(function);
43        delete function;
44        releaseSlabAllocatorMemory();
45    } catch (std::runtime_error e) {
46        delete function;
47        releaseSlabAllocatorMemory();
48        std::cerr << "Runtime error: " << e.what() << std::endl;
49        exit(1);
50    }
51
52}
53
54void PipelineBuilder::ExecuteKernels(){
55    Type * T = iBuilder->getIntNTy(64);   
56    Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
57    Type * inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
58 
59    Constant* c = mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, T, S, T, NULL);
60    Function* mMainFunction = cast<Function>(c);
61    mMainFunction->setCallingConv(CallingConv::C);
62    Function::arg_iterator args = mMainFunction->arg_begin();
63
64
65    Value* input_param = args++;
66    input_param->setName("input");
67    Value* buffersize_param = args++;
68    buffersize_param->setName("buffersize");   
69    Value* filename_param = args++;
70    filename_param->setName("filename");     
71    Value* finalLineUnterminated_param = args++;
72    finalLineUnterminated_param->setName("finalLineUnterminated");
73
74    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mMainFunction,0));
75
76
77    BasicBlock * entry_block = iBuilder->GetInsertBlock();
78    BasicBlock * pipeline_test_block = BasicBlock::Create(mMod->getContext(), "pipeline_test_block", mMainFunction, 0);
79    BasicBlock * pipeline_do_block = BasicBlock::Create(mMod->getContext(), "pipeline_do_block", mMainFunction, 0);
80    BasicBlock * pipeline_final_block = BasicBlock::Create(mMod->getContext(), "pipeline_final_block", mMainFunction, 0);
81    BasicBlock * pipeline_partial_block = BasicBlock::Create(mMod->getContext(), "pipeline_partial_block", mMainFunction, 0);
82    BasicBlock * pipeline_empty_block = BasicBlock::Create(mMod->getContext(), "pipeline_empty_block", mMainFunction, 0);
83    BasicBlock * pipeline_end_block = BasicBlock::Create(mMod->getContext(), "pipeline_end_block", mMainFunction, 0);   
84    BasicBlock * pipeline_Unterminated_block = BasicBlock::Create(mMod->getContext(), "pipeline_Unterminated_block", mMainFunction, 0);
85    BasicBlock * pipeline_return_block = BasicBlock::Create(mMod->getContext(), "pipeline_return_block", mMainFunction, 0);
86
87    Value * s2pKernelStruct = mS2PKernel->generateKernelInstance();
88    Value * icGrepKernelStruct = mICgrepKernel->generateKernelInstance();
89    Value * scanMatchKernelStruct = mScanMatchKernel->generateKernelInstance();
90
91    Value * gep = iBuilder->CreateGEP(scanMatchKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(7)});
92    Value* filebuf = iBuilder->CreateBitCast(input_param, S);
93    iBuilder->CreateStore(filebuf, gep);
94    gep = iBuilder->CreateGEP(scanMatchKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(8)});
95    iBuilder->CreateStore(buffersize_param, gep);
96    gep = iBuilder->CreateGEP(scanMatchKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(9)});
97    iBuilder->CreateStore(filename_param, gep);
98
99    Value * basis_bits = iBuilder->CreateGEP(s2pKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
100    Value * results = iBuilder->CreateGEP(icGrepKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
101 
102    iBuilder->CreateBr(pipeline_test_block);
103
104    iBuilder->SetInsertPoint(pipeline_test_block);
105    PHINode * remaining_phi = iBuilder->CreatePHI(T, 2, "remaining");   
106    PHINode * blkNo_phi = iBuilder->CreatePHI(T, 2, "blkNo");
107    remaining_phi->addIncoming(buffersize_param, entry_block);
108    blkNo_phi->addIncoming(iBuilder->getInt64(0), entry_block);
109
110    Value * final_block_cond = iBuilder->CreateICmpSLT(remaining_phi, ConstantInt::get(T, mBlockSize));
111    iBuilder->CreateCondBr(final_block_cond, pipeline_final_block, pipeline_do_block);
112
113    iBuilder->SetInsertPoint(pipeline_do_block);
114
115    gep = iBuilder->CreateGEP(input_param, {blkNo_phi});
116    Value * update_blkNo = iBuilder->CreateAdd(blkNo_phi, iBuilder->getInt64(1));
117    blkNo_phi->addIncoming(update_blkNo, pipeline_do_block);
118
119    mS2PKernel->generateDoBlockCall(gep);
120    mICgrepKernel->generateDoBlockCall(basis_bits);
121    mScanMatchKernel->generateDoBlockCall(results);
122
123    Value * update_remaining = iBuilder->CreateSub(remaining_phi, iBuilder->getInt64(mBlockSize));
124    remaining_phi->addIncoming(update_remaining, pipeline_do_block);
125    iBuilder->CreateBr(pipeline_test_block);
126
127    iBuilder->SetInsertPoint(pipeline_final_block);
128
129    Value * empty_block_cond = iBuilder->CreateICmpEQ(remaining_phi, ConstantInt::get(T, 0));
130    iBuilder->CreateCondBr(empty_block_cond, pipeline_empty_block, pipeline_partial_block);
131
132    iBuilder->SetInsertPoint(pipeline_partial_block);
133
134    gep = iBuilder->CreateGEP(input_param, {blkNo_phi});
135    mS2PKernel->generateDoBlockCall(gep);
136    iBuilder->CreateBr(pipeline_end_block);
137
138    iBuilder->SetInsertPoint(pipeline_empty_block);
139
140    iBuilder->CreateMemSet(basis_bits, iBuilder->getInt8(0), mBlockSize, 4);
141    iBuilder->CreateBr(pipeline_end_block);
142
143    iBuilder->SetInsertPoint(pipeline_end_block);
144
145    Value * return_block_cond = iBuilder->CreateICmpNE(finalLineUnterminated_param, ConstantInt::get(T, 0));
146    iBuilder->CreateCondBr(return_block_cond, pipeline_return_block, pipeline_Unterminated_block);
147   
148    iBuilder->SetInsertPoint(pipeline_Unterminated_block);
149
150    Value * remaining = iBuilder->CreateBitCast(remaining_phi, iBuilder->getIntNTy(128));
151    Value * EOF_mask = iBuilder->CreateShl(ConstantInt::get(iBuilder->getIntNTy(128), 1), remaining);
152    EOF_mask = iBuilder->CreateSub(EOF_mask, ConstantInt::get(iBuilder->getIntNTy(128), 1));
153
154    Value * EOF_pos = iBuilder->CreateNeg(iBuilder->CreateOr(iBuilder->CreateShl(iBuilder->CreateNeg(EOF_mask), 1), EOF_mask));
155    EOF_pos = iBuilder->CreateBitCast(EOF_pos, mBitBlockType);
156
157    Value * gep_bits4 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(4)});
158    Value * bits4 = iBuilder->CreateAlignedLoad(gep_bits4, mBlockSize/8, false, "bits4");
159    bits4 = iBuilder->CreateOr(bits4, EOF_pos);
160    iBuilder->CreateAlignedStore(bits4, gep_bits4, mBlockSize/8, false);
161
162    Value * gep_bits6 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(6)});
163    Value * bits6 = iBuilder->CreateAlignedLoad(gep_bits6, mBlockSize/8, false, "bits6");
164    bits6 = iBuilder->CreateOr(bits6, EOF_pos);
165    iBuilder->CreateAlignedStore(bits6, gep_bits6, mBlockSize/8, false);
166    iBuilder->CreateBr(pipeline_return_block);
167
168    iBuilder->SetInsertPoint(pipeline_return_block);
169
170    mICgrepKernel->generateDoBlockCall(basis_bits);
171    mScanMatchKernel->generateDoBlockCall(results);
172    iBuilder->CreateRetVoid();
173
174}
175
176
177
Note: See TracBrowser for help on using the repository browser.