source: icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.h @ 6111

Last change on this file since 6111 was 6111, checked in by xwa163, 10 months ago
  1. Cleanup LZ4 AIO related kernels
  2. Improve LZ4ParallelByteStreamAIOKernel
  3. Implement simd_cttz
File size: 10.1 KB
Line 
1#ifndef IDISA_BUILDER_H
2#define IDISA_BUILDER_H
3
4/*
5 *  Copyright (c) 2018 International Characters.
6 *  This software is licensed to the public under the Open Software License 3.0.
7 *  icgrep is a trademark of International Characters.
8 */
9#include "CBuilder.h"
10#include <llvm/IR/DerivedTypes.h>
11namespace llvm { class Constant; }
12namespace llvm { class LoadInst; }
13namespace llvm { class Module; }
14namespace llvm { class Value; }
15
16namespace IDISA {
17
18   
19inline bool isStreamTy(llvm::Type * t) {
20    return t->isVectorTy() && (t->getVectorNumElements() == 0);
21}
22
23inline bool isStreamSetTy(llvm::Type * t) {
24    return t->isArrayTy() && (isStreamTy(t->getArrayElementType()));
25}
26
27inline unsigned getNumOfStreams (llvm::Type * t) {
28    if (isStreamTy(t)) return 1;
29    assert(isStreamSetTy(t));
30    return t->getArrayNumElements();
31}
32
33inline unsigned getStreamFieldWidth (llvm::Type * t) {
34    if (isStreamTy(t)) return t->getScalarSizeInBits();
35    assert(isStreamSetTy(t));
36    return t->getArrayElementType()->getScalarSizeInBits();
37}
38
39unsigned getVectorBitWidth(llvm::Value * vec);
40   
41class IDISA_Builder : public CBuilder {
42
43public:
44
45    IDISA_Builder(llvm::LLVMContext & C, unsigned nativeVectorWidth, unsigned vectorWidth, unsigned laneWidth);
46
47    virtual ~IDISA_Builder();
48   
49    virtual std::string getBuilderUniqueName() = 0;  // A name uniquely identifying builder/bitBlockWidth/stride.
50   
51    llvm::Value * bitCast(llvm::Value * a) {
52        return fwCast(mLaneWidth, a);
53    }
54
55    unsigned getBitBlockWidth() const {
56        return mBitBlockWidth;
57    }
58
59    llvm::Constant * allZeroes() const {
60        return mZeroInitializer;
61    }
62
63    llvm::Constant * allOnes() const {
64        return mOneInitializer;
65    }
66   
67    llvm::Constant * getConstantVectorSequence(unsigned fw, unsigned first, unsigned last, unsigned by = 1);
68   
69    llvm::Value * CreateHalfVectorHigh(llvm::Value *);
70   
71    llvm::Value * CreateHalfVectorLow(llvm::Value *);
72
73    llvm::Value * CreateDoubleVector(llvm::Value * lo, llvm::Value * hi);
74   
75    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr) {
76        return CreateAlignedLoad(ptr, mBitBlockWidth / 8);
77    }
78
79    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr, llvm::Value * const index) {
80        return CreateBlockAlignedLoad(CreateGEP(ptr, index));
81    }
82
83    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
84        return CreateBlockAlignedLoad(CreateGEP(ptr, indices));
85    }
86
87    llvm::StoreInst * CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr) {
88        return CreateAlignedStore(value, ptr, mBitBlockWidth / 8);
89    }
90
91    llvm::StoreInst * CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, llvm::Value * const index) {
92        return CreateBlockAlignedStore(value, CreateGEP(ptr, index));
93    }
94
95    llvm::StoreInst * CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
96        return CreateBlockAlignedStore(value, CreateGEP(ptr, indices));
97    }
98
99    llvm::Value * CreateBlockAlignedMalloc(llvm::Value * size) {
100        return CreateAlignedMalloc(size, mBitBlockWidth / 8);
101    }
102
103    llvm::VectorType * fwVectorType(const unsigned fw);
104
105    llvm::Constant * simd_himask(unsigned fw);
106    llvm::Constant * simd_lomask(unsigned fw);
107   
108    llvm::Value * simd_select_hi(unsigned fw, llvm::Value * a);
109    llvm::Value * simd_select_lo(unsigned fw, llvm::Value * a);
110
111    virtual llvm::Value * simd_fill(unsigned fw, llvm::Value * a);
112
113    virtual llvm::Value * simd_add(unsigned fw, llvm::Value * a, llvm::Value * b);
114    virtual llvm::Value * simd_sub(unsigned fw, llvm::Value * a, llvm::Value * b);
115    virtual llvm::Value * simd_mult(unsigned fw, llvm::Value * a, llvm::Value * b);
116    virtual llvm::Value * simd_eq(unsigned fw, llvm::Value * a, llvm::Value * b);
117    virtual llvm::Value * simd_gt(unsigned fw, llvm::Value * a, llvm::Value * b);
118    virtual llvm::Value * simd_ugt(unsigned fw, llvm::Value * a, llvm::Value * b);
119    virtual llvm::Value * simd_lt(unsigned fw, llvm::Value * a, llvm::Value * b);
120    virtual llvm::Value * simd_ult(unsigned fw, llvm::Value * a, llvm::Value * b);
121    virtual llvm::Value * simd_ule(unsigned fw, llvm::Value * a, llvm::Value * b);
122    virtual llvm::Value * simd_uge(unsigned fw, llvm::Value * a, llvm::Value * b);
123    virtual llvm::Value * simd_max(unsigned fw, llvm::Value * a, llvm::Value * b);
124    virtual llvm::Value * simd_umax(unsigned fw, llvm::Value * a, llvm::Value * b);
125    virtual llvm::Value * simd_min(unsigned fw, llvm::Value * a, llvm::Value * b);
126    virtual llvm::Value * simd_umin(unsigned fw, llvm::Value * a, llvm::Value * b);
127    virtual llvm::Value * simd_if(unsigned fw, llvm::Value * cond, llvm::Value * a, llvm::Value * b);
128   
129    virtual llvm::Value * simd_slli(unsigned fw, llvm::Value * a, unsigned shift);
130    virtual llvm::Value * simd_srli(unsigned fw, llvm::Value * a, unsigned shift);
131    virtual llvm::Value * simd_srai(unsigned fw, llvm::Value * a, unsigned shift);
132    virtual llvm::Value * simd_sllv(unsigned fw, llvm::Value * a, llvm::Value * shifts);
133    virtual llvm::Value * simd_srlv(unsigned fw, llvm::Value * a, llvm::Value * shifts);
134   
135    virtual llvm::Value * simd_pext(unsigned fw, llvm::Value * v, llvm::Value * extract_mask);
136    virtual llvm::Value * simd_pdep(unsigned fw, llvm::Value * v, llvm::Value * deposit_mask);
137   
138    virtual llvm::Value * simd_popcount(unsigned fw, llvm::Value * a);
139    virtual llvm::Value * simd_cttz(unsigned fw, llvm::Value * a);
140
141    virtual llvm::Value * simd_bitreverse(unsigned fw, llvm::Value * a);
142   
143    virtual llvm::Value * esimd_mergeh(unsigned fw, llvm::Value * a, llvm::Value * b);
144    virtual llvm::Value * esimd_mergel(unsigned fw, llvm::Value * a, llvm::Value * b);
145    virtual llvm::Value * esimd_bitspread(unsigned fw, llvm::Value * bitmask);
146   
147    virtual llvm::Value * hsimd_packh(unsigned fw, llvm::Value * a, llvm::Value * b);
148    virtual llvm::Value * hsimd_packl(unsigned fw, llvm::Value * a, llvm::Value * b);
149    virtual llvm::Value * hsimd_packh_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
150    virtual llvm::Value * hsimd_packl_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
151
152    virtual llvm::Value * hsimd_signmask(unsigned fw, llvm::Value * a);
153   
154    virtual llvm::Value * mvmd_extract(unsigned fw, llvm::Value * a, unsigned fieldIndex);
155    virtual llvm::Value * mvmd_insert(unsigned fw, llvm::Value * blk, llvm::Value * elt, unsigned fieldIndex);
156
157    virtual llvm::Value * mvmd_sll(unsigned fw, llvm::Value * value, llvm::Value * shift);
158    virtual llvm::Value * mvmd_srl(unsigned fw, llvm::Value * value, llvm::Value * shift);
159    virtual llvm::Value * mvmd_slli(unsigned fw, llvm::Value * a, unsigned shift);
160    virtual llvm::Value * mvmd_srli(unsigned fw, llvm::Value * a, unsigned shift);
161    virtual llvm::Value * mvmd_dslli(unsigned fw, llvm::Value * a, llvm::Value * b, unsigned shift);
162    virtual llvm::Value * mvmd_dsll(unsigned fw, llvm::Value * a, llvm::Value * b, llvm::Value * shift);
163    virtual llvm::Value * mvmd_shuffle(unsigned fw, llvm::Value * data_table, llvm::Value * index_vector);
164    virtual llvm::Value * mvmd_shuffle2(unsigned fw, llvm::Value * table0, llvm::Value * table1, llvm::Value * index_vector);
165    virtual llvm::Value * mvmd_compress(unsigned fw, llvm::Value * a, llvm::Value * select_mask);
166
167   
168    virtual llvm::Value * bitblock_any(llvm::Value * a);
169    // full add producing {carryout, sum}
170    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_add_with_carry(llvm::Value * a, llvm::Value * b, llvm::Value * carryin);
171    // full shift producing {shiftout, shifted}
172    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_advance(llvm::Value * a, llvm::Value * shiftin, unsigned shift);
173    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_indexed_advance(llvm::Value * a, llvm::Value * index_strm, llvm::Value * shiftin, unsigned shift);
174    virtual llvm::Value * bitblock_mask_from(llvm::Value * pos);
175    virtual llvm::Value * bitblock_set_bit(llvm::Value * pos);
176
177    // returns a scalar with the popcount of this block
178    llvm::Value * bitblock_popcount(llvm::Value * const to_count);
179
180    virtual void CreateBaseFunctions() {}
181   
182    llvm::Value * simd_and(llvm::Value * a, llvm::Value * b);
183    llvm::Value * simd_or(llvm::Value * a, llvm::Value * b);
184    llvm::Value * simd_xor(llvm::Value * a, llvm::Value * b);
185    llvm::Value * simd_not(llvm::Value * a);
186    llvm::Value * fwCast(unsigned fw, llvm::Value * a);
187   
188    inline llvm::VectorType * getBitBlockType() const {
189        return mBitBlockType;
190    }
191
192    static llvm::VectorType * LLVM_READNONE getStreamTy(llvm::LLVMContext & C, const unsigned FieldWidth = 1) {
193        return llvm::VectorType::get(llvm::IntegerType::getIntNTy(C, FieldWidth), 0);
194    }
195
196    static llvm::ArrayType * LLVM_READNONE getStreamSetTy(llvm::LLVMContext & C, const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
197        return llvm::ArrayType::get(getStreamTy(C, FieldWidth), NumElements);
198    }
199
200    llvm::VectorType * getStreamTy(const unsigned FieldWidth = 1) {
201        return getStreamTy(getContext(), FieldWidth);
202    }
203
204    llvm::ArrayType * getStreamSetTy(const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
205        return getStreamSetTy(getContext(), NumElements, FieldWidth);
206    }
207
208    void CallPrintRegisterCond(const std::string & regName, llvm::Value * const value, llvm::Value * const cond);
209    void CallPrintRegister(const std::string & regName, llvm::Value * const value);
210
211protected:
212    LLVM_ATTRIBUTE_NORETURN void UnsupportedFieldWidthError(const unsigned FieldWidth, std::string op_name);
213   
214    llvm::Constant * bit_interleave_byteshuffle_table(unsigned fw);  // support function for merge using shuffles.
215
216    const unsigned              mNativeBitBlockWidth;
217    const unsigned              mBitBlockWidth;
218    const unsigned              mLaneWidth;
219    llvm::VectorType * const    mBitBlockType;
220    llvm::Constant * const      mZeroInitializer;
221    llvm::Constant * const      mOneInitializer;
222    llvm::Constant *            mPrintRegisterFunction;
223};
224
225}
226#endif // IDISA_BUILDER_H
Note: See TracBrowser for help on using the repository browser.