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

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

Re-enabled segment pipeline parallelism; moved logical segment number into pipeline kernel.

File size: 8.5 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    llvm::Value * getAvailableItemCount(const std::string & name);
28
29    llvm::Value * getAccessibleItemCount(const std::string & name);
30
31    llvm::Value * getProcessedItemCount(const std::string & name) {
32        return getNamedItemCount(name, PROCESSED_ITEM_COUNT_SUFFIX);
33    }
34
35    void setProcessedItemCount(const std::string & name, llvm::Value * value) {
36        setNamedItemCount(name, PROCESSED_ITEM_COUNT_SUFFIX, value);
37    }
38
39    llvm::Value * getProducedItemCount(const std::string & name) {
40        return getNamedItemCount(name, PRODUCED_ITEM_COUNT_SUFFIX);
41    }
42
43    void setProducedItemCount(const std::string & name, llvm::Value * value) {
44        setNamedItemCount(name, PRODUCED_ITEM_COUNT_SUFFIX, value);
45    }
46
47    llvm::Value * getConsumedItemCount(const std::string & name) {
48        return getNamedItemCount(name, CONSUMED_ITEM_COUNT_SUFFIX);
49    }
50
51    void setConsumedItemCount(const std::string & name, llvm::Value * value) {
52        setNamedItemCount(name, CONSUMED_ITEM_COUNT_SUFFIX, value);
53    }
54
55    llvm::Value * getNonDeferredProcessedItemCount(const Binding & input) {
56        return getNamedItemCount(input.getName(), input.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PROCESSED_ITEM_COUNT_SUFFIX);
57    }
58
59    void setNonDeferredProcessedItemCount(const Binding & input, llvm::Value * value) {
60        setNamedItemCount(input.getName(), input.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PROCESSED_ITEM_COUNT_SUFFIX, value);
61    }
62
63    llvm::Value * getNonDeferredProducedItemCount(const Binding & output) {
64        return getNamedItemCount(output.getName(), output.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PRODUCED_ITEM_COUNT_SUFFIX);
65    }
66
67    void setNonDeferredProducedItemCount(const Binding & output, llvm::Value * value) {
68        setNamedItemCount(output.getName(), output.isDeferred() ? NON_DEFERRED_ITEM_COUNT_SUFFIX : PRODUCED_ITEM_COUNT_SUFFIX, value);
69    }
70
71    llvm::Value * getTerminationSignal();
72
73    void setTerminationSignal() { setTerminationSignal(getTrue()); }
74
75    void setTerminationSignal(llvm::Value * const value);
76
77    llvm::Value * getCycleCountPtr();
78
79    // Run-time access of Kernel State and parameters of methods for
80    // use in implementing kernels.
81
82    llvm::Value * getInputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex) {
83        return getInputStreamBlockPtr(name, streamIndex, nullptr);
84    }
85
86    llvm::Value * getInputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset);
87
88    llvm::Value * getInputStreamLogicalBasePtr(const Binding & input);
89
90    llvm::Value * loadInputStreamBlock(const std::string & name, llvm::Value * streamIndex) {
91        return loadInputStreamBlock(name, streamIndex, nullptr);
92    }
93
94    llvm::Value * loadInputStreamBlock(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset);
95
96    llvm::Value * getInputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) {
97        return getInputStreamPackPtr(name, streamIndex, packIndex, nullptr);
98    }
99
100    llvm::Value * getInputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset);
101
102    llvm::Value * loadInputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) {
103        return loadInputStreamPack(name, streamIndex, packIndex, nullptr);
104    }
105
106    llvm::Value * loadInputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset);
107
108    llvm::Value * getInputStreamSetCount(const std::string & name);
109
110    llvm::Value * getOutputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex) {
111        return getOutputStreamBlockPtr(name, streamIndex, nullptr);
112    }
113
114    llvm::Value * getOutputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset);
115
116    llvm::Value * getOutputStreamLogicalBasePtr(const Binding & output);
117
118    llvm::StoreInst * storeOutputStreamBlock(const std::string & name, llvm::Value * streamIndex, llvm::Value * toStore) {
119        return storeOutputStreamBlock(name, streamIndex, nullptr, toStore);
120    }
121
122    llvm::StoreInst * storeOutputStreamBlock(const std::string & name, llvm::Value * streamIndex, llvm::Value * blockOffset, llvm::Value * toStore);
123
124    llvm::Value * getOutputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) {
125        return getOutputStreamPackPtr(name, streamIndex, packIndex, nullptr);
126    }
127
128    llvm::Value * getOutputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset);
129
130    llvm::StoreInst * storeOutputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * toStore) {
131        return storeOutputStreamPack(name, streamIndex, packIndex, nullptr, toStore);
132    }
133
134    llvm::StoreInst * storeOutputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * blockOffset, llvm::Value * toStore);
135
136    llvm::Value * getOutputStreamSetCount(const std::string & name);
137
138    llvm::Value * getRawInputPointer(const std::string & name, llvm::Value * absolutePosition);
139
140    llvm::Value * getRawOutputPointer(const std::string & name, llvm::Value * absolutePosition);
141
142    llvm::Value * getBaseAddress(const std::string & name);
143
144    void setBaseAddress(const std::string & name, llvm::Value * addr);
145
146    llvm::Value * getCapacity(const std::string & name);
147
148    void setCapacity(const std::string & name, llvm::Value * capacity);
149
150    llvm::CallInst * createDoSegmentCall(const std::vector<llvm::Value *> & args);
151
152    const Kernel * getKernel() const {
153        return mKernel;
154    }
155
156    void setKernel(const Kernel * const kernel) {
157        mKernel = kernel;
158    }
159
160    // overloading wrongly subsitutes this for CBuilder function. renamed for now until I can investigate why.
161    llvm::Value * CreateUDiv2(llvm::Value * const number, const ProcessingRate::RateValue & divisor, const llvm::Twine & Name = "");
162
163    llvm::Value * CreateCeilUDiv2(llvm::Value * const number, const ProcessingRate::RateValue & divisor, const llvm::Twine & Name = "");
164
165    llvm::Value * CreateMul2(llvm::Value * const number, const ProcessingRate::RateValue & factor, const llvm::Twine & Name = "");
166
167    llvm::Value * CreateCeilUMul2(llvm::Value * const number, const ProcessingRate::RateValue & factor, const llvm::Twine & Name = "");
168
169    llvm::Type * resolveStreamSetType(llvm::Type * streamSetType);
170
171    unsigned getStride() const {
172        return mStride;
173    }
174
175protected:
176
177    KernelBuilder(llvm::LLVMContext & C, unsigned nativeVectorWidth, unsigned vectorWidth, unsigned laneWidth)
178    : IDISA::IDISA_Builder(C, nativeVectorWidth, vectorWidth, laneWidth)
179    , mStride(vectorWidth)
180    , mKernel(nullptr) {
181
182    }
183
184    const unsigned mStride;
185
186    llvm::Value * getScalarFieldPtr(llvm::Value * handle, llvm::Value * index);
187
188    llvm::Value * getScalarFieldPtr(llvm::Value * instance, const std::string & fieldName);
189
190    llvm::Value * getNamedItemCount(const std::string & name, const std::string & suffix);
191
192    void setNamedItemCount(const std::string & name, const std::string & suffix, llvm::Value * const value);
193
194    std::string getKernelName() const final;
195
196protected:
197    const Kernel * mKernel;
198
199};
200
201template <class SpecifiedArchitectureBuilder>
202class KernelBuilderImpl final : public KernelBuilder, public SpecifiedArchitectureBuilder {
203public:
204    KernelBuilderImpl(llvm::LLVMContext & C, unsigned vectorWidth, unsigned laneWidth)
205    : IDISA::IDISA_Builder(C, SpecifiedArchitectureBuilder::NativeBitBlockWidth, vectorWidth, laneWidth)
206    , KernelBuilder(C, SpecifiedArchitectureBuilder::NativeBitBlockWidth, vectorWidth, laneWidth)
207    , SpecifiedArchitectureBuilder(C, vectorWidth, laneWidth) {
208
209    }
210};
211
212}
213
214#endif // KERNEL_BUILDER_H
Note: See TracBrowser for help on using the repository browser.