source: icGREP/icgrep-devel/icgrep/kernels/interface.cpp @ 5287

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

More changes towards simplifying the KernelBuilder?

File size: 4.6 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 "interface.h"
7#include <llvm/IR/Value.h>         // for Value
8#include <llvm/IR/CallingConv.h>   // for ::C
9#include <llvm/IR/DerivedTypes.h>  // for FunctionType (ptr only), PointerType
10#include <llvm/IR/Function.h>      // for Function, Function::arg_iterator
11#include <llvm/IR/Module.h>
12#include <IR_Gen/idisa_builder.h>
13namespace llvm { class Module; }
14namespace llvm { class Type; }
15
16static const auto INIT_SUFFIX = "_Init";
17
18static const auto DO_SEGMENT_SUFFIX = "_DoSegment";
19
20static const auto ACCUMULATOR_INFIX = "_get_";
21
22using namespace llvm;
23
24void KernelInterface::addKernelDeclarations(Module * client) const {
25    Module * saveModule = iBuilder->getModule();
26    auto savePoint = iBuilder->saveIP();
27    iBuilder->setModule(client);
28    if (mKernelStateType == nullptr) {
29        throw std::runtime_error("Kernel interface " + mKernelName + " not yet finalized.");
30    }
31    PointerType * selfType = PointerType::getUnqual(mKernelStateType);
32
33    // Create the accumulator get function prototypes
34    for (auto binding : mScalarOutputs) {
35        FunctionType * accumFnType = FunctionType::get(binding.type, {selfType}, false);
36        std::string fnName = mKernelName + ACCUMULATOR_INFIX + binding.name;
37        Function * accumFn = Function::Create(accumFnType, GlobalValue::ExternalLinkage, fnName, client);
38        accumFn->setCallingConv(CallingConv::C);
39        accumFn->setDoesNotThrow();
40        Value * self = &*(accumFn->arg_begin());
41        self->setName("self");       
42    }
43
44    // Create the initialization function prototype
45    std::vector<Type *> initParameters = {selfType};
46    for (auto binding : mScalarInputs) {
47        initParameters.push_back(binding.type);
48    }
49    FunctionType * initFunctionType = FunctionType::get(iBuilder->getVoidTy(), initParameters, false);
50    std::string initFnName = mKernelName + INIT_SUFFIX;
51    Function * initFn = Function::Create(initFunctionType, GlobalValue::ExternalLinkage, initFnName, client);
52    initFn->setCallingConv(CallingConv::C);
53    initFn->setDoesNotThrow();
54    Function::arg_iterator initArgs = initFn->arg_begin();
55    Value * initArg = &*(initArgs++);
56    initArg->setName("self");
57    for (auto binding : mScalarInputs) {
58        initArg = &*(initArgs++);
59        initArg->setName(binding.name);
60    }
61
62    // Create the doSegment function prototype.
63    std::vector<Type *> doSegmentParameters = {selfType, iBuilder->getInt1Ty()};
64    for (auto ss : mStreamSetInputs) {
65        doSegmentParameters.push_back(iBuilder->getSizeTy());
66    }
67    FunctionType * doSegmentFunctionType = FunctionType::get(iBuilder->getVoidTy(), doSegmentParameters, false);
68    std::string doSegmentName = mKernelName + DO_SEGMENT_SUFFIX;
69    Function * doSegmentFn = Function::Create(doSegmentFunctionType, GlobalValue::ExternalLinkage, doSegmentName, client);
70    doSegmentFn->setCallingConv(CallingConv::C);
71    doSegmentFn->setDoesNotThrow();
72    Function::arg_iterator args = doSegmentFn->arg_begin();
73    Value * arg = &*(args++);
74    arg->setName("self");
75    arg = &*(args++);
76    arg->setName("doFinal");
77    for (auto ss : mStreamSetInputs) {
78        arg = &*(args++);
79        arg->setName(ss.name + "_availableItems");
80    }
81    doSegmentFn->setDoesNotCapture(1); // for self parameter only.
82
83    // Add any additional kernel declarations
84    addAdditionalKernelDeclarations(client, selfType);
85
86    iBuilder->setModule(saveModule);
87    iBuilder->restoreIP(savePoint);
88}
89
90void KernelInterface::addAdditionalKernelDeclarations(llvm::Module * module, llvm::PointerType * selfType) const {
91
92}
93
94void KernelInterface::setInitialArguments(std::vector<Value *> args) {
95    mInitialArguments = args;
96}
97
98llvm::Function * KernelInterface::getAccumulatorFunction(const std::string & accumName) const {
99    const auto name = mKernelName + ACCUMULATOR_INFIX + accumName;
100    Function * f = iBuilder->getModule()->getFunction(name);
101    if (LLVM_UNLIKELY(f == nullptr)) {
102        llvm::report_fatal_error("Cannot find " + name);
103    }
104    return f;
105}
106
107Function * KernelInterface::getInitFunction() const {
108    const auto name = mKernelName + INIT_SUFFIX;
109    Function * f = iBuilder->getModule()->getFunction(name);
110    if (LLVM_UNLIKELY(f == nullptr)) {
111        llvm::report_fatal_error("Cannot find " + name);
112    }
113    return f;
114}
115
116Function * KernelInterface::getDoSegmentFunction() const {
117    const auto name = mKernelName + DO_SEGMENT_SUFFIX;
118    Function * f = iBuilder->getModule()->getFunction(name);
119    if (LLVM_UNLIKELY(f == nullptr)) {
120        llvm::report_fatal_error("Cannot find " + name);
121    }
122    return f;
123}
Note: See TracBrowser for help on using the repository browser.