source: icGREP/icgrep-devel/icgrep/kernels/streamset.cpp @ 5298

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

Removed StreamType? in favour of 0-length VectorType?.

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#include "streamset.h"
7#include <IR_Gen/idisa_builder.h>  // for IDISA_Builder
8#include <assert.h>                // for assert
9#include <llvm/IR/Type.h>          // for Type
10#include <stdexcept>               // for runtime_error
11#include <llvm/IR/BasicBlock.h>    // for BasicBlock
12#include <llvm/IR/Constants.h>     // for ConstantInt
13#include <llvm/IR/DataLayout.h>    // for DataLayout
14#include <llvm/IR/DerivedTypes.h>  // for IntegerType (ptr only), PointerType
15#include <llvm/IR/Module.h>        // for Module
16#include <llvm/IR/Value.h>         // for Value
17namespace llvm { class Constant; }
18namespace llvm { class Function; }
19
20using namespace parabix;
21using namespace llvm;
22using namespace IDISA;
23
24Type * resolveVectorTy(IDISA_Builder * const b, Type * type) {
25    if (LLVM_LIKELY(type->isVectorTy() && type->getVectorNumElements() == 0)) {
26        type = type->getVectorElementType();
27        if (LLVM_LIKELY(type->isIntegerTy())) {
28            const auto fieldWidth = cast<IntegerType>(type)->getBitWidth();
29            type = b->getBitBlockType();
30            if (fieldWidth != 1) {
31                type = llvm::ArrayType::get(type, fieldWidth);
32            }
33        }
34    }
35    return type;
36}
37
38Type * StreamSetBuffer::resolveStreamSetBufferType(Type * const type) const {
39    if (type->isArrayTy()) {
40        return ArrayType::get(resolveVectorTy(iBuilder, type->getArrayElementType()), type->getArrayNumElements());
41    } else if (type->isVectorTy()) {
42        return resolveVectorTy(iBuilder, type);
43    }
44    return type;
45}
46
47void StreamSetBuffer::allocateBuffer() {
48    mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferSize));
49}
50
51Value * StreamSetBuffer::getStream(Value * self, Value * blockNo, Value * index) const {
52    return iBuilder->CreateGEP(getStreamSetPtr(self, blockNo), {iBuilder->getInt32(0), index});
53}
54
55Value * StreamSetBuffer::getStream(Value * self, Value * blockNo, Value * index1, Value * index2) const {
56    return iBuilder->CreateGEP(getStreamSetPtr(self, blockNo), {iBuilder->getInt32(0), index1, index2});
57}
58
59Value * StreamSetBuffer::getStreamView(llvm::Type * type, llvm::Value * self, Value * blockNo, llvm::Value * index) const {
60    return iBuilder->CreateGEP(iBuilder->CreatePointerCast(getStreamSetPtr(self, blockNo), type), index, "view");
61}
62
63// Single Block Buffer
64
65// For a single block buffer, the block pointer is always the buffer base pointer.
66Value * SingleBlockBuffer::getStreamSetPtr(Value * self, Value *) const {
67    return self;
68}
69
70// External File Buffer
71void ExternalFileBuffer::setStreamSetBuffer(Value * ptr, Value * /* fileSize */) {
72    mStreamSetBufferPtr = iBuilder->CreatePointerBitCastOrAddrSpaceCast(ptr, getPointerType());
73}
74
75void ExternalFileBuffer::setEmptyBuffer(Value * ptr) {   
76    mStreamSetBufferPtr = iBuilder->CreatePointerBitCastOrAddrSpaceCast(ptr, getPointerType());
77}
78
79void ExternalFileBuffer::allocateBuffer() {
80    throw std::runtime_error("External buffers cannot be allocated.");
81}
82
83Value * ExternalFileBuffer::getStreamSetPtr(Value * self, Value * blockNo) const {
84    return iBuilder->CreateGEP(self, blockNo);
85}
86
87// Circular Buffer
88
89Value * CircularBuffer::getStreamSetPtr(Value * self, Value * blockNo) const {
90    assert (blockNo->getType()->isIntegerTy());
91
92    Value * offset = nullptr;
93    if (mBufferSize == 1) {
94        offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
95    } else if ((mBufferSize & (mBufferSize - 1)) == 0) { // is power of 2
96        offset = iBuilder->CreateAnd(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize - 1));
97    } else {
98        offset = iBuilder->CreateURem(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize));
99    }
100    return iBuilder->CreateGEP(self, offset);
101}
102
103// Linear Copyback Buffer
104
105Value * LinearCopybackBuffer::getStreamSetPtr(Value * self, Value * blockNo) const {
106    Value * offset = nullptr;
107    if (mBufferSize == 1) {
108        offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
109    } else if ((mBufferSize & (mBufferSize - 1)) == 0) { // is power of 2
110        offset = iBuilder->CreateAnd(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize - 1));
111    } else {
112        offset = iBuilder->CreateURem(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize));
113    }
114    return iBuilder->CreateGEP(self, offset);
115}
116
117
118// Expandable Buffer
119
120Value * ExpandableBuffer::getStreamSetPtr(Value * self, Value * blockNo) const {
121    return nullptr;
122}
123
124llvm::Value * ExpandableBuffer::getStream(llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const {
125    return nullptr;
126}
127
128llvm::Value * ExpandableBuffer::getStream(llvm::Value * self, llvm::Value * blockNo, Value *index1, Value *index2) const {
129    return nullptr;
130}
131
132llvm::Value * ExpandableBuffer::getStreamView(llvm::Type * type, llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const {
133    return nullptr;
134}
135
136// Constructors
137
138SingleBlockBuffer::SingleBlockBuffer(IDISA::IDISA_Builder * b, llvm::Type * type)
139: StreamSetBuffer(BufferKind::BlockBuffer, b, type, 1, 0) {
140
141}
142
143ExternalFileBuffer::ExternalFileBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace)
144: StreamSetBuffer(BufferKind::ExternalFileBuffer, b, type, 0, AddressSpace) {
145
146}
147
148CircularBuffer::CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace)
149: StreamSetBuffer(BufferKind::CircularBuffer, b, type, bufferBlocks, AddressSpace) {
150
151}
152
153LinearCopybackBuffer::LinearCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace)
154: StreamSetBuffer(BufferKind::LinearCopybackBuffer, b, type, bufferBlocks, AddressSpace) {
155
156}
157
158ExpandableBuffer::ExpandableBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace)
159: StreamSetBuffer(BufferKind::ExpandableBuffer, b, type, bufferBlocks, AddressSpace) {
160
161}
162
163StreamSetBuffer::StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, Type * type, unsigned blocks, unsigned AddressSpace)
164: mBufferKind(k)
165, iBuilder(b)
166, mStreamSetType(resolveStreamSetBufferType(type))
167, mBufferSize(blocks)
168, mAddressSpace(AddressSpace)
169, mStreamSetBufferPtr(nullptr)
170, mBaseStreamSetType(type) {
171
172}
Note: See TracBrowser for help on using the repository browser.