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

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

Initial work on adding types to PabloAST and mutable Var objects.

File size: 4.4 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#include <pablo/pe_var.h>
10#include <pablo/type/streamtype.h>
11#include <llvm/IR/Verifier.h>
12
13using namespace pablo;
14using namespace kernel;
15using namespace parabix;
16
17PabloKernel::PabloKernel(IDISA::IDISA_Builder * builder,
18                         std::string kernelName,
19                         PabloFunction * function)
20: KernelBuilder(builder, kernelName, {}, {}, {}, {}, {Binding{builder->getBitBlockType(), "EOFbit"}, Binding{builder->getBitBlockType(), "EOFmask"}})
21, mPabloFunction(function)
22, mPabloCompiler(new PabloCompiler(this, function))
23
24{
25    for (unsigned i = 0; i < function->getNumOfParameters(); ++i) {
26        const auto param = function->getParameter(i);
27        Type * type = param->getType();
28        bool scalar = false;
29        if (isa<StreamType>(type)) {
30            type = cast<StreamType>(type)->resolveType(builder);
31        } else if (type->isSingleValueType()) {
32            scalar = true;
33        }
34        std::string name = param->getName()->to_string();
35        if (scalar) {
36            mScalarInputs.emplace_back(type, std::move(name));
37        } else {
38            mStreamSetInputs.emplace_back(type, std::move(name));
39        }
40    }
41
42    for (unsigned i = 0; i < function->getNumOfResults(); ++i) {
43        const auto param = function->getResult(i);
44        Type * type = param->getType();
45        bool scalar = false;
46        if (isa<StreamType>(type)) {
47            type = cast<StreamType>(type)->resolveType(builder);
48        } else if (type->isSingleValueType()) {
49            scalar = true;
50        }
51        std::string name = param->getName()->to_string();
52        if (scalar) {
53            mScalarOutputs.emplace_back(type, std::move(name));
54        } else {
55            mStreamSetOutputs.emplace_back(type, std::move(name));
56        }
57    }
58
59
60}
61
62PabloKernel::~PabloKernel() {
63    delete mPabloCompiler;
64}
65
66void PabloKernel::prepareKernel() {
67    Type * carryDataType = mPabloCompiler->initializeKernelData();
68    addScalar(carryDataType, "carries");
69    KernelBuilder::prepareKernel();
70}
71
72void PabloKernel::generateDoBlockMethod() {
73    auto savePoint = iBuilder->saveIP();
74    Module * m = iBuilder->getModule();
75    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
76    mPabloCompiler->compile(doBlockFunction);
77    Function::arg_iterator args = doBlockFunction->arg_begin();
78    Value * self = &*(args);
79    Value * produced = getProducedItemCount(self);
80    produced = iBuilder->CreateAdd(produced, ConstantInt::get(iBuilder->getSizeTy(), iBuilder->getStride()));
81    setProducedItemCount(self, produced);
82    iBuilder->CreateRetVoid();
83    #ifndef NDEBUG
84    llvm::verifyFunction(*doBlockFunction, &errs());
85    #endif
86    iBuilder->restoreIP(savePoint);
87}
88
89void PabloKernel::generateFinalBlockMethod() {
90    auto savePoint = iBuilder->saveIP();
91    Module * m = iBuilder->getModule();
92    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
93    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
94    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_entry", finalBlockFunction, 0));
95    // Final Block arguments: self, remaining, then the standard DoBlock args.
96    Function::arg_iterator args = finalBlockFunction->arg_begin();
97    Value * self = &*(args++);
98    Value * remaining = &*(args++);
99    std::vector<Value *> doBlockArgs = {self};
100    while (args != finalBlockFunction->arg_end()){
101        doBlockArgs.push_back(&*args++);
102    }
103    // Standard Pablo convention for final block processing: set a bit marking
104    // the position just past EOF, as well as a mask marking all positions past EOF.
105    setScalarField(self, "EOFbit", iBuilder->bitblock_set_bit(remaining));
106    setScalarField(self, "EOFmask", iBuilder->bitblock_mask_from(remaining));
107    iBuilder->CreateCall(doBlockFunction, doBlockArgs);
108    /* Adjust the produced item count */
109    Value * produced = getProducedItemCount(self);
110    produced = iBuilder->CreateSub(produced, ConstantInt::get(iBuilder->getSizeTy(), iBuilder->getStride()));
111    setProducedItemCount(self, iBuilder->CreateAdd(produced, remaining));
112    iBuilder->CreateRetVoid();
113    #ifndef NDEBUG
114    llvm::verifyFunction(*doBlockFunction, &errs());
115    #endif
116    iBuilder->restoreIP(savePoint);
117}
Note: See TracBrowser for help on using the repository browser.