source: icGREP/icgrep-devel/icgrep/kernels/kernel_builder.h @ 6233

Last change on this file since 6233 was 6233, checked in by nmedfort, 4 months ago

Moved termination signals into pipeline kernel

File size: 9.2 KB
Line 
1#ifndef KERNEL_BUILDER_H
2#define KERNEL_BUILDER_H
3
4#include <IR_Gen/idisa_builder.h>
5#include <kernels/kernel.h>
6
7namespace kernel {
8
9class Kernel;
10
11class KernelBuilder : public virtual IDISA::IDISA_Builder {
12    friend class Kernel;
13    friend class MultiBlockKernel;
14    friend class PipelineGenerator;
15public:
16
17    // Get the value of a scalar field for the current instance.
18    llvm::Value * getScalarFieldPtr(llvm::Value * index);
19
20    llvm::Value * getScalarFieldPtr(const std::string & fieldName);
21
22    llvm::Value * getScalarField(const std::string & fieldName);
23
24    // Set the value of a scalar field for the current instance.
25    void setScalarField(const std::string & fieldName, llvm::Value * value);
26
27    // Synchronization actions for executing a kernel for a particular logical segment.
28    //
29    // Before the segment is processed, acquireLogicalSegmentNo must be used to load
30    // the segment number of the kernel state to ensure that the previous segment is
31    // complete (by checking that the acquired segment number is equal to the desired segment
32    // number).
33    // After all segment processing actions for the kernel are complete, and any necessary
34    // data has been extracted from the kernel for further pipeline processing, the
35    // segment number must be incremented and stored using releaseLogicalSegmentNo.
36    llvm::LoadInst * acquireLogicalSegmentNo();
37
38    void releaseLogicalSegmentNo(llvm::Value * const nextSegNo);
39
40    llvm::Value * getAvailableItemCount(const std::string & name);
41
42    llvm::Value * getAccessibleItemCount(const std::string & name);
43
44    llvm::Value * getProcessedItemCount(const std::string & name) {
45        return getNamedItemCount(name, PROCESSED_ITEM_COUNT_SUFFIX);
46    }
47
48    void setProcessedItemCount(const std::string & name, llvm::Value * value) {
49        setNamedItemCount(name, PROCESSED_ITEM_COUNT_SUFFIX, value);
50    }
51
52    llvm::Value * getProducedItemCount(const std::string & name) {
53        return getNamedItemCount(name, PRODUCED_ITEM_COUNT_SUFFIX);
54    }
55
56    void setProducedItemCount(const std::string & name, llvm::Value * value) {
57        setNamedItemCount(name, PRODUCED_ITEM_COUNT_SUFFIX, value);
58    }
59
60    llvm::Value * getConsumedItemCount(const std::string & name) {
61        return getNamedItemCount(name, CONSUMED_ITEM_COUNT_SUFFIX);
62    }
63
64    void setConsumedItemCount(const std::string & name, llvm::Value * value) {
65        setNamedItemCount(name, CONSUMED_ITEM_COUNT_SUFFIX, value);
66    }
67
68    llvm::Value * getNonDeferredProcessedItemCount(const Binding & input) {
69        return getNamedItemCount(input.getName(), input.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PROCESSED_ITEM_COUNT_SUFFIX);
70    }
71
72    void setNonDeferredProcessedItemCount(const Binding & input, llvm::Value * value) {
73        setNamedItemCount(input.getName(), input.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PROCESSED_ITEM_COUNT_SUFFIX, value);
74    }
75
76    llvm::Value * getNonDeferredProducedItemCount(const Binding & output) {
77        return getNamedItemCount(output.getName(), output.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PRODUCED_ITEM_COUNT_SUFFIX);
78    }
79
80    void setNonDeferredProducedItemCount(const Binding & output, llvm::Value * value) {
81        setNamedItemCount(output.getName(), output.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PRODUCED_ITEM_COUNT_SUFFIX, value);
82    }
83
84    llvm::Value * getTerminationSignal();
85
86    void setTerminationSignal() { setTerminationSignal(getTrue()); }
87
88    void setTerminationSignal(llvm::Value * const value);
89
90    llvm::Value * getCycleCountPtr();
91
92    // Run-time access of Kernel State and parameters of methods for
93    // use in implementing kernels.
94
95    llvm::Value * getInputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex) {
96        return getInputStreamBlockPtr(name, streamIndex, nullptr);
97    }
98
99    llvm::Value * getInputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset);
100
101    llvm::Value * getInputStreamLogicalBasePtr(const Binding & input);
102
103    llvm::Value * loadInputStreamBlock(const std::string & name, llvm::Value * streamIndex) {
104        return loadInputStreamBlock(name, streamIndex, nullptr);
105    }
106
107    llvm::Value * loadInputStreamBlock(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset);
108
109    llvm::Value * getInputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) {
110        return getInputStreamPackPtr(name, streamIndex, packIndex, nullptr);
111    }
112
113    llvm::Value * getInputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset);
114
115    llvm::Value * loadInputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) {
116        return loadInputStreamPack(name, streamIndex, packIndex, nullptr);
117    }
118
119    llvm::Value * loadInputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset);
120
121    llvm::Value * getInputStreamSetCount(const std::string & name);
122
123    llvm::Value * getOutputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex) {
124        return getOutputStreamBlockPtr(name, streamIndex, nullptr);
125    }
126
127    llvm::Value * getOutputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset);
128
129    llvm::Value * getOutputStreamLogicalBasePtr(const Binding & output);
130
131    llvm::StoreInst * storeOutputStreamBlock(const std::string & name, llvm::Value * streamIndex, llvm::Value * toStore) {
132        return storeOutputStreamBlock(name, streamIndex, nullptr, toStore);
133    }
134
135    llvm::StoreInst * storeOutputStreamBlock(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset, llvm::Value * toStore);
136
137    llvm::Value * getOutputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) {
138        return getOutputStreamPackPtr(name, streamIndex, packIndex, nullptr);
139    }
140
141    llvm::Value * getOutputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset);
142
143    llvm::StoreInst * storeOutputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * toStore) {
144        return storeOutputStreamPack(name, streamIndex, packIndex, nullptr, toStore);
145    }
146
147    llvm::StoreInst * storeOutputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset, llvm::Value * toStore);
148
149    llvm::Value * getOutputStreamSetCount(const std::string & name);
150
151    llvm::Value * getRawInputPointer(const std::string & name, llvm::Value * absolutePosition);
152
153    llvm::Value * getRawOutputPointer(const std::string & name, llvm::Value * absolutePosition);
154
155    llvm::Value * getBaseAddress(const std::string & name);
156
157    void setBaseAddress(const std::string & name, llvm::Value * addr);
158
159    llvm::Value * getCapacity(const std::string & name);
160
161    void setCapacity(const std::string & name, llvm::Value * capacity);
162
163    llvm::CallInst * createDoSegmentCall(const std::vector<llvm::Value *> & args);
164
165    const Kernel * getKernel() const {
166        return mKernel;
167    }
168
169    void setKernel(const Kernel * const kernel) {
170        mKernel = kernel;
171    }
172
173    // overloading wrongly subsitutes this for CBuilder function. renamed for now until I can investigate why.
174    llvm::Value * CreateUDiv2(llvm::Value * const number, const ProcessingRate::RateValue & divisor, const llvm::Twine & Name = "");
175
176    llvm::Value * CreateCeilUDiv2(llvm::Value * const number, const ProcessingRate::RateValue & divisor, const llvm::Twine & Name = "");
177
178    llvm::Value * CreateMul2(llvm::Value * const number, const ProcessingRate::RateValue & factor, const llvm::Twine & Name = "");
179
180    llvm::Value * CreateCeilUMul2(llvm::Value * const number, const ProcessingRate::RateValue & factor, const llvm::Twine & Name = "");
181
182    llvm::Type * resolveStreamSetType(llvm::Type * streamSetType);
183
184    unsigned getStride() const {
185        return mStride;
186    }
187
188protected:
189
190    KernelBuilder(llvm::LLVMContext & C, unsigned nativeVectorWidth, unsigned vectorWidth, unsigned laneWidth)
191    : IDISA::IDISA_Builder(C, nativeVectorWidth, vectorWidth, laneWidth)
192    , mStride(vectorWidth)
193    , mKernel(nullptr) {
194
195    }
196
197    const unsigned mStride;
198
199    llvm::Value * getScalarFieldPtr(llvm::Value * handle, llvm::Value * index);
200
201    llvm::Value * getScalarFieldPtr(llvm::Value * instance, const std::string & fieldName);
202
203    llvm::Value * getNamedItemCount(const std::string & name, const std::string & suffix);
204
205    void setNamedItemCount(const std::string & name, const std::string & suffix, llvm::Value * const value);
206
207    std::string getKernelName() const final;
208
209protected:
210    const Kernel * mKernel;
211
212};
213
214template <class SpecifiedArchitectureBuilder>
215class KernelBuilderImpl final : public KernelBuilder, public SpecifiedArchitectureBuilder {
216public:
217    KernelBuilderImpl(llvm::LLVMContext & C, unsigned vectorWidth, unsigned laneWidth)
218    : IDISA::IDISA_Builder(C, SpecifiedArchitectureBuilder::NativeBitBlockWidth, vectorWidth, laneWidth)
219    , KernelBuilder(C, SpecifiedArchitectureBuilder::NativeBitBlockWidth, vectorWidth, laneWidth)
220    , SpecifiedArchitectureBuilder(C, vectorWidth, laneWidth) {
221
222    }
223};
224
225}
226
227#endif // KERNEL_BUILDER_H
Note: See TracBrowser for help on using the repository browser.