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

Last change on this file since 6014 was 6008, checked in by nmedfort, 14 months ago

Removed temporary buffers from pipeline and placed them in the source kernels.

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