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

Last change on this file since 6135 was 6105, checked in by cameron, 9 months ago

NativeBitWidth? for idisa_builders, laneWidth replaces stride

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 * 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
196    unsigned getStride() const {
197        return mStride;
198    }
199
200protected:
201
202    KernelBuilder(llvm::LLVMContext & C, unsigned nativeVectorWidth, unsigned vectorWidth, unsigned laneWidth)
203    : IDISA::IDISA_Builder(C, nativeVectorWidth, vectorWidth, laneWidth)
204    , mStride(vectorWidth)
205    , mKernel(nullptr) {
206
207    }
208   
209    const unsigned mStride;
210
211    llvm::Value * getScalarFieldPtr(llvm::Value * instance, llvm::Value * index);
212
213    llvm::Value * getScalarFieldPtr(llvm::Value * instance, const std::string & fieldName);
214
215    llvm::Value * getNamedItemCount(const std::string & name, const std::string & suffix);
216
217    void setNamedItemCount(const std::string & name, const std::string & suffix, llvm::Value * const value);
218
219protected:
220    const Kernel * mKernel;
221   
222};
223
224template <class SpecifiedArchitectureBuilder>
225class KernelBuilderImpl final : public KernelBuilder, public SpecifiedArchitectureBuilder {
226public:
227    KernelBuilderImpl(llvm::LLVMContext & C, unsigned vectorWidth, unsigned laneWidth)
228    : IDISA::IDISA_Builder(C, SpecifiedArchitectureBuilder::NativeBitBlockWidth, vectorWidth, laneWidth)
229    , KernelBuilder(C, SpecifiedArchitectureBuilder::NativeBitBlockWidth, vectorWidth, laneWidth)
230    , SpecifiedArchitectureBuilder(C, vectorWidth, laneWidth) {
231
232    }
233};
234
235}
236
237#endif // KERNEL_BUILDER_H
Note: See TracBrowser for help on using the repository browser.