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

Last change on this file since 5340 was 5340, checked in by nmedfort, 3 years ago

Added a simple CreateAssert? function in CBuilder and ReadOnly? flag for getStreamSetBufferPtr method to prevent expanding input stream sets. Begun work on CarryManager? to preallocate variable-length carry data slots.

File size: 6.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, ExpandableBuffer};
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 llvm::Value * getStreamBlockPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
50
51    virtual llvm::Value * getStreamPackPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const;
52   
53    virtual llvm::Value * getStreamSetCount(llvm::Value * self) const;
54
55    llvm::Value * getRawItemPointer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * absolutePosition) const;
56
57    // The number of items that cam be linearly accessed from a given logical stream position.
58    virtual llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const;
59   
60protected:
61
62    StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, llvm::Type * baseType, llvm::Type * resolvedType, unsigned blocks, unsigned AddressSpace);
63
64    // Get the buffer pointer for a given block of the stream.
65    virtual llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const = 0;
66
67protected:
68    const BufferKind                mBufferKind;
69    IDISA::IDISA_Builder * const    iBuilder;
70    llvm::Type * const              mType;
71    const size_t                    mBufferBlocks;
72    const unsigned                  mAddressSpace;
73    llvm::Value *                   mStreamSetBufferPtr;
74    llvm::Type * const              mBaseType;
75};   
76
77class SingleBlockBuffer : public StreamSetBuffer {
78public:
79    static inline bool classof(const StreamSetBuffer * b) {
80        return b->getBufferKind() == BufferKind::BlockBuffer;
81    }   
82
83    SingleBlockBuffer(IDISA::IDISA_Builder * b, llvm::Type * type);
84
85protected:
86    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
87};
88
89class ExternalFileBuffer : public StreamSetBuffer {
90public:
91    static inline bool classof(const StreamSetBuffer * b) {
92        return b->getBufferKind() == BufferKind::ExternalFileBuffer;
93    }
94   
95    ExternalFileBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace = 0);
96
97    void setStreamSetBuffer(llvm::Value * ptr, llvm::Value * fileSize);
98
99    void setEmptyBuffer(llvm::Value * buffer_ptr);
100
101    // Can't allocate - raise an error. */
102    void allocateBuffer() override;
103
104    llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const override;
105   
106protected:
107    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
108};
109   
110class CircularBuffer : public StreamSetBuffer {
111public:
112    static inline bool classof(const StreamSetBuffer * b) {
113        return b->getBufferKind() == BufferKind::CircularBuffer;
114    }
115   
116    CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
117
118protected:
119    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
120};
121   
122
123//
124//  A CircularCopybackBuffer operates as a circular buffer buffer with an overflow area
125//  for temporary use by the kernel that writes to it.   If the kernel uses the overflow
126//  area, it must perform the doCopyBack action before releasing the buffer for use by
127//  subsequent kernels.
128//  Kernels that read from a CircularCopybackBuffer must not access the overflow area.
129//
130class CircularCopybackBuffer : public StreamSetBuffer {
131public:
132    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::CircularCopybackBuffer;}
133   
134    CircularCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace = 0);
135
136    void allocateBuffer() override;
137   
138    // Generate copyback code for the given number of overflowItems.
139    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems) const;
140   
141   
142protected:
143    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
144private:
145    size_t mOverflowBlocks;
146
147};
148
149// ExpandableBuffers do not allow access to the base stream set but will automatically increase the number of streams
150// within their set whenever the index exceeds its capacity
151//
152// ExpandableBuffers do not allow access to the base stream set but will automatically increase the number of streams
153// within their set whenever the index exceeds its capacity
154//
155class ExpandableBuffer : public StreamSetBuffer {
156public:
157    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::ExpandableBuffer;}
158
159    ExpandableBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
160
161    llvm::Value * getStreamBlockPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const override;
162
163    llvm::Value * getStreamPackPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const override;
164
165    llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const override;
166
167    void allocateBuffer() override;
168
169    llvm::Value * getStreamSetCount(llvm::Value * self) const override;
170
171protected:
172
173    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
174
175private:
176
177    bool isGuaranteedCapacity(const llvm::Value * const index) const;
178
179    std::pair<llvm::Value *, llvm::Value *> getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
180
181private:
182
183    const uint64_t  mInitialCapacity;
184
185};
186
187}
188#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.