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

Last change on this file since 5320 was 5320, checked in by nmedfort, 3 years ago

memcpy/memset support for 32-bit systems; more error messages/handling; bug fix for ParabixCharacterClassKernelBuilder?. continued work on parenthesis matching + expandable buffers.

File size: 4.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 "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) {
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 " + getName() + " not yet finalized.");
30    }
31    PointerType * selfType = PointerType::getUnqual(mKernelStateType);
32
33    // Create the initialization function prototype
34    std::vector<Type *> initParameters = {selfType};
35    for (auto binding : mScalarInputs) {
36        initParameters.push_back(binding.type);
37    }
38    FunctionType * initType = FunctionType::get(iBuilder->getVoidTy(), initParameters, false);
39    Function * init = Function::Create(initType, GlobalValue::ExternalLinkage, getName() + INIT_SUFFIX, client);
40    init->setCallingConv(CallingConv::C);
41    init->setDoesNotThrow();
42    auto args = init->arg_begin();
43    args->setName("self");
44    for (auto binding : mScalarInputs) {
45        (++args)->setName(binding.name);
46    }
47
48    // Create the doSegment function prototype.
49    std::vector<Type *> doSegmentParameters = {selfType, iBuilder->getInt1Ty()};
50    for (unsigned i = 0; i < mStreamSetInputs.size(); ++i) {
51        doSegmentParameters.push_back(iBuilder->getSizeTy());
52    }
53    FunctionType * doSegmentType = FunctionType::get(iBuilder->getVoidTy(), doSegmentParameters, false);
54    Function * doSegment = Function::Create(doSegmentType, GlobalValue::ExternalLinkage, getName() + DO_SEGMENT_SUFFIX, client);
55    doSegment->setCallingConv(CallingConv::C);
56    doSegment->setDoesNotThrow();
57    doSegment->setDoesNotCapture(1); // for self parameter only.
58    args = doSegment->arg_begin();
59    args->setName("self");
60    (++args)->setName("doFinal");
61    for (auto ss : mStreamSetInputs) {
62        (++args)->setName(ss.name + "_availableItems");
63    }
64
65    // Add any additional kernel declarations
66    addAdditionalKernelDeclarations(client, selfType);
67
68    // Create the accumulator get function prototypes
69    for (const auto & binding : mScalarOutputs) {
70        FunctionType * accumFnType = FunctionType::get(binding.type, {selfType}, false);
71        Function * accumFn = Function::Create(accumFnType, GlobalValue::ExternalLinkage, getName() + ACCUMULATOR_INFIX + binding.name, client);
72        accumFn->setCallingConv(CallingConv::C);
73        accumFn->setDoesNotThrow();
74        accumFn->setDoesNotCapture(1);
75        auto args = accumFn->arg_begin();
76        args->setName("self");
77        assert ((++args) == accumFn->arg_end());
78    }
79
80    iBuilder->setModule(saveModule);
81    iBuilder->restoreIP(savePoint);
82}
83
84void KernelInterface::setInitialArguments(std::vector<Value *> args) {
85    mInitialArguments = args;
86}
87
88llvm::Function * KernelInterface::getAccumulatorFunction(const std::string & accumName) const {
89    const auto name = getName() + ACCUMULATOR_INFIX + accumName;
90    Function * f = iBuilder->getModule()->getFunction(name);
91    if (LLVM_UNLIKELY(f == nullptr)) {
92        llvm::report_fatal_error("Cannot find " + name);
93    }
94    return f;
95}
96
97Function * KernelInterface::getInitFunction() const {
98    const auto name = getName() + INIT_SUFFIX;
99    Function * f = iBuilder->getModule()->getFunction(name);
100    if (LLVM_UNLIKELY(f == nullptr)) {
101        llvm::report_fatal_error("Cannot find " + name);
102    }
103    return f;
104}
105
106Function * KernelInterface::getDoSegmentFunction() const {
107    const auto name = getName() + DO_SEGMENT_SUFFIX;
108    Function * f = iBuilder->getModule()->getFunction(name);
109    if (LLVM_UNLIKELY(f == nullptr)) {
110        llvm::report_fatal_error("Cannot find " + name);
111    }
112    return f;
113}
Note: See TracBrowser for help on using the repository browser.