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

Last change on this file since 5829 was 5828, checked in by nmedfort, 18 months ago

Pablo support for byte comparisions; LineFeed? kernel processes byte streams directly. Some clean up of PabloBuilder? functionality.

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