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

Last change on this file since 6047 was 6047, checked in by nmedfort, 17 months ago

Major refactoring of buffer types. Static buffers replace Circular and CircularCopyback?. External buffers unify Source/External?.

File size: 9.4 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 * getCapacity(const std::string & name);
158   
159    void setCapacity(const std::string & name, llvm::Value * c);
160   
161    llvm::Value * getAvailableItemCount(const std::string & name);
162
163    llvm::Value * getLinearlyAccessibleItems(const std::string & name, llvm::Value * fromPos, llvm::Value * avail, bool reverse = false);
164
165    llvm::Value * getLinearlyWritableItems(const std::string & name, llvm::Value * fromPos, bool reverse = false);
166
167    llvm::BasicBlock * CreateConsumerWait();
168
169    llvm::Value * getStreamHandle(const std::string & name);
170
171    llvm::CallInst * createDoSegmentCall(const std::vector<llvm::Value *> & args);
172
173    llvm::Value * getAccumulator(const std::string & accumName);
174
175    llvm::Value * getConsumerLock(const std::string & name);
176
177    void setConsumerLock(const std::string & name, llvm::Value * value);
178
179    const Kernel * getKernel() const {
180        return mKernel;
181    }
182
183    void setKernel(const Kernel * const kernel) {
184        mKernel = kernel;
185    }
186
187    // overloading wrongly subsitutes this for CBuilder function. renamed for now until I can investigate why.
188    llvm::Value * CreateUDiv2(llvm::Value * const number, const ProcessingRate::RateValue & divisor, const llvm::Twine & Name = "");
189
190    llvm::Value * CreateCeilUDiv2(llvm::Value * const number, const ProcessingRate::RateValue & divisor, const llvm::Twine & Name = "");
191
192    llvm::Value * CreateMul2(llvm::Value * const number, const ProcessingRate::RateValue & factor, const llvm::Twine & Name = "");
193
194    llvm::Value * CreateCeilUMul2(llvm::Value * const number, const ProcessingRate::RateValue & factor, const llvm::Twine & Name = "");
195
196protected:
197
198    KernelBuilder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride)
199    : IDISA::IDISA_Builder(C, vectorWidth, stride)
200    , mKernel(nullptr) {
201
202    }
203
204    llvm::Value * getScalarFieldPtr(llvm::Value * instance, llvm::Value * index);
205
206    llvm::Value * getScalarFieldPtr(llvm::Value * instance, const std::string & fieldName);
207
208    llvm::Value * getNamedItemCount(const std::string & name, const std::string & suffix);
209
210    void setNamedItemCount(const std::string & name, const std::string & suffix, llvm::Value * const value);
211
212protected:
213    const Kernel * mKernel;
214};
215
216template <class SpecifiedArchitectureBuilder>
217class KernelBuilderImpl final : public KernelBuilder, public SpecifiedArchitectureBuilder {
218public:
219    KernelBuilderImpl(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride)
220    : IDISA::IDISA_Builder(C, vectorWidth, stride)
221    , KernelBuilder(C, vectorWidth, stride)
222    , SpecifiedArchitectureBuilder(C, vectorWidth, stride) {
223
224    }
225};
226
227}
228
229#endif // KERNEL_BUILDER_H
Note: See TracBrowser for help on using the repository browser.