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

Last change on this file since 5998 was 5998, checked in by nmedfort, 12 months ago

Added temporary buffer functionality to the pipeline for single stream source buffers. Fixed memory leak from UCD::UnicodeBreakRE()

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