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

Last change on this file since 5805 was 5440, checked in by nmedfort, 23 months 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.