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

Last change on this file since 5204 was 5204, checked in by nmedfort, 2 years ago

More 32-bit fixes.

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