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

Last change on this file since 5772 was 5440, checked in by nmedfort, 2 years ago

Large refactoring step. Removed IR generation code from Kernel (formally KernelBuilder?) and moved it into the new KernelBuilder? class.

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