source: icGREP/icgrep-devel/icgrep/editd/editdscan_kernel.cpp @ 5267

Last change on this file since 5267 was 5267, checked in by nmedfort, 3 years ago

Code clean-up. Removed Pablo Call, SetIthBit? and Prototype.

File size: 4.6 KB
Line 
1/*
2 *  Copyright (c) 2015 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6
7#include "editdscan_kernel.h"
8#include <IR_Gen/idisa_builder.h>
9#include <llvm/IR/Module.h>
10
11using namespace llvm;
12
13namespace kernel {
14
15Value * generateCountForwardZeroes(IDISA::IDISA_Builder * iBuilder, Value * bits) {
16    Value * cttzFunc = Intrinsic::getDeclaration(iBuilder->getModule(), Intrinsic::cttz, bits->getType());
17    return iBuilder->CreateCall(cttzFunc, std::vector<Value *>({bits, ConstantInt::get(iBuilder->getInt1Ty(), 0)}));
18}
19
20void editdScanKernel::generateDoBlockMethod() const {
21    auto savePoint = iBuilder->saveIP();
22    Module * m = iBuilder->getModule();
23    Function * scanWordFunction = generateScanWordRoutine(m);
24    const unsigned fieldCount = iBuilder->getBitBlockWidth() / mScanwordBitWidth;
25    Type * T = iBuilder->getIntNTy(mScanwordBitWidth);
26    Type * scanwordVectorType =  VectorType::get(T, fieldCount);
27
28    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
29
30    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doBlockFunction, 0));
31    Value * kernelStuctParam = getParameter(doBlockFunction, "self");
32    Value * blockNo = getScalarField(kernelStuctParam, blockNoScalar);
33    Value * scanwordPos = iBuilder->CreateMul(blockNo, ConstantInt::get(blockNo->getType(), iBuilder->getBitBlockWidth()));
34   
35    std::vector<Value * > matchWordVectors;
36    for(unsigned d = 0; d <= mEditDistance; d++){
37        Value * ptr = getStream(kernelStuctParam, "matchResults", blockNo, iBuilder->getInt32(d));
38        Value * matches = iBuilder->CreateBlockAlignedLoad(ptr);
39        matchWordVectors.push_back(iBuilder->CreateBitCast(matches, scanwordVectorType));
40    }
41   
42    for(unsigned i = 0; i < fieldCount; ++i){       
43        for(unsigned d = 0; d <= mEditDistance; d++){
44            Value * matchWord = iBuilder->CreateExtractElement(matchWordVectors[d], ConstantInt::get(T, i));
45            iBuilder->CreateCall(scanWordFunction, {matchWord, iBuilder->getInt32(d), scanwordPos});
46        }
47        scanwordPos = iBuilder->CreateAdd(scanwordPos, ConstantInt::get(T, mScanwordBitWidth));
48
49    }
50    iBuilder -> CreateRetVoid();
51    iBuilder->restoreIP(savePoint);
52}
53
54Function * editdScanKernel::generateScanWordRoutine(Module * m) const {
55
56    Type * T = iBuilder->getIntNTy(mScanwordBitWidth);
57
58    Function * scanFunc = cast<Function>(m->getOrInsertFunction("scan_word", iBuilder->getVoidTy(), T, iBuilder->getInt32Ty(), T, nullptr));
59    scanFunc->setCallingConv(CallingConv::C);
60    Function::arg_iterator args = scanFunc->arg_begin();
61
62    Value * matchWord = &*(args++);
63    matchWord->setName("matchWord");
64    Value * dist = &*(args++);
65    dist->setName("dist");
66    Value * basePos = &*(args++);
67    basePos->setName("basePos");
68
69    Constant * matchProcessor = m->getOrInsertFunction("wrapped_report_pos", iBuilder->getVoidTy(), T, iBuilder->getInt32Ty(), nullptr);
70
71    BasicBlock * entryBlock = BasicBlock::Create(m->getContext(), "entry", scanFunc, 0);
72
73    BasicBlock * matchesCondBlock = BasicBlock::Create(m->getContext(), "matchesCond", scanFunc, 0);
74    BasicBlock * matchesLoopBlock = BasicBlock::Create(m->getContext(), "matchesLoop", scanFunc, 0);
75    BasicBlock * matchesDoneBlock = BasicBlock::Create(m->getContext(), "matchesDone", scanFunc, 0);
76
77    iBuilder->SetInsertPoint(entryBlock);
78    iBuilder->CreateBr(matchesCondBlock);
79
80    iBuilder->SetInsertPoint(matchesCondBlock);
81    PHINode * matches_phi = iBuilder->CreatePHI(T, 2, "matches");
82    matches_phi->addIncoming(matchWord, entryBlock);
83    Value * have_matches_cond = iBuilder->CreateICmpUGT(matches_phi, ConstantInt::get(T, 0));
84    iBuilder->CreateCondBr(have_matches_cond, matchesLoopBlock, matchesDoneBlock);
85
86    iBuilder->SetInsertPoint(matchesLoopBlock);
87    Value * match_pos = iBuilder->CreateAdd(generateCountForwardZeroes(iBuilder, matches_phi), basePos);
88    Value * matches_new = iBuilder->CreateAnd(matches_phi, iBuilder->CreateSub(matches_phi, ConstantInt::get(T, 1)));
89    matches_phi->addIncoming(matches_new, matchesLoopBlock);
90    iBuilder->CreateCall(matchProcessor, std::vector<Value *>({match_pos, dist}));
91    iBuilder->CreateBr(matchesCondBlock);
92
93    iBuilder->SetInsertPoint(matchesDoneBlock);
94    iBuilder -> CreateRetVoid();
95
96    return scanFunc;
97
98}
99
100editdScanKernel::editdScanKernel(IDISA::IDISA_Builder * iBuilder, unsigned dist) :
101KernelBuilder(iBuilder, "scanMatch",
102              {Binding{iBuilder->getStreamSetTy(dist + 1), "matchResults"}},
103              {}, {}, {}, {}),
104mEditDistance(dist),
105mScanwordBitWidth(iBuilder->getSizeTy()->getBitWidth()) {
106
107}
108
109}
Note: See TracBrowser for help on using the repository browser.