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

Last change on this file since 5395 was 5395, checked in by cameron, 2 years ago

Uniquify kernel names with buffer types/sizes; update u8u16 to use ParabixDriver?

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