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

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

Code clean up to enforce proper calling order of KernelBuilder? methods

File size: 6.2 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 <string>
10#include <vector>
11#include <IR_Gen/idisa_builder.h>
12#include <llvm/IR/Type.h>
13
14namespace parabix {
15   
16enum FieldType {i1 = 1, i2 = 2, i4 = 4, i8 = 8, i16 = 16, i32 = 32, i64 = 64, i128 = 128, i256 = 256};
17
18// Stream Set Structs hold information about the current state of a stream set buffer.
19
20llvm::Value * getProducerPosPtr(IDISA::IDISA_Builder * b, Value * bufferStructPtr);
21llvm::Value * getConsumerPosPtr(IDISA::IDISA_Builder * b, Value * bufferStructPtr);
22llvm::Value * getEndOfInputPtr(IDISA::IDISA_Builder * b, Value * bufferStructPtr);
23llvm::Value * getStreamSetBufferPtr(IDISA::IDISA_Builder * b, Value * bufferStructPtr);
24
25class StreamSetBuffer {
26public:
27
28    enum class BufferKind : unsigned {BlockBuffer, ExternalFileBuffer, CircularBuffer, LinearCopybackBuffer};
29
30    inline BufferKind getBufferKind() const {
31        return mBufferKind;
32    }
33
34    inline llvm::Type * getBufferStreamSetType() const {
35        return mStreamSetType;
36    }
37
38    llvm::PointerType * getStreamBufferPointerType() const {
39        return mStreamSetType->getPointerTo(mAddrSpace);
40    }
41
42    llvm::PointerType * getStreamSetStructPointerType() const {
43        return mStreamSetStructType->getPointerTo();
44    }
45
46    size_t getBufferSize() const { return mBufferBlocks; }
47       
48    llvm::Value * getStreamSetBasePtr() const { return mStreamSetBufferPtr; }
49   
50    llvm::Value * getStreamSetStructPtr() const { return mStreamSetStructPtr; }
51
52    virtual void allocateBuffer();
53
54    // Get the buffer pointer for a given block of the stream.
55    virtual llvm::Value * getStreamSetBlockPointer(llvm::Value * bufferStructPtr, llvm::Value * blockNo) = 0;
56   
57    llvm::Value * getProducerPosPtr(Value * bufferStructPtr);
58
59    void setProducerPos(Value * bufferStructPtr, Value * pos);
60
61    llvm::Value * getConsumerPosPtr(Value * bufferStructPtr);
62
63    virtual void setConsumerPos(Value * bufferStructPtr, Value * pos);
64
65    llvm::Value * getEndOfInputPtr(Value * bufferStructPtr);
66
67    void setEndOfInput(Value * bufferStructPtr);
68   
69    llvm::Type * resolveStreamTypes(llvm::Type * type) {
70        if (auto ty = dyn_cast<ArrayType>(type)) {
71            unsigned numElems = ty->getNumElements();
72            auto elemTy = ty->getElementType();
73            if (isa<IDISA::StreamType>(elemTy)) {
74                return ArrayType::get(cast<IDISA::StreamType>(elemTy)->resolveType(iBuilder), numElems);
75            }
76        }
77        else if (auto ty = dyn_cast<IDISA::StreamType>(type)) {
78            return ty->resolveType(iBuilder);
79        }
80        return type;
81    }
82   
83protected:
84    StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, llvm::Type * type, unsigned blocks, unsigned AddressSpace = 0)
85    : mBufferKind(k)
86    , iBuilder(b)
87    , mStreamSetType(resolveStreamTypes(type))
88    , mBufferBlocks(blocks)
89    , mAddrSpace(AddressSpace)
90    , mStreamSetBufferPtr(nullptr)
91    , mStreamSetStructPtr(nullptr)
92    , mStreamSetStructType(StructType::get(b->getContext(),
93                            {{b->getSizeTy(),
94                              b->getSizeTy(),
95                              b->getInt1Ty(),
96                              PointerType::get(mStreamSetType, AddressSpace)}})) {
97
98    }
99protected:
100    const BufferKind        mBufferKind;
101    IDISA::IDISA_Builder *  iBuilder;
102    llvm::Type * const      mStreamSetType;
103    size_t                  mBufferBlocks;
104    int                     mAddrSpace;
105    llvm::Value *           mStreamSetBufferPtr;
106    llvm::Value *           mStreamSetStructPtr;
107    llvm::Type * const      mStreamSetStructType;
108};   
109
110class SingleBlockBuffer : public StreamSetBuffer {
111public:
112    static inline bool classof(const StreamSetBuffer * b) {
113        return b->getBufferKind() == BufferKind::BlockBuffer;
114    }   
115    SingleBlockBuffer(IDISA::IDISA_Builder * b, llvm::Type * type)
116    : StreamSetBuffer(BufferKind::BlockBuffer, b, type, 1, 0) {
117
118    }
119    llvm::Value * getStreamSetBlockPointer(llvm::Value * bufferBasePtr, llvm::Value * blockNo) override;
120};
121
122class ExternalFileBuffer : public StreamSetBuffer {
123public:
124    static inline bool classof(const StreamSetBuffer * b) {
125        return b->getBufferKind() == BufferKind::ExternalFileBuffer;
126    }
127   
128    ExternalFileBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace = 0)
129    : StreamSetBuffer(BufferKind::ExternalFileBuffer, b, type, 0, AddressSpace) {
130
131    }
132
133    void setStreamSetBuffer(llvm::Value * ptr, llvm::Value * fileSize);
134    void setEmptyBuffer(llvm::Value * buffer_ptr);
135
136    // Can't allocate - raise an error. */
137    void allocateBuffer() override;
138
139    llvm::Value * getStreamSetBlockPointer(llvm::Value * bufferStructPtr, llvm::Value * blockNo) override;
140};
141   
142class CircularBuffer : public StreamSetBuffer {
143public:
144    static inline bool classof(const StreamSetBuffer * b) {
145        return b->getBufferKind() == BufferKind::CircularBuffer;
146    }
147 
148    CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0)
149    : StreamSetBuffer(BufferKind::CircularBuffer, b, type, bufferBlocks, AddressSpace) {
150
151    }
152
153    llvm::Value * getStreamSetBlockPointer(llvm::Value * bufferBasePtr, llvm::Value * blockNo) override;
154};
155   
156// Linear buffers extending from the current ConsumerPos forward.   Within the buffer, the
157// offset of the block containing the current consumer position is always zero.
158//
159class LinearCopybackBuffer : public StreamSetBuffer {
160public:
161    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::LinearCopybackBuffer;}
162   
163    LinearCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0) :
164        StreamSetBuffer(BufferKind::LinearCopybackBuffer, b, type, bufferBlocks, AddressSpace) {}
165   
166    llvm::Value * getStreamSetBlockPointer(llvm::Value * bufferStructPtr, llvm::Value * blockNo) override;
167   
168    // Reset the buffer to contain data starting at the base block of new_consumer_pos,
169    // copying back any data beyond that position.
170    void setConsumerPos(Value * bufferStructPtr, Value * newConsumerPos) override;
171};
172
173}
174#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.