source: icGREP/icgrep-devel/icgrep/kernels/cc_scan_kernel.cpp @ 5440

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