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

Last change on this file since 5389 was 5389, checked in by nmedfort, 2 years ago

Investigating jenkins issue.

File size: 8.5 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
10namespace IDISA { class IDISA_Builder; }
11namespace llvm { class Value; }
12namespace kernel { class KernelBuilder; }
13
14namespace parabix {
15   
16class StreamSetBuffer {
17    friend class kernel::KernelBuilder;
18
19public:
20
21    enum class BufferKind : unsigned {BlockBuffer, ExternalFileBuffer, CircularBuffer, CircularCopybackBuffer, SwizzledCopybackBuffer, ExpandableBuffer, ExtensibleBuffer};
22
23    BufferKind getBufferKind() const {
24        return mBufferKind;
25    }
26
27    llvm::Type * getType() const {
28        return mType;
29    }
30
31    llvm::Type * getBaseType() const {
32        return mBaseType;
33    }
34
35    llvm::PointerType * getPointerType() const {
36        return getType()->getPointerTo(mAddressSpace);
37    }
38
39    size_t getBufferBlocks() const {
40        return mBufferBlocks;
41    }
42
43    llvm::Value * getStreamSetBasePtr() const {
44        return mStreamSetBufferPtr;
45    }
46
47    virtual void allocateBuffer();
48
49    virtual void releaseBuffer(llvm::Value * self);
50
51    virtual llvm::Value * getStreamBlockPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
52
53    virtual llvm::Value * getStreamPackPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const;
54   
55    virtual llvm::Value * getStreamSetCount(llvm::Value * self) const;
56
57    llvm::Value * getRawItemPointer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * absolutePosition) const;
58
59    // The number of items that cam be linearly accessed from a given logical stream position.
60    virtual llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const;
61    virtual llvm::Value * getLinearlyAccessibleBlocks(llvm::Value * self, llvm::Value * fromBlock) const;
62
63    virtual void reserveBytes(llvm::Value * self, llvm::Value * requested) const;
64
65    virtual ~StreamSetBuffer() = 0;
66
67protected:
68
69    StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, llvm::Type * baseType, llvm::Type * resolvedType, unsigned blocks, unsigned AddressSpace);
70
71    // Get the buffer pointer for a given block of the stream.
72    virtual llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const = 0;
73
74    bool isCapacityGuaranteed(const llvm::Value * const index, const size_t capacity) const;
75
76    llvm::Value * modByBufferBlocks(llvm::Value * const offset) const;
77
78    virtual llvm::Value * getBaseAddress(llvm::Value * self) const;
79
80protected:
81    const BufferKind                mBufferKind;
82    IDISA::IDISA_Builder * const    iBuilder;
83    llvm::Type * const              mType;
84    const size_t                    mBufferBlocks;
85    const unsigned                  mAddressSpace;
86    llvm::Value *                   mStreamSetBufferPtr;
87    llvm::Type * const              mBaseType;
88};   
89
90class SingleBlockBuffer final : public StreamSetBuffer {
91public:
92    static inline bool classof(const StreamSetBuffer * b) {
93        return b->getBufferKind() == BufferKind::BlockBuffer;
94    }   
95
96    SingleBlockBuffer(IDISA::IDISA_Builder * b, llvm::Type * type);
97
98protected:
99    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
100};
101
102class ExternalFileBuffer final : public StreamSetBuffer {
103public:
104    static inline bool classof(const StreamSetBuffer * b) {
105        return b->getBufferKind() == BufferKind::ExternalFileBuffer;
106    }
107   
108    ExternalFileBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace = 0);
109
110    void setStreamSetBuffer(llvm::Value * ptr);
111
112    // Can't allocate - raise an error. */
113    void allocateBuffer() override;
114
115    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
116   
117protected:
118    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
119};
120
121class ExtensibleBuffer final : public StreamSetBuffer {
122public:
123    static inline bool classof(const StreamSetBuffer * b) {
124        return b->getBufferKind() == BufferKind::ExtensibleBuffer;
125    }
126
127    ExtensibleBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
128
129    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self,llvm::Value * fromPosition) const override;
130
131    void allocateBuffer() override;
132
133    void reserveBytes(llvm::Value * self, llvm::Value * required) const override;
134
135    void releaseBuffer(llvm::Value * self) override;
136
137protected:
138
139    llvm::Value * getBaseAddress(llvm::Value * self) const override;
140
141    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
142
143};
144   
145class CircularBuffer final : public StreamSetBuffer {
146public:
147    static inline bool classof(const StreamSetBuffer * b) {
148        return b->getBufferKind() == BufferKind::CircularBuffer;
149    }
150   
151    CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
152
153protected:
154    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
155};
156   
157
158//
159//  A CircularCopybackBuffer operates as a circular buffer buffer with an overflow area
160//  for temporary use by the kernel that writes to it.   If the kernel uses the overflow
161//  area, it must perform the doCopyBack action before releasing the buffer for use by
162//  subsequent kernels.
163//  Kernels that read from a CircularCopybackBuffer must not access the overflow area.
164//
165class CircularCopybackBuffer final : public StreamSetBuffer {
166public:
167    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::CircularCopybackBuffer;}
168   
169    CircularCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace = 0);
170
171    void allocateBuffer() override;
172   
173    // Generate copyback code for the given number of overflowItems.
174    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems) const;
175       
176protected:
177    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
178private:
179    size_t mOverflowBlocks;
180
181};
182   
183class SwizzledCopybackBuffer final : public StreamSetBuffer {
184public:
185    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::SwizzledCopybackBuffer;}
186   
187    SwizzledCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned fieldwidth = 64, unsigned AddressSpace = 0);
188   
189    void allocateBuffer() override;
190   
191    // Generate copyback code for the given number of overflowItems.
192    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems) const;
193protected:
194    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
195private:
196    size_t mOverflowBlocks;
197    unsigned mFieldWidth;
198   
199};
200
201// ExpandableBuffers do not allow access to the base stream set but will automatically increase the number of streams
202// within their set whenever the index exceeds its capacity
203//
204class ExpandableBuffer final : public StreamSetBuffer {
205public:
206    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::ExpandableBuffer;}
207
208    ExpandableBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
209
210    llvm::Value * getStreamBlockPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const override;
211
212    llvm::Value * getStreamPackPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const override;
213
214    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
215
216    void allocateBuffer() override;
217
218    llvm::Value * getStreamSetCount(llvm::Value * self) const override;
219
220    void releaseBuffer(llvm::Value * self) override;
221
222protected:
223
224    llvm::Value * getBaseAddress(llvm::Value * self) const override;
225
226    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
227
228private:
229
230    std::pair<llvm::Value *, llvm::Value *> getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
231
232private:
233
234    const uint64_t  mInitialCapacity;
235
236};
237
238}
239#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.