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

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

Merged PabloFunction? and PabloKernel? classes. Updated projects where necessary.

File size: 5.2 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/pablo_kernel.h>
7#include <pablo/pablo_compiler.h>
8#include <llvm/Support/Debug.h>
9#include <pablo/pe_var.h>
10#include <llvm/IR/Verifier.h>
11#include <IDISA/idisa_builder.h>
12#include <pablo/prototype.h>
13
14using namespace pablo;
15using namespace kernel;
16using namespace parabix;
17using namespace IDISA;
18
19Var * PabloKernel::addInput(const std::string name, Type * const type) {
20    Var * param = new Var(mSymbolTable->make(name), type);
21    mInputs.push_back(param);
22    if (isa<StreamType>(type)) {
23        Type * const resolvedType = cast<StreamType>(type)->resolveType(iBuilder);
24        mStreamSetInputs.emplace_back(resolvedType, name);
25    } else {
26        mScalarInputs.emplace_back(type, name);
27    }
28    assert (mStreamSetInputs.size() + mScalarInputs.size() == mInputs.size());
29    return param;
30}
31
32Var * PabloKernel::addOutput(const std::string name, Type * const type) {
33    Var * result = new Var(mSymbolTable->make(name), type);
34    mOutputs.push_back(result);
35    if (isa<StreamType>(type)) {
36        Type * const resolvedType = cast<StreamType>(type)->resolveType(iBuilder);
37        mStreamSetOutputs.emplace_back(resolvedType, name);
38    } else {
39        mScalarOutputs.emplace_back(type, name);
40    }
41    assert (mStreamSetOutputs.size() + mScalarOutputs.size() == mOutputs.size());
42    return result;
43}
44
45Var * PabloKernel::makeVariable(PabloAST * name, Type * const type) {
46    Var * const var = new Var(name, type);
47    mVariables.push_back(var);
48    return var;
49}
50
51Zeroes * PabloKernel::getNullValue(Type * type) {
52    if (type == nullptr) {
53        type = getStreamSetTy();
54    }
55    for (PabloAST * constant : mConstants) {
56        if (isa<Zeroes>(constant) && constant->getType() == type) {
57            return cast<Zeroes>(constant);
58        }
59    }
60    Zeroes * value = new Zeroes(type);
61    mConstants.push_back(value);
62    return value;
63}
64
65Ones * PabloKernel::getAllOnesValue(Type * type) {
66    if (type == nullptr) {
67        type = getStreamSetTy();
68    }
69    for (PabloAST * constant : mConstants) {
70        if (isa<Ones>(constant) && constant->getType() == type) {
71            return cast<Ones>(constant);
72        }
73    }
74    Ones * value = new Ones(type);
75    mConstants.push_back(value);
76    return value;
77}
78
79void PabloKernel::prepareKernel() {
80    Type * carryDataType = mPabloCompiler->initializeKernelData();
81    addScalar(carryDataType, "carries");
82    KernelBuilder::prepareKernel();
83}
84
85void PabloKernel::generateDoBlockMethod() {
86    auto savePoint = iBuilder->saveIP();
87    Module * m = iBuilder->getModule();
88    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
89    auto args = doBlockFunction->arg_begin();
90    Value * const self = &*(args);
91    mPabloCompiler->compile(self, doBlockFunction);
92    Value * produced = getProducedItemCount(self);
93    produced = iBuilder->CreateAdd(produced, ConstantInt::get(iBuilder->getSizeTy(), iBuilder->getStride()));
94    setProducedItemCount(self, produced);
95    iBuilder->CreateRetVoid();
96    #ifndef NDEBUG
97    llvm::verifyFunction(*doBlockFunction, &errs());
98    #endif
99    iBuilder->restoreIP(savePoint);
100}
101
102void PabloKernel::generateFinalBlockMethod() {
103    auto savePoint = iBuilder->saveIP();
104    Module * m = iBuilder->getModule();
105    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
106    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
107    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_entry", finalBlockFunction, 0));
108    // Final Block arguments: self, remaining, then the standard DoBlock args.
109    Function::arg_iterator args = finalBlockFunction->arg_begin();
110    Value * self = &*(args++);
111    Value * remaining = &*(args++);
112    std::vector<Value *> doBlockArgs = {self};
113    while (args != finalBlockFunction->arg_end()){
114        doBlockArgs.push_back(&*args++);
115    }
116    // Standard Pablo convention for final block processing: set a bit marking
117    // the position just past EOF, as well as a mask marking all positions past EOF.
118    setScalarField(self, "EOFbit", iBuilder->bitblock_set_bit(remaining));
119    setScalarField(self, "EOFmask", iBuilder->bitblock_mask_from(remaining));
120    iBuilder->CreateCall(doBlockFunction, doBlockArgs);
121    /* Adjust the produced item count */
122    Value * produced = getProducedItemCount(self);
123    produced = iBuilder->CreateSub(produced, ConstantInt::get(iBuilder->getSizeTy(), iBuilder->getStride()));
124    setProducedItemCount(self, iBuilder->CreateAdd(produced, remaining));
125    iBuilder->CreateRetVoid();
126    #ifndef NDEBUG
127    llvm::verifyFunction(*doBlockFunction, &errs());
128    #endif
129    iBuilder->restoreIP(savePoint);
130}
131
132PabloKernel::PabloKernel(IDISA::IDISA_Builder * builder, const std::string & kernelName)
133: KernelBuilder(builder, kernelName, {}, {}, {}, {}, {Binding{builder->getBitBlockType(), "EOFbit"}, Binding{builder->getBitBlockType(), "EOFmask"}})
134, mPabloCompiler(new PabloCompiler(this))
135, mSymbolTable(new SymbolGenerator())
136, mEntryBlock(PabloBlock::Create(this))
137{
138
139}
140
141PabloKernel::~PabloKernel() {
142    delete mPabloCompiler;
143    delete mSymbolTable;
144}
145
Note: See TracBrowser for help on using the repository browser.