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

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

New kernel infrastructure

File size: 6.2 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
7#include <toolchain.h>
8#include "pipeline.h"
9#include "utf_encoding.h"
10
11#include <kernels/scanmatchgen.h>
12#include <kernels/s2p_kernel.h>
13
14#include <pablo/function.h>
15#include <pablo/pablo_kernel.h>
16#include <pablo/pablo_toolchain.h>
17
18#include <llvm/IR/Intrinsics.h>
19#include "llvm/Support/SourceMgr.h"
20#include "llvm/IRReader/IRReader.h"
21#include "llvm/Linker/Linker.h"
22
23
24
25using namespace pablo;
26using namespace kernel;
27
28PipelineBuilder::PipelineBuilder(Module * m, IDISA::IDISA_Builder * b)
29: mMod(m)
30, iBuilder(b)
31, mBitBlockType(b->getBitBlockType())
32, mBlockSize(b->getBitBlockWidth()) {
33
34}
35
36PipelineBuilder::~PipelineBuilder() {
37}
38
39inline 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
44inline 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
49Function * 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.prepareKernel();
66    icgrepK.generateKernel();
67
68    //std::unique_ptr<Module> icgrepM = icgrepK.createKernelModule();
69    //icgrepK.addKernelDeclarations(mMod);
70   
71    Type * const int64ty = iBuilder->getInt64Ty();
72    Type * const int8PtrTy = iBuilder->getInt8PtrTy();
73    Type * const inputType = PointerType::get(ArrayType::get(ArrayType::get(mBitBlockType, (UTF_16 ? 16 : 8)), 1), 0);
74    Type * const resultTy = CountOnly ? int64ty : iBuilder->getVoidTy();
75    Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", resultTy, inputType, int64ty, int64ty, nullptr));
76    main->setCallingConv(CallingConv::C);
77    Function::arg_iterator args = main->arg_begin();
78
79    Value * const inputStream = &*(args++);
80    inputStream->setName("input");
81    Value * const bufferSize = &*(args++);
82    bufferSize->setName("bufferSize");
83    Value * const fileIdx = &*(args++);
84    fileIdx->setName("fileIdx");
85
86    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
87    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
88    BasicBlock * fullCondBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
89    BasicBlock * fullBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
90    BasicBlock * finalBlock = BasicBlock::Create(mMod->getContext(), "final", main, 0);
91
92   
93    const unsigned segmentSize = 1;// or codegen::SegmentSize
94   
95    StreamSetBuffer ByteStream(iBuilder, StreamSetType(1, (UTF_16 ? 16 : 8)), 0);
96    StreamSetBuffer BasisBits(iBuilder, StreamSetType((UTF_16 ? 16 : 8), 1), segmentSize);
97    StreamSetBuffer MatchResults(iBuilder, StreamSetType(2, 1), segmentSize);
98   
99    ByteStream.setStreamSetBuffer(inputStream);
100    BasisBits.allocateBuffer();
101    MatchResults.allocateBuffer();
102
103    Value * initialBufferSize = bufferSize;
104    Value * initialBlockNo = iBuilder->getInt64(0);
105    BasicBlock * initialBlock = entryBlock;
106   
107    Value * s2pInstance = s2pk.createInstance({});
108    Value * icgrepInstance = icgrepK.createInstance({});
109    Value * scanMatchInstance = nullptr;
110    if (!CountOnly) {
111        scanMatchInstance = scanMatchK.createInstance({iBuilder->CreateBitCast(inputStream, int8PtrTy), bufferSize, fileIdx});
112    }
113    iBuilder->CreateBr(fullCondBlock);
114   
115    iBuilder->SetInsertPoint(fullCondBlock);
116    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
117    remainingBytes->addIncoming(initialBufferSize, initialBlock);
118    PHINode * blockNo = iBuilder->CreatePHI(int64ty, 2, "blockNo");
119    blockNo->addIncoming(initialBlockNo, initialBlock);
120   
121    Constant * const step = ConstantInt::get(int64ty, mBlockSize * (UTF_16 ? 2 : 1));
122    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
123    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
124
125    // Full Block Pipeline loop
126    iBuilder->SetInsertPoint(fullBodyBlock);
127   
128    Value * byteStreamPtr = ByteStream.getBlockPointer(blockNo);
129    Value * basisBitsPtr = BasisBits.getBlockPointer(blockNo);
130    Value * matchResultsPtr = MatchResults.getBlockPointer(blockNo);
131    s2pk.createDoBlockCall(s2pInstance, {byteStreamPtr, basisBitsPtr});
132    icgrepK.createDoBlockCall(icgrepInstance, {basisBitsPtr, matchResultsPtr});
133    if (!CountOnly) {
134
135        scanMatchK.createDoBlockCall(scanMatchInstance, {matchResultsPtr});
136    }
137    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), fullBodyBlock);
138    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), fullBodyBlock);
139    iBuilder->CreateBr(fullCondBlock);
140
141    iBuilder->SetInsertPoint(finalBlock);
142    byteStreamPtr = ByteStream.getBlockPointer(blockNo);
143    basisBitsPtr = BasisBits.getBlockPointer(blockNo);
144    matchResultsPtr = MatchResults.getBlockPointer(blockNo);
145    s2pk.createFinalBlockCall(s2pInstance, remainingBytes, {byteStreamPtr, basisBitsPtr});
146    icgrepK.createFinalBlockCall(icgrepInstance, remainingBytes, {basisBitsPtr, matchResultsPtr});
147    if (CountOnly) {
148        Value * matchCount = icgrepK.createGetAccumulatorCall(icgrepInstance, "matchedLineCount");
149        iBuilder->CreateRet(matchCount);
150    }
151    else {
152        scanMatchK.createFinalBlockCall(scanMatchInstance, remainingBytes, {matchResultsPtr});
153        iBuilder->CreateRetVoid();
154    }
155   
156    //Linker L(*mMod);
157    //L.linkInModule(std::move(s2pM));
158    //L.linkInModule(std::move(scanMatchM));
159    //L.linkInModule(std::move(icgrepM));
160
161
162    return main;
163}
Note: See TracBrowser for help on using the repository browser.