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

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

Multi-threading support for PabloAST / PabloCompiler?. Requires unique LLVM Context / Module for each thread.

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