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

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

Restructuring work for the Driver classes. Start of work to eliminate the memory leaks with the ExecutionEngine?. Replaced custom AlignedMalloc? with backend call to std::aligned_malloc. Salvaged some work on DistributionPass? for reevaluation.

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 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
149String * PabloKernel::makeName(const llvm::StringRef & prefix) const {
150    return mSymbolTable->makeString(prefix);
151}
152
153Integer * PabloKernel::getInteger(const int64_t value) const {
154    return mSymbolTable->getInteger(value);
155}
156
157llvm::IntegerType * PabloKernel::getInt1Ty() const {
158    return IntegerType::getInt1Ty(getModule()->getContext());
159}
160
161static inline std::string annotateKernelNameWithDebugFlags(std::string && name) {
162    if (DebugOptionIsSet(DumpTrace)) {
163        name += "_DumpTrace";
164    }
165    return name;
166}
167
168PabloKernel::PabloKernel(const std::unique_ptr<KernelBuilder> & b,
169                         std::string && kernelName,
170                         std::vector<Binding> stream_inputs,
171                         std::vector<Binding> stream_outputs,
172                         std::vector<Binding> scalar_parameters,
173                         std::vector<Binding> scalar_outputs)
174: BlockOrientedKernel(std::move(annotateKernelNameWithDebugFlags(std::move(kernelName))),
175                      std::move(stream_inputs), std::move(stream_outputs), 
176                      std::move(scalar_parameters), std::move(scalar_outputs),
177                      {Binding{b->getBitBlockType(), "EOFbit"}, Binding{b->getBitBlockType(), "EOFmask"}})
178, PabloAST(PabloAST::ClassTypeId::Kernel, nullptr, mAllocator)
179, mPabloCompiler(new PabloCompiler(this))
180, mSymbolTable(new SymbolGenerator(b->getContext(), mAllocator))
181, mEntryBlock(PabloBlock::Create(this))
182, mSizeTy(nullptr)
183, mStreamTy(nullptr) {
184    prepareStreamSetNameMap();
185    for (const Binding & ss : mStreamSetInputs) {
186        Var * param = new (mAllocator) Var(makeName(ss.name), ss.type, mAllocator, Var::KernelInputParameter);
187        param->addUser(this);
188        mInputs.push_back(param);
189        mVariables.push_back(param);
190    }
191    for (const Binding & ss : mStreamSetOutputs) {
192        Var * result = new (mAllocator) Var(makeName(ss.name), ss.type, mAllocator, Var::KernelOutputParameter);
193        result->addUser(this);
194        mOutputs.push_back(result);
195        mVariables.push_back(result);
196    }
197    for (const Binding & ss : mScalarOutputs) {
198        Var * result = new (mAllocator) Var(makeName(ss.name), ss.type, mAllocator, Var::KernelOutputParameter);
199        result->addUser(this);
200        mOutputs.push_back(result);
201        mVariables.push_back(result);
202        mScalarOutputNameMap.emplace(ss.name, result);
203        result->setScalar();
204    }
205}
206
207PabloKernel::~PabloKernel() {
208    delete mPabloCompiler;
209    delete mSymbolTable; 
210}
211
212}
Note: See TracBrowser for help on using the repository browser.