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

Last change on this file since 5843 was 5843, checked in by cameron, 15 months ago

CC Compiler refactoring step

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