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

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

Added enable asserts (-ea) command line flag + restructured BlockOrientedKernels? to allow for inlined code.

File size: 6.1 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_kernel.h"
7#include <pablo/codegenstate.h>
8#include <pablo/pablo_compiler.h>
9#include <pablo/pe_var.h>
10#include <pablo/pe_zeroes.h>
11#include <pablo/pe_ones.h>
12#include "llvm/Support/Debug.h"
13
14using namespace pablo;
15using namespace kernel;
16using namespace parabix;
17using namespace IDISA;
18using namespace llvm;
19
20inline bool isStreamType(const Type * ty) {
21    if (ty->isArrayTy()) {
22        ty = ty->getArrayElementType();
23    }
24    if (ty->isVectorTy()) {
25        return (ty->getVectorNumElements() == 0);
26    }
27    return false;
28}
29
30Var * PabloKernel::getInputStreamVar(const std::string & inputSetName) {
31    return mInputs[getStreamSetIndex(inputSetName)];
32}
33
34Var * PabloKernel::getOutputStreamVar(const std::string & outputSetName) {
35    return mOutputs[getStreamSetIndex(outputSetName)];
36}
37
38Var * PabloKernel::getOutputScalarVar(const std::string & outputName) {
39    const auto f = mScalarOutputNameMap.find(outputName);
40    if (LLVM_UNLIKELY(f == mScalarOutputNameMap.end())) {
41        report_fatal_error("Kernel does not contain scalar: " + outputName);
42    }
43    return f->second;
44}
45
46Var * PabloKernel::addInput(const std::string & name, Type * const type) {
47    Var * param = new (mAllocator) Var(mSymbolTable->makeString(name, iBuilder), type, mAllocator, Var::KernelInputParameter);
48    param->addUser(this);
49    mInputs.push_back(param);
50    mVariables.push_back(param);
51    if (isStreamType(type)) {
52        mStreamSetNameMap.emplace(name, mStreamSetInputs.size());
53        mStreamSetInputs.emplace_back(type, name);       
54    } else {
55        mScalarInputs.emplace_back(type, name);
56        param->setScalar();
57    }
58    assert (mStreamSetInputs.size() + mScalarInputs.size() == mInputs.size());
59    return param;
60}
61
62Var * PabloKernel::addOutput(const std::string & name, Type * const type) {
63    Var * result = new (mAllocator) Var(mSymbolTable->makeString(name, iBuilder), type, mAllocator, Var::KernelOutputParameter);
64    result->addUser(this);
65    mOutputs.push_back(result);
66    mVariables.push_back(result);
67    if (isStreamType(type)) {
68        mStreamSetNameMap.emplace(name, mStreamSetOutputs.size());
69        mStreamSetOutputs.emplace_back(type, name);
70    } else {
71        mScalarOutputs.emplace_back(type, name);
72        mScalarOutputNameMap.emplace(name, result);
73        result->setScalar();
74    }
75    assert (mStreamSetOutputs.size() + mScalarOutputs.size() == mOutputs.size());
76    return result;
77}
78
79Var * PabloKernel::makeVariable(String * name, Type * const type) {
80    Var * const var = new (mAllocator) Var(name, type, mAllocator);
81    mVariables.push_back(var);
82    return var;
83}
84
85Zeroes * PabloKernel::getNullValue(Type * type) {
86    if (type == nullptr) {
87        type = getStreamTy();
88    }
89    for (PabloAST * constant : mConstants) {
90        if (isa<Zeroes>(constant) && constant->getType() == type) {
91            return cast<Zeroes>(constant);
92        }
93    }
94    Zeroes * value = new (mAllocator) Zeroes(type, mAllocator);
95    mConstants.push_back(value);
96    return value;
97}
98
99Ones * PabloKernel::getAllOnesValue(Type * type) {
100    if (type == nullptr) {
101        type = getStreamTy();
102    }
103    for (PabloAST * constant : mConstants) {
104        if (isa<Ones>(constant) && constant->getType() == type) {
105            return cast<Ones>(constant);
106        }
107    }
108    Ones * value = new (mAllocator) Ones(type, mAllocator);
109    mConstants.push_back(value);
110    return value;
111}
112
113void PabloKernel::prepareKernel() {
114    mPabloCompiler->initializeKernelData();
115    BlockOrientedKernel::prepareKernel();
116}
117
118void PabloKernel::generateDoBlockMethod() {
119    mPabloCompiler->compile();
120}
121
122void PabloKernel::generateFinalBlockMethod(Value * remainingBytes) {
123    // Standard Pablo convention for final block processing: set a bit marking
124    // the position just past EOF, as well as a mask marking all positions past EOF.
125    setScalarField("EOFbit", iBuilder->bitblock_set_bit(remainingBytes));
126    setScalarField("EOFmask", iBuilder->bitblock_mask_from(remainingBytes));
127    CreateDoBlockMethodCall();
128}
129
130PabloKernel::PabloKernel(IDISA::IDISA_Builder * builder, std::string kernelName,
131                         std::vector<Binding> stream_inputs,
132                         std::vector<Binding> stream_outputs,
133                         std::vector<Binding> scalar_parameters,
134                         std::vector<Binding> scalar_outputs)
135: BlockOrientedKernel(builder, std::move(kernelName), 
136                      std::move(stream_inputs), std::move(stream_outputs), 
137                      std::move(scalar_parameters), std::move(scalar_outputs),
138                      {Binding{builder->getBitBlockType(), "EOFbit"}, Binding{builder->getBitBlockType(), "EOFmask"}})
139, PabloAST(PabloAST::ClassTypeId::Kernel, nullptr, mAllocator)
140, mPabloCompiler(new PabloCompiler(this))
141, mSymbolTable(new SymbolGenerator(mAllocator))
142, mEntryBlock(PabloBlock::Create(this)) {
143    setDoBlockUpdatesProducedItemCountsAttribute(false);
144    prepareKernelSignature();
145    for (const Binding & ss : mStreamSetInputs) {
146        Var * param = new (mAllocator) Var(mSymbolTable->makeString(ss.name, iBuilder), ss.type, mAllocator, Var::KernelInputParameter);
147        param->addUser(this);
148        mInputs.push_back(param);
149        mVariables.push_back(param);
150    }
151    for (const Binding & ss : mStreamSetOutputs) {
152        Var * result = new (mAllocator) Var(mSymbolTable->makeString(ss.name, iBuilder), ss.type, mAllocator, Var::KernelOutputParameter);
153        result->addUser(this);
154        mOutputs.push_back(result);
155        mVariables.push_back(result);
156    }
157    for (const Binding & ss : mScalarOutputs) {
158        Var * result = new (mAllocator) Var(mSymbolTable->makeString(ss.name, iBuilder), ss.type, mAllocator, Var::KernelOutputParameter);
159        result->addUser(this);
160        mOutputs.push_back(result);
161        mVariables.push_back(result);
162        mScalarOutputNameMap.emplace(ss.name, result);
163        result->setScalar();
164    }
165}
166
167PabloKernel::~PabloKernel() {
168    delete mPabloCompiler;
169    delete mSymbolTable; 
170}
171
Note: See TracBrowser for help on using the repository browser.