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

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

Circular copy-back buffers: initial check-in

File size: 6.0 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 PointerType; }
12namespace llvm { class Value; }
13namespace kernel { class KernelBuilder; }
14
15namespace parabix {
16   
17class StreamSetBuffer {
18    friend class kernel::KernelBuilder;
19
20public:
21
22    enum class BufferKind : unsigned {BlockBuffer, ExternalFileBuffer, CircularBuffer, CircularCopybackBuffer, ExpandableBuffer};
23
24    BufferKind getBufferKind() const {
25        return mBufferKind;
26    }
27
28    llvm::Type * getType() const {
29        return mStreamSetType;
30    }
31
32    llvm::Type * getBaseType() const {
33        return mBaseStreamSetType;
34    }
35
36    llvm::PointerType * getPointerType() const {
37        return getType()->getPointerTo(mAddressSpace);
38    }
39
40    size_t getBufferBlocks() const {
41        return mBufferBlocks;
42    }
43
44    llvm::Value * getStreamSetBasePtr() const {
45        return mStreamSetBufferPtr;
46    }
47
48    virtual void allocateBuffer();
49
50    virtual llvm::Value * getStream(llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const;
51
52    virtual llvm::Value * getStream(llvm::Value * self, llvm::Value * blockNo, llvm::Value * index1, llvm::Value * index2) const;
53   
54    virtual llvm::Value * getStreamView(llvm::Type * type, llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const;
55
56    // The number of items that cam be linearly accessed from a given logical stream position.
57    virtual llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const;
58   
59protected:
60
61    StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, llvm::Type * type, unsigned blocks, unsigned AddressSpace);
62
63    // Get the buffer pointer for a given block of the stream.
64    virtual llvm::Value * getStreamSetPtr(llvm::Value * self, llvm::Value * blockNo) const = 0;
65
66    llvm::Type * resolveStreamSetBufferType(llvm::Type * type) const;
67
68protected:
69    const BufferKind                mBufferKind;
70    IDISA::IDISA_Builder * const    iBuilder;
71    llvm::Type * const              mStreamSetType;
72    const size_t                    mBufferBlocks;
73    const unsigned                  mAddressSpace;
74    llvm::Value *                   mStreamSetBufferPtr;
75    llvm::Type * const              mBaseStreamSetType;
76};   
77
78class SingleBlockBuffer : public StreamSetBuffer {
79public:
80    static inline bool classof(const StreamSetBuffer * b) {
81        return b->getBufferKind() == BufferKind::BlockBuffer;
82    }   
83
84    SingleBlockBuffer(IDISA::IDISA_Builder * b, llvm::Type * type);
85
86protected:
87    llvm::Value * getStreamSetPtr(llvm::Value * self, llvm::Value * blockNo) const override;
88};
89
90class ExternalFileBuffer : public StreamSetBuffer {
91public:
92    static inline bool classof(const StreamSetBuffer * b) {
93        return b->getBufferKind() == BufferKind::ExternalFileBuffer;
94    }
95   
96    ExternalFileBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace = 0);
97
98    void setStreamSetBuffer(llvm::Value * ptr, llvm::Value * fileSize);
99
100    void setEmptyBuffer(llvm::Value * buffer_ptr);
101
102    // Can't allocate - raise an error. */
103    void allocateBuffer() override;
104
105    llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const override;
106   
107protected:
108    llvm::Value * getStreamSetPtr(llvm::Value * self, llvm::Value * blockNo) const override;
109};
110   
111class CircularBuffer : public StreamSetBuffer {
112public:
113    static inline bool classof(const StreamSetBuffer * b) {
114        return b->getBufferKind() == BufferKind::CircularBuffer;
115    }
116   
117    CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
118
119protected:
120    llvm::Value * getStreamSetPtr(llvm::Value * bufferBasePtr, llvm::Value * blockNo) const override;
121};
122   
123
124//
125//  A CircularCopybackBuffer operates as a circular buffer buffer with an overflow area
126//  for temporary use by the kernel that writes to it.   If the kernel uses the overflow
127//  area, it must perform the doCopyBack action before releasing the buffer for use by
128//  subsequent kernels.
129//  Kernels that read from a CircularCopybackBuffer must not access the overflow area.
130//
131class CircularCopybackBuffer : public StreamSetBuffer {
132public:
133    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::CircularCopybackBuffer;}
134   
135    CircularCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace = 0);
136
137    void allocateBuffer() override;
138   
139    // Generate copyback code for the given number of overflowItems.
140    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems);
141   
142   
143protected:
144    llvm::Value * getStreamSetPtr(llvm::Value * bufferBasePtr, llvm::Value * blockNo) const override;
145private:
146    size_t mOverflowBlocks;
147
148};
149
150// ExpandableBuffers do not allow access to the base stream set but will automatically increase the number of streams
151// within their set whenever the index exceeds its capacity
152//
153class ExpandableBuffer : public StreamSetBuffer {
154public:
155    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::ExpandableBuffer;}
156
157    ExpandableBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
158
159    llvm::Value * getStream(llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const override;
160
161    llvm::Value * getStream(llvm::Value * self, llvm::Value * blockNo, llvm::Value * index1, llvm::Value * index2) const override;
162
163    llvm::Value * getStreamView(llvm::Type * type, llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const override;
164
165    llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const override;
166   
167protected:
168
169    llvm::Value * getStreamSetPtr(llvm::Value * self, llvm::Value * blockNo) const override;
170};
171
172}
173#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.