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

Last change on this file since 6184 was 6184, checked in by nmedfort, 9 months ago

Initial version of PipelineKernel? + revised StreamSet? model.

File size: 4.0 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 <kernels/kernel_builder.h>
9#include <llvm/IR/Module.h>
10
11using namespace llvm;
12
13namespace kernel {
14
15void editdScanKernel::generateDoBlockMethod(const std::unique_ptr<kernel::KernelBuilder> & b) {
16    auto savePoint = b->saveIP();
17    Function * scanWordFunction = generateScanWordRoutine(b);
18    b->restoreIP(savePoint);
19
20    const unsigned fieldCount = b->getBitBlockWidth() / mScanwordBitWidth;
21    Type * T = b->getIntNTy(mScanwordBitWidth);
22    VectorType * scanwordVectorType =  VectorType::get(T, fieldCount);
23    Value * blockNo = b->getScalarField("BlockNo");
24    Value * scanwordPos = b->CreateMul(blockNo, ConstantInt::get(blockNo->getType(), b->getBitBlockWidth()));
25   
26    std::vector<Value * > matchWordVectors;
27    for(unsigned d = 0; d < mNumElements; d++) {
28        Value * matches = b->loadInputStreamBlock("matchResults", b->getInt32(d));
29        matchWordVectors.push_back(b->CreateBitCast(matches, scanwordVectorType));
30    }
31   
32    for(unsigned i = 0; i < fieldCount; ++i) {
33        for(unsigned d = 0; d < mNumElements; d++) {
34            Value * matchWord = b->CreateExtractElement(matchWordVectors[d], ConstantInt::get(T, i));
35            b->CreateCall(scanWordFunction, {matchWord, b->getInt32(d), scanwordPos});
36        }
37        scanwordPos = b->CreateAdd(scanwordPos, ConstantInt::get(T, mScanwordBitWidth));
38    }
39
40    b->setScalarField("BlockNo", b->CreateAdd(blockNo, b->getSize(1)));
41}
42
43Function * editdScanKernel::generateScanWordRoutine(const std::unique_ptr<KernelBuilder> &b) const {
44
45    IntegerType * T = b->getIntNTy(mScanwordBitWidth);
46    Module * const m = b->getModule();
47
48    Function * scanFunc = cast<Function>(m->getOrInsertFunction("scan_word", b->getVoidTy(), T, b->getInt32Ty(), T, nullptr));
49    scanFunc->setCallingConv(CallingConv::C);
50    Function::arg_iterator args = scanFunc->arg_begin();
51
52    Value * matchWord = &*(args++);
53    matchWord->setName("matchWord");
54    Value * dist = &*(args++);
55    dist->setName("dist");
56    Value * basePos = &*(args++);
57    basePos->setName("basePos");
58
59    Constant * matchProcessor = m->getOrInsertFunction("wrapped_report_pos", b->getVoidTy(), T, b->getInt32Ty(), nullptr);
60    BasicBlock * entryBlock = BasicBlock::Create(b->getContext(), "entry", scanFunc, 0);
61    BasicBlock * matchesCondBlock = BasicBlock::Create(b->getContext(), "matchesCond", scanFunc, 0);
62    BasicBlock * matchesLoopBlock = BasicBlock::Create(b->getContext(), "matchesLoop", scanFunc, 0);
63    BasicBlock * matchesDoneBlock = BasicBlock::Create(b->getContext(), "matchesDone", scanFunc, 0);
64
65    b->SetInsertPoint(entryBlock);
66    b->CreateBr(matchesCondBlock);
67
68    b->SetInsertPoint(matchesCondBlock);
69    PHINode * matches_phi = b->CreatePHI(T, 2, "matches");
70    matches_phi->addIncoming(matchWord, entryBlock);
71    Value * have_matches_cond = b->CreateICmpUGT(matches_phi, ConstantInt::get(T, 0));
72    b->CreateCondBr(have_matches_cond, matchesLoopBlock, matchesDoneBlock);
73
74    b->SetInsertPoint(matchesLoopBlock);
75    Value * match_pos = b->CreateAdd(b->CreateCountForwardZeroes(matches_phi), basePos);
76    Value * matches_new = b->CreateAnd(matches_phi, b->CreateSub(matches_phi, ConstantInt::get(T, 1)));
77    matches_phi->addIncoming(matches_new, matchesLoopBlock);
78    b->CreateCall(matchProcessor, std::vector<Value *>({match_pos, dist}));
79    b->CreateBr(matchesCondBlock);
80
81    b->SetInsertPoint(matchesDoneBlock);
82    b -> CreateRetVoid();
83
84    return scanFunc;
85
86}
87
88editdScanKernel::editdScanKernel(const std::unique_ptr<kernel::KernelBuilder> & b, StreamSet * matchResults) :
89BlockOrientedKernel("editdScanMatch" + std::to_string(matchResults->getNumElements()),
90              {Binding{"matchResults", matchResults}},
91              {}, {}, {}, {Binding{b->getSizeTy(), "BlockNo"}}),
92mNumElements(matchResults->getNumElements()),
93mScanwordBitWidth(b->getSizeTy()->getBitWidth()) {
94    addAttribute(SideEffecting());
95}
96
97}
Note: See TracBrowser for help on using the repository browser.