source: icGREP/icgrep-devel/icgrep/pablo/pablo_kernel.cpp @ 5063

Last change on this file since 5063 was 5063, checked in by cameron, 3 years ago

New kernel infrastructure

File size: 3.3 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#include <pablo/pablo_kernel.h>
7#include <pablo/pablo_compiler.h>
8#include <llvm/Support/Debug.h>
9
10
11using namespace pablo;
12using namespace kernel;
13
14PabloKernel::PabloKernel(IDISA::IDISA_Builder * builder,
15                         std::string kernelName,
16                         PabloFunction * function,
17                         std::vector<std::string> accumulators) :
18    KernelBuilder(builder, kernelName,
19                    {StreamSetBinding{StreamSetType(function->getNumOfParameters(), 1), "inputs"}},
20                    {},
21                    {},
22                    {},
23                    {ScalarBinding{builder->getBitBlockType(), "EOFmark"}}),
24    mPabloFunction(function) {
25    unsigned output_streams = function->getNumOfResults();
26    if (output_streams > 0) {
27        mStreamSetOutputs = {StreamSetBinding{StreamSetType(output_streams, 1), "outputs"}};
28    }
29    mScalarOutputs = accumBindings(accumulators);
30    pablo_compiler = new PabloCompiler(builder, this, function);
31}
32
33std::vector<ScalarBinding> PabloKernel::accumBindings(std::vector<std::string> accum_names) {
34    std::vector<ScalarBinding> vec;
35    Type * accum_t = iBuilder->getInt64Ty();
36    for (auto a : accum_names) {
37        vec.push_back(ScalarBinding{accum_t, a});
38        addScalar(accum_t, a);
39    }
40    return vec;
41}
42
43void PabloKernel::prepareKernel() {
44    Type * carryDataType = pablo_compiler->initializeCarryData();
45    addScalar(carryDataType, "carries");
46    finalizeKernelStateType();
47}
48
49void PabloKernel::generateKernel() {
50    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
51    KernelBuilder::generateKernel();
52    Module * m = iBuilder->getModule();
53    addFinalBlockMethod(m);
54    pablo_compiler->compile(m->getFunction(mKernelName + doBlock_suffix));
55    iBuilder->restoreIP(savePoint);
56}
57
58void PabloKernel::addFinalBlockMethod(Module * m) {
59    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
60    Module * saveModule = iBuilder->getModule();
61    iBuilder->setModule(m);
62    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
63    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
64    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_entry", finalBlockFunction, 0));
65    // Final Block arguments: self, remaining, then the standard DoBlock args.
66    Function::arg_iterator args = finalBlockFunction->arg_begin();
67    Value * self = &*(args++);
68    Value * remaining = &*(args++);
69    std::vector<Value *> doBlockArgs = {self};
70    while (args != finalBlockFunction->arg_end()){
71        doBlockArgs.push_back(&*args++);
72    }
73    // Standard Pablo convention for final block processing: set a bit marking
74    // the position just past EOF.
75    Type * bitBlockInt = iBuilder->getIntNTy(iBuilder->getBitBlockWidth());
76    Value * EOFmark = iBuilder->CreateShl(ConstantInt::get(bitBlockInt, 1), iBuilder->CreateZExt(remaining, bitBlockInt));
77    setScalarField(self, "EOFmark", iBuilder->CreateBitCast(EOFmark, iBuilder->getBitBlockType()));
78    iBuilder->CreateCall(doBlockFunction, doBlockArgs);
79    iBuilder->CreateRetVoid();
80    iBuilder->setModule(saveModule);
81    iBuilder->restoreIP(savePoint);
82}
83
Note: See TracBrowser for help on using the repository browser.