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

Last change on this file since 5299 was 5299, checked in by cameron, 2 years ago

Ability to set input/output signatures for Pablo functions in the constructor

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