source: icGREP/icgrep-devel/icgrep/kernels/streamset.h @ 6186

Last change on this file since 6186 was 6186, checked in by cameron, 5 months ago

Various clean-ups

File size: 11.7 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#ifndef STREAMSET_H
7#define STREAMSET_H
8
9#include <llvm/IR/Type.h>  // for Type
10#include <llvm/IR/DerivedTypes.h>  // for Type
11namespace IDISA { class IDISA_Builder; }
12namespace llvm { class Value; }
13namespace llvm { class Constant; }
14
15namespace kernel {
16
17class Kernel;
18class PipelineKernel;
19class KernelBuilder;
20
21class StreamSetBuffer {
22public:
23
24    enum class BufferKind : unsigned {
25        ExternalBuffer
26        , StaticBuffer
27        , DynamicBuffer
28    };
29   
30    BufferKind getBufferKind() const {
31        return mBufferKind;
32    }
33
34    llvm::Type * getType() const {
35        return mType;
36    }
37   
38    llvm::Type * getBaseType() const {
39        return mBaseType;
40    }
41
42    uint64_t getNumOfStreams() const {
43        uint64_t numStreams = 1;
44        if (mBaseType->isArrayTy()) {
45            numStreams = mBaseType->getArrayNumElements();
46        }
47        return numStreams;
48    }
49   
50    unsigned getAddressSpace() const {
51        return mAddressSpace;
52    }
53
54    llvm::PointerType * getPointerType() const {
55        return getType()->getPointerTo(getAddressSpace());
56    }
57
58    virtual bool hasOverflow() const = 0;
59
60    virtual size_t getOverflowCapacity(const std::unique_ptr<kernel::KernelBuilder> & b) const = 0;
61
62    virtual ~StreamSetBuffer() = 0;
63
64    llvm::Value * getHandle() const {
65        return mHandle;
66    }
67
68    virtual void allocateBuffer(const std::unique_ptr<KernelBuilder> & b) = 0;
69
70    virtual void releaseBuffer(const std::unique_ptr<KernelBuilder> & b) const = 0;
71
72    // The number of items that cam be linearly accessed from a given logical stream position.
73    virtual llvm::Value * getLinearlyAccessibleItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * fromPosition, llvm::Value * totalItems, const unsigned overflowSize = 0) const = 0;
74
75    virtual llvm::Value * getLinearlyWritableItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * fromPosition, llvm::Value * consumedItems, const unsigned overflowSize = 0) const = 0;
76
77    virtual llvm::Type * getHandleType(const std::unique_ptr<kernel::KernelBuilder> & b) const = 0;
78
79    llvm::PointerType * getHandlePointerType(const std::unique_ptr<kernel::KernelBuilder> & b) const {
80        return getHandleType(b)->getPointerTo(getAddressSpace());
81    }
82
83    virtual llvm::Value * getStreamBlockPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex) const;
84
85    virtual llvm::Value * getStreamPackPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex) const;
86
87    virtual llvm::Value * getStreamSetCount(IDISA::IDISA_Builder * const b) const;
88
89    virtual llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b) const = 0;
90
91    virtual void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * addr) const = 0;
92
93    virtual llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b) const = 0;
94
95    virtual void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * size) const = 0;
96   
97    virtual llvm::Value * getCapacity(IDISA::IDISA_Builder * const b) const = 0;
98
99    virtual llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * absolutePosition) const = 0;
100
101    virtual llvm::Value * getStreamLogicalBasePtr(IDISA::IDISA_Builder * const b, llvm::Value * const streamIndex, llvm::Value * blockIndex) const = 0;
102
103    void setHandle(const std::unique_ptr<KernelBuilder> & b, llvm::Value * const handle);
104
105protected:
106
107    llvm::Value * getHandle(IDISA::IDISA_Builder * const b) const;
108
109    StreamSetBuffer(const BufferKind k, const std::unique_ptr<KernelBuilder> & b, llvm::Type * baseType, unsigned AddressSpace);
110
111private:
112
113    void assertValidStreamIndex(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex) const;
114
115protected:
116
117    const BufferKind                mBufferKind;
118    // Each StreamSetBuffer object is local to the Kernel (or pipeline) object at (pre-JIT) "compile time" but
119    // by sharing the same handle will refer to the same stream set at (post-JIT) run time.
120    llvm::Value *                   mHandle;
121    llvm::Type * const              mType;
122    const unsigned                  mAddressSpace;
123    llvm::Type * const              mBaseType;
124};   
125
126class ExternalBuffer final : public StreamSetBuffer {
127public:
128    static inline bool classof(const StreamSetBuffer * b) {
129        return b->getBufferKind() == BufferKind::ExternalBuffer;
130    }
131
132    enum Field {BaseAddress, Capacity};
133
134    ExternalBuffer(const std::unique_ptr<KernelBuilder> & b, llvm::Type * const type, const unsigned AddressSpace = 0);
135
136    void allocateBuffer(const std::unique_ptr<KernelBuilder> & b) override;
137
138    void releaseBuffer(const std::unique_ptr<KernelBuilder> & b) const override;
139
140    llvm::Value * getStreamBlockPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex) const override;
141
142    llvm::Value * getStreamPackPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex) const override;
143
144    llvm::Value * getStreamLogicalBasePtr(IDISA::IDISA_Builder * const b, llvm::Value * const streamIndex, llvm::Value * blockIndex) const override;
145
146    llvm::Value * getLinearlyAccessibleItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * fromPosition, llvm::Value * totalItems, const unsigned overflowSize = 0) const override;
147
148    llvm::Value * getLinearlyWritableItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * fromPosition, llvm::Value * consumedItems, const unsigned overflowSize = 0) const override;
149
150    llvm::Type * getHandleType(const std::unique_ptr<kernel::KernelBuilder> & b) const override;
151
152    llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b) const override;
153
154    void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * capacity) const override;
155
156    llvm::Value * getCapacity(IDISA::IDISA_Builder * const b) const override;
157
158    void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * addr) const override;
159
160    virtual bool hasOverflow() const override {
161        return false;
162    }
163
164    virtual size_t getOverflowCapacity(const std::unique_ptr<kernel::KernelBuilder> & b) const override;
165
166    llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b) const override;
167
168    llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * absolutePosition) const override;
169
170private:
171
172    void assertValidBlockIndex(IDISA::IDISA_Builder * const b, llvm::Value * blockIndex) const;
173
174};
175
176class StaticBuffer final : public StreamSetBuffer {
177public:
178    static inline bool classof(const StreamSetBuffer * b) {
179        return b->getBufferKind() == BufferKind::StaticBuffer;
180    }
181   
182    StaticBuffer(const std::unique_ptr<KernelBuilder> & b, llvm::Type * const type,
183                 const size_t capacity, const size_t overflowBlocks = 0, const unsigned AddressSpace = 0);
184
185    void allocateBuffer(const std::unique_ptr<KernelBuilder> & b) override;
186
187    void releaseBuffer(const std::unique_ptr<KernelBuilder> & b) const override;
188
189    llvm::Value * getLinearlyAccessibleItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * fromPosition, llvm::Value * const totalItems, const unsigned overflowSize = 0) const override;
190
191    llvm::Value * getLinearlyWritableItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * const fromPosition, llvm::Value * const consumedItems, const unsigned overflowSize = 0) const override;
192
193    bool hasOverflow() const override {
194        return mOverflow > 0;
195    }
196
197    size_t getOverflowCapacity(const std::unique_ptr<kernel::KernelBuilder> & b) const override;
198
199    llvm::Type * getHandleType(const std::unique_ptr<kernel::KernelBuilder> & b) const override;
200
201    llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b) const override;
202
203    void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * addr) const override;
204
205    llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b) const override;
206
207    llvm::Value * getCapacity(IDISA::IDISA_Builder * const b) const override;
208
209    void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * capacity) const override;
210
211    llvm::Value * getStreamBlockPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex) const override;
212
213    llvm::Value * getStreamPackPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex) const override;
214
215    llvm::Value * getStreamLogicalBasePtr(IDISA::IDISA_Builder * const b, llvm::Value * const streamIndex, llvm::Value * blockIndex) const override;
216
217    llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * absolutePosition) const override;
218
219private:
220
221    llvm::Value * modByCapacity(IDISA::IDISA_Builder * const b, llvm::Value * const offset) const;
222
223private:
224
225    const size_t    mCapacity;
226    const size_t    mOverflow;
227
228};
229       
230class DynamicBuffer final : public StreamSetBuffer {
231
232    friend class KernelBuilder;
233
234    enum Field {BaseAddress, PriorBaseAddress, Capacity};
235
236public:
237    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::DynamicBuffer;}
238   
239    DynamicBuffer(const std::unique_ptr<KernelBuilder> & b, llvm::Type * type, size_t initialCapacity, size_t overflowSize = 0, unsigned AddressSpace = 0);
240
241    void allocateBuffer(const std::unique_ptr<KernelBuilder> & b) override;
242
243    void releaseBuffer(const std::unique_ptr<KernelBuilder> & b) const override;
244
245    // void expandBuffer(const std::unique_ptr<KernelBuilder> & b, llvm::Value * consumed, llvm::Value * produced, llvm::Value * required) const;
246
247    llvm::Value * getLinearlyAccessibleItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * fromPosition, llvm::Value * totalItems, const unsigned overflowSize = 0) const override;
248
249    llvm::Value * getLinearlyWritableItems(const std::unique_ptr<KernelBuilder> & b, llvm::Value * fromPosition, llvm::Value * consumedItems, const unsigned overflowSize = 0) const override;
250   
251    bool hasOverflow() const override {
252        return mOverflow > 0;
253    }
254
255    size_t getOverflowCapacity(const std::unique_ptr<kernel::KernelBuilder> & b) const override;
256
257protected:
258
259    llvm::Type * getHandleType(const std::unique_ptr<kernel::KernelBuilder> & b) const override;
260
261    llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b) const override;
262
263    void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * addr) const override;
264
265    llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b) const override;
266   
267    llvm::Value * getCapacity(IDISA::IDISA_Builder * const b) const override;
268   
269    void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * capacity) const override;
270
271    llvm::Value * getStreamBlockPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex) const override;
272
273    llvm::Value * getStreamPackPtr(IDISA::IDISA_Builder * const b, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex) const override;
274
275    llvm::Value * getStreamLogicalBasePtr(IDISA::IDISA_Builder * const b, llvm::Value * const streamIndex, llvm::Value * blockIndex) const override;
276
277    llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * absolutePosition) const override;
278
279private:
280
281    llvm::Value * getAllocationSize(IDISA::IDISA_Builder * const b, llvm::Value * const requiredItemCapacity, const size_t overflowSize) const;
282
283    llvm::Value * modByCapacity(IDISA::IDISA_Builder * const b, llvm::Value * const offset) const;
284
285private:
286
287    const size_t    mInitialCapacity;
288    const size_t    mOverflow;
289
290};
291
292using StreamSetBuffers = std::vector<StreamSetBuffer *>;
293using OwnedStreamSetBuffers = std::vector<std::unique_ptr<StreamSetBuffer>>;
294
295}
296#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.