source: icGREP/icgrep-devel/icgrep/kernels/interface.h @ 5836

Last change on this file since 5836 was 5836, checked in by nmedfort, 20 months ago

Added PabloBlock/Builder? createScope() methods + minor code changes.

File size: 6.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#ifndef KERNEL_INTERFACE_H
7#define KERNEL_INTERFACE_H
8
9#include <kernels/processing_rate.h>
10#include <kernels/attributes.h>
11#include <llvm/Support/Compiler.h>
12#include <memory>
13#include <string>
14#include <vector>
15
16namespace IDISA { class IDISA_Builder; }
17namespace kernel { class Kernel; }
18namespace kernel { class KernelBuilder; }
19namespace llvm { class CallInst; }
20namespace llvm { class Function; }
21namespace llvm { class Value; }
22namespace llvm { class Module; }
23namespace llvm { class StructType; }
24namespace llvm { class Type; }
25
26namespace kernel {
27
28struct Binding : public AttributeSet {
29
30    Binding(llvm::Type * type, const std::string & name, ProcessingRate r = FixedRate(1))
31    : AttributeSet()
32    , mType(type), mName(name), mRate(std::move(r)) { }
33
34
35    Binding(llvm::Type * type, const std::string & name, ProcessingRate r, Attribute && attribute)
36    : AttributeSet(std::move(attribute))
37    , mType(type), mName(name), mRate(std::move(r)) { }
38
39
40    Binding(llvm::Type * type, const std::string & name, ProcessingRate r, std::initializer_list<Attribute> attributes)
41    : AttributeSet(attributes)
42    , mType(type), mName(name), mRate(std::move(r)) { }
43
44    llvm::Type * getType() const {
45        return mType;
46    }
47
48    const std::string & getName() const {
49        return mName;
50    }
51
52    const ProcessingRate & getRate() const {
53        return mRate;
54    }
55
56    ProcessingRate & getRate() {
57        return mRate;
58    }
59
60    bool isPrincipal() const {
61        return hasAttribute(AttributeId::Principal);
62    }
63
64    bool hasLookahead() const {
65        return hasAttribute(AttributeId::LookAhead);
66    }
67
68    bool isMisaligned() const {
69        return hasAttribute(AttributeId::Misaligned);
70    }
71
72    unsigned const getLookahead() const {
73        return findAttribute(AttributeId::LookAhead).amount();
74    }
75
76    bool nonDeferred() const {
77        return !hasAttribute(AttributeId::Deferred);
78    }
79
80private:
81    llvm::Type * const          mType;
82    const std::string           mName;
83    ProcessingRate              mRate;
84};
85
86using Bindings = std::vector<Binding>;
87
88class KernelInterface : public AttributeSet {
89public:
90    /*
91     
92     This class defines the methods to be used to generate the code 
93     necessary for declaring, allocating, calling and synchronizing
94     kernels.   The methods to be used for constructing kernels are defined
95     within the KernelBuilder class of kernel.h
96     
97     */
98   
99    const std::string & getName() const {
100        return mKernelName;
101    }
102       
103    virtual bool isCachable() const = 0;
104
105    virtual std::string makeSignature(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
106
107    const std::vector<Binding> & getStreamInputs() const {
108        return mStreamSetInputs;
109    }
110
111    const Binding & getStreamInput(const unsigned i) const {
112        assert (i < getNumOfStreamInputs());
113        return mStreamSetInputs[i];
114    }
115
116    unsigned getNumOfStreamInputs() const {
117        return mStreamSetInputs.size();
118    }
119
120    const std::vector<Binding> & getStreamOutputs() const {
121        return mStreamSetOutputs;
122    }
123
124    unsigned getNumOfStreamOutputs() const {
125        return mStreamSetOutputs.size();
126    }
127
128    const Binding & getStreamOutput(const unsigned i) const {
129        assert (i < getNumOfStreamOutputs());
130        return mStreamSetOutputs[i];
131    }
132
133    const std::vector<Binding> & getScalarInputs() const {
134        return mScalarInputs;
135    }
136
137    const Binding & getScalarInput(const unsigned i) const {
138        return mScalarInputs[i];
139    }
140
141    const std::vector<Binding> & getScalarOutputs() const {
142        return mScalarOutputs;
143    }
144
145    const Binding & getScalarOutput(const unsigned i) const {
146        return mScalarOutputs[i];
147    }
148
149    // Add ExternalLinkage method declarations for the kernel to a given client module.
150    void addKernelDeclarations(const std::unique_ptr<kernel::KernelBuilder> & idb);
151
152    virtual void linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
153
154    virtual llvm::Value * createInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
155
156    virtual void initializeInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
157
158    virtual void finalizeInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
159
160    void setInitialArguments(std::vector<llvm::Value *> && args) {
161        mInitialArguments.swap(args);
162    }
163
164    llvm::Value * getInstance() const {
165        return mKernelInstance;
166    }
167
168    void setInstance(llvm::Value * const instance);
169
170    bool hasPrincipalItemCount() const {
171        return mHasPrincipalItemCount;
172    }
173
174protected:
175
176    llvm::Function * getInitFunction(llvm::Module * const module) const;
177
178    llvm::Function * getDoSegmentFunction(llvm::Module * const module) const;
179
180    llvm::Function * getTerminateFunction(llvm::Module * const module) const;
181
182    llvm::CallInst * makeDoSegmentCall(KernelBuilder & idb, const std::vector<llvm::Value *> & args) const;
183
184    KernelInterface(const std::string && kernelName,
185                    Bindings && stream_inputs,
186                    Bindings && stream_outputs,
187                    Bindings && scalar_inputs,
188                    Bindings && scalar_outputs,
189                    Bindings && internal_scalars)
190    : mKernelInstance(nullptr)
191    , mModule(nullptr)
192    , mKernelStateType(nullptr)
193    , mHasPrincipalItemCount(false)
194    , mKernelName(kernelName)
195    , mStreamSetInputs(stream_inputs)
196    , mStreamSetOutputs(stream_outputs)
197    , mScalarInputs(scalar_inputs)
198    , mScalarOutputs(scalar_outputs)
199    , mInternalScalars(internal_scalars) {
200
201    }
202   
203protected:
204
205    llvm::Value *                   mKernelInstance;
206    llvm::Module *                  mModule;
207    llvm::StructType *              mKernelStateType;
208    bool                            mHasPrincipalItemCount;
209    const std::string               mKernelName;
210    std::vector<llvm::Value *>      mInitialArguments;
211    Bindings                        mStreamSetInputs;
212    Bindings                        mStreamSetOutputs;
213    Bindings                        mScalarInputs;
214    Bindings                        mScalarOutputs;
215    Bindings                        mInternalScalars;
216};
217
218}
219
220#endif
Note: See TracBrowser for help on using the repository browser.