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

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

Restore check-ins from the last several days

File size: 7.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_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 <pablo/pablo_toolchain.h>
13#include <kernels/kernel_builder.h>
14#include <llvm/IR/Module.h>
15
16using namespace kernel;
17using namespace parabix;
18using namespace IDISA;
19using namespace llvm;
20
21inline bool isStreamType(const Type * ty) {
22    if (ty->isArrayTy()) {
23        ty = ty->getArrayElementType();
24    }
25    if (ty->isVectorTy()) {
26        return (ty->getVectorNumElements() == 0);
27    }
28    return false;
29}
30
31namespace pablo {
32
33Var * PabloKernel::getInputStreamVar(const std::string & name) {
34    Port port; unsigned index;
35    std::tie(port, index) = getStreamPort(name);
36    assert (port == Port::Input);
37    return mInputs[index];
38}
39
40Var * PabloKernel::getOutputStreamVar(const std::string & name) {
41    Port port; unsigned index;
42    std::tie(port, index) = getStreamPort(name);
43    assert (port == Port::Output);
44    return mOutputs[index];
45}
46
47Var * PabloKernel::getOutputScalarVar(const std::string & name) {
48    const auto f = mScalarOutputNameMap.find(name);
49    if (LLVM_UNLIKELY(f == mScalarOutputNameMap.end())) {
50        report_fatal_error("Kernel does not contain scalar: " + name);
51    }
52    return f->second;
53}
54
55Var * PabloKernel::addInput(const std::string & name, Type * const type) {
56    Var * param = new (mAllocator) Var(makeName(name), type, mAllocator, Var::KernelInputParameter);
57    param->addUser(this);
58    mInputs.push_back(param);
59    mVariables.push_back(param);
60    if (isStreamType(type)) {
61        mStreamMap.emplace(name, std::make_pair(Port::Input, mStreamSetInputs.size()));
62        mStreamSetInputs.emplace_back(type, name);       
63    } else {
64        mScalarInputs.emplace_back(type, name);
65        param->setScalar();
66    }
67    assert (mStreamSetInputs.size() + mScalarInputs.size() == mInputs.size());
68    return param;
69}
70
71Var * PabloKernel::addOutput(const std::string & name, Type * const type) {
72    Var * result = new (mAllocator) Var(makeName(name), type, mAllocator, Var::KernelOutputParameter);
73    result->addUser(this);
74    mOutputs.push_back(result);
75    mVariables.push_back(result);
76    if (isStreamType(type)) {
77        mStreamMap.emplace(name, std::make_pair(Port::Output, mStreamSetOutputs.size()));
78        mStreamSetOutputs.emplace_back(type, name);
79    } else {
80        mScalarOutputs.emplace_back(type, name);
81        mScalarOutputNameMap.emplace(name, result);
82        result->setScalar();
83    }
84    assert (mStreamSetOutputs.size() + mScalarOutputs.size() == mOutputs.size());
85    return result;
86}
87
88Var * PabloKernel::makeVariable(String * name, Type * const type) {
89    Var * const var = new (mAllocator) Var(name, type, mAllocator);
90    mVariables.push_back(var);
91    return var;
92}
93
94Zeroes * PabloKernel::getNullValue(Type * type) {
95    if (LLVM_LIKELY(type == nullptr)) {
96        type = getStreamTy();
97    }
98    for (PabloAST * constant : mConstants) {
99        if (isa<Zeroes>(constant) && constant->getType() == type) {
100            return cast<Zeroes>(constant);
101        }
102    }
103    Zeroes * value = new (mAllocator) Zeroes(type, mAllocator);
104    mConstants.push_back(value);
105    return value;
106}
107
108Ones * PabloKernel::getAllOnesValue(Type * type) {
109    if (LLVM_LIKELY(type == nullptr)) {
110        type = getStreamTy();
111    }
112    for (PabloAST * constant : mConstants) {
113        if (isa<Ones>(constant) && constant->getType() == type) {
114            return cast<Ones>(constant);
115        }
116    }
117    Ones * value = new (mAllocator) Ones(type, mAllocator);
118    mConstants.push_back(value);
119    return value;
120}
121
122void PabloKernel::prepareKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
123    mSizeTy = iBuilder->getSizeTy();
124    mStreamTy = iBuilder->getStreamTy();
125    generatePabloMethod();   
126    pablo_function_passes(this);
127    mPabloCompiler->initializeKernelData(iBuilder);
128    mSizeTy = nullptr;
129    mStreamTy = nullptr;
130    BlockOrientedKernel::prepareKernel(iBuilder);
131}
132
133void PabloKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & iBuilder) {
134    mSizeTy = iBuilder->getSizeTy();
135    mStreamTy = iBuilder->getStreamTy();
136    mPabloCompiler->compile(iBuilder);
137    mSizeTy = nullptr;
138    mStreamTy = nullptr;
139}
140
141void PabloKernel::generateFinalBlockMethod(const std::unique_ptr<KernelBuilder> & iBuilder, Value * const remainingBytes) {
142    // Standard Pablo convention for final block processing: set a bit marking
143    // the position just past EOF, as well as a mask marking all positions past EOF.
144    iBuilder->setScalarField("EOFbit", iBuilder->bitblock_set_bit(remainingBytes));
145    iBuilder->setScalarField("EOFmask", iBuilder->bitblock_mask_from(remainingBytes));
146    CreateDoBlockMethodCall(iBuilder);
147}
148
149void PabloKernel::generateFinalizeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
150    mPabloCompiler->releaseKernelData(iBuilder);
151}
152
153String * PabloKernel::makeName(const llvm::StringRef & prefix) const {
154    return mSymbolTable->makeString(prefix);
155}
156
157Integer * PabloKernel::getInteger(const int64_t value) const {
158    return mSymbolTable->getInteger(value);
159}
160
161llvm::IntegerType * PabloKernel::getInt1Ty() const {
162    return IntegerType::getInt1Ty(getModule()->getContext());
163}
164
165static inline std::string annotateKernelNameWithDebugFlags(std::string && name) {
166    if (DebugOptionIsSet(DumpTrace)) {
167        name += "_DumpTrace";
168    }
169    return name;
170}
171
172PabloKernel::PabloKernel(const std::unique_ptr<KernelBuilder> & b,
173                         std::string && kernelName,
174                         std::vector<Binding> stream_inputs,
175                         std::vector<Binding> stream_outputs,
176                         std::vector<Binding> scalar_parameters,
177                         std::vector<Binding> scalar_outputs)
178: BlockOrientedKernel(annotateKernelNameWithDebugFlags(std::move(kernelName)),
179                      std::move(stream_inputs), std::move(stream_outputs), 
180                      std::move(scalar_parameters), std::move(scalar_outputs),
181                      {Binding{b->getBitBlockType(), "EOFbit"}, Binding{b->getBitBlockType(), "EOFmask"}})
182, PabloAST(PabloAST::ClassTypeId::Kernel, nullptr, mAllocator)
183, mPabloCompiler(new PabloCompiler(this))
184, mSymbolTable(new SymbolGenerator(b->getContext(), mAllocator))
185, mEntryBlock(PabloBlock::Create(this))
186, mSizeTy(nullptr)
187, mStreamTy(nullptr) {
188    prepareStreamSetNameMap();
189    for (const Binding & ss : mStreamSetInputs) {
190        Var * param = new (mAllocator) Var(makeName(ss.name), ss.type, mAllocator, Var::KernelInputParameter);
191        param->addUser(this);
192        mInputs.push_back(param);
193        mVariables.push_back(param);
194    }
195    for (const Binding & ss : mStreamSetOutputs) {
196        Var * result = new (mAllocator) Var(makeName(ss.name), ss.type, mAllocator, Var::KernelOutputParameter);
197        result->addUser(this);
198        mOutputs.push_back(result);
199        mVariables.push_back(result);
200    }
201    for (const Binding & ss : mScalarOutputs) {
202        Var * result = new (mAllocator) Var(makeName(ss.name), ss.type, mAllocator, Var::KernelOutputParameter);
203        result->addUser(this);
204        mOutputs.push_back(result);
205        mVariables.push_back(result);
206        mScalarOutputNameMap.emplace(ss.name, result);
207        result->setScalar();
208    }
209}
210
211PabloKernel::~PabloKernel() {
212    delete mPabloCompiler;
213    delete mSymbolTable; 
214}
215
216}
Note: See TracBrowser for help on using the repository browser.