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

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

Bug fix check in for DumpTrace?, compilation of DoBlock? / DoFinalBlock? functions. Pablo CodeMotionPass? optimized and enabled by default.

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