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

Last change on this file since 5837 was 5832, checked in by nmedfort, 19 months ago

Bug fix for UntilN

File size: 8.0 KB
RevLine 
[4651]1#ifndef IDISA_BUILDER_H
2#define IDISA_BUILDER_H
3
4/*
5 *  Copyright (c) 2015 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 */
[5260]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; }
[4651]15
16namespace IDISA {
17
[5239]18class IDISA_Builder : public CBuilder {
[5230]19
[4651]20public:
[4665]21
[5489]22    IDISA_Builder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride);
[4665]23
[5240]24    virtual ~IDISA_Builder();
[4821]25   
[5374]26    virtual std::string getBuilderUniqueName() = 0;  // A name uniquely identifying builder/bitBlockWidth/stride.
27   
[5260]28    llvm::Value * bitCast(llvm::Value * a) {
[5377]29        return CreateBitCast(a, mBitBlockType);
[4974]30    }
31
32    unsigned getBitBlockWidth() const {
33        return mBitBlockWidth;
34    }
35
[5126]36    unsigned getStride() const {
37        return mStride;
38    }
39
[5260]40    llvm::Constant * allZeroes() const {
[4974]41        return mZeroInitializer;
42    }
43
[5260]44    llvm::Constant * allOnes() const {
[4974]45        return mOneInitializer;
46    }
[5106]47   
[5493]48    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr) {
49        return CreateAlignedLoad(ptr, mBitBlockWidth / 8);
50    }
[4974]51
[5493]52    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr, llvm::Value * const index) {
53        return CreateBlockAlignedLoad(CreateGEP(ptr, index));
54    }
[4959]55
[5493]56    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
57        return CreateBlockAlignedLoad(CreateGEP(ptr, indices));
58    }
59
60    llvm::StoreInst * CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr) {
61        return CreateAlignedStore(value, ptr, mBitBlockWidth / 8);
62    }
63
64    llvm::StoreInst * CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, llvm::Value * const index) {
65        return CreateBlockAlignedStore(value, CreateGEP(ptr, index));
66    }
67
68    llvm::StoreInst * CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
69        return CreateBlockAlignedStore(value, CreateGEP(ptr, indices));
70    }
71
72    llvm::Value * CreateBlockAlignedMalloc(llvm::Value * size) {
73        return CreateAlignedMalloc(size, mBitBlockWidth / 8);
74    }
75
[5377]76    llvm::VectorType * fwVectorType(const unsigned fw);
[5220]77
[5260]78    llvm::Constant * simd_himask(unsigned fw);
79    llvm::Constant * simd_lomask(unsigned fw);
[5140]80   
[5260]81    virtual llvm::Value * simd_fill(unsigned fw, llvm::Value * a);
[4974]82
[5260]83    virtual llvm::Value * simd_add(unsigned fw, llvm::Value * a, llvm::Value * b);
84    virtual llvm::Value * simd_sub(unsigned fw, llvm::Value * a, llvm::Value * b);
85    virtual llvm::Value * simd_mult(unsigned fw, llvm::Value * a, llvm::Value * b);
86    virtual llvm::Value * simd_eq(unsigned fw, llvm::Value * a, llvm::Value * b);
87    virtual llvm::Value * simd_gt(unsigned fw, llvm::Value * a, llvm::Value * b);
88    virtual llvm::Value * simd_ugt(unsigned fw, llvm::Value * a, llvm::Value * b);
89    virtual llvm::Value * simd_lt(unsigned fw, llvm::Value * a, llvm::Value * b);
90    virtual llvm::Value * simd_ult(unsigned fw, llvm::Value * a, llvm::Value * b);
91    virtual llvm::Value * simd_max(unsigned fw, llvm::Value * a, llvm::Value * b);
92    virtual llvm::Value * simd_umax(unsigned fw, llvm::Value * a, llvm::Value * b);
93    virtual llvm::Value * simd_min(unsigned fw, llvm::Value * a, llvm::Value * b);
94    virtual llvm::Value * simd_umin(unsigned fw, llvm::Value * a, llvm::Value * b);
95    virtual llvm::Value * simd_if(unsigned fw, llvm::Value * cond, llvm::Value * a, llvm::Value * b);
[4651]96   
[5260]97    virtual llvm::Value * simd_slli(unsigned fw, llvm::Value * a, unsigned shift);
98    virtual llvm::Value * simd_srli(unsigned fw, llvm::Value * a, unsigned shift);
99    virtual llvm::Value * simd_srai(unsigned fw, llvm::Value * a, unsigned shift);
[5729]100    virtual llvm::Value * simd_sllv(unsigned fw, llvm::Value * a, llvm::Value * shifts);
101    virtual llvm::Value * simd_srlv(unsigned fw, llvm::Value * a, llvm::Value * shifts);
[4651]102   
[5729]103    virtual llvm::Value * simd_pext(unsigned fw, llvm::Value * v, llvm::Value * extract_mask);
104    virtual llvm::Value * simd_pdep(unsigned fw, llvm::Value * v, llvm::Value * deposit_mask);
105   
[5828]106    llvm::Value * simd_popcount(unsigned fw, llvm::Value * a) {
107        if (LLVM_UNLIKELY(fw < 8)) {
[5832]108            assert ("field width is less than 8" && false);
[5828]109            llvm::report_fatal_error("Unsupported field width: popcount " + std::to_string(fw));
110        }
111        return CreatePopcount(fwCast(fw, a));
112    }
113
[5488]114    virtual llvm::Value * simd_bitreverse(unsigned fw, llvm::Value * a);
[4651]115   
[5260]116    virtual llvm::Value * esimd_mergeh(unsigned fw, llvm::Value * a, llvm::Value * b);
117    virtual llvm::Value * esimd_mergel(unsigned fw, llvm::Value * a, llvm::Value * b);
118    virtual llvm::Value * esimd_bitspread(unsigned fw, llvm::Value * bitmask);
[4653]119   
[5260]120    virtual llvm::Value * hsimd_packh(unsigned fw, llvm::Value * a, llvm::Value * b);
121    virtual llvm::Value * hsimd_packl(unsigned fw, llvm::Value * a, llvm::Value * b);
122    virtual llvm::Value * hsimd_packh_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
123    virtual llvm::Value * hsimd_packl_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
[4957]124
[5260]125    virtual llvm::Value * hsimd_signmask(unsigned fw, llvm::Value * a);
[4697]126   
[5260]127    virtual llvm::Value * mvmd_extract(unsigned fw, llvm::Value * a, unsigned fieldIndex);
128    virtual llvm::Value * mvmd_insert(unsigned fw, llvm::Value * blk, llvm::Value * elt, unsigned fieldIndex);
129    virtual llvm::Value * mvmd_slli(unsigned fw, llvm::Value * a, unsigned shift);
130    virtual llvm::Value * mvmd_srli(unsigned fw, llvm::Value * a, unsigned shift);
131    virtual llvm::Value * mvmd_dslli(unsigned fw, llvm::Value * a, llvm::Value * b, unsigned shift);
[4662]132   
[5114]133   
[5260]134    virtual llvm::Value * bitblock_any(llvm::Value * a);
[5114]135    // full add producing {carryout, sum}
[5260]136    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_add_with_carry(llvm::Value * a, llvm::Value * b, llvm::Value * carryin);
[5114]137    // full shift producing {shiftout, shifted}
[5260]138    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_advance(llvm::Value * a, llvm::Value * shiftin, unsigned shift);
[5713]139    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_indexed_advance(llvm::Value * a, llvm::Value * index_strm, llvm::Value * shiftin, unsigned shift);
[5260]140    virtual llvm::Value * bitblock_mask_from(llvm::Value * pos);
141    virtual llvm::Value * bitblock_set_bit(llvm::Value * pos);
[5458]142
[5464]143    virtual void CreateBaseFunctions() {}
[5114]144   
[5260]145    llvm::Value * simd_and(llvm::Value * a, llvm::Value * b);
146    llvm::Value * simd_or(llvm::Value * a, llvm::Value * b);
147    llvm::Value * simd_xor(llvm::Value * a, llvm::Value * b);
148    llvm::Value * simd_not(llvm::Value * a);
149    llvm::Value * fwCast(unsigned fw, llvm::Value * a);
[4837]150   
[5260]151    inline llvm::VectorType * getBitBlockType() const {
[5217]152        return mBitBlockType;
[5204]153    }
[5217]154
[5446]155    static llvm::VectorType * getStreamTy(llvm::LLVMContext & C, const unsigned FieldWidth = 1) {
156        return llvm::VectorType::get(llvm::IntegerType::getIntNTy(C, FieldWidth), 0);
157    }
158
159    static llvm::ArrayType * getStreamSetTy(llvm::LLVMContext & C, const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
160        return llvm::ArrayType::get(getStreamTy(C, FieldWidth), NumElements);
161    }
162
[5298]163    llvm::VectorType * getStreamTy(const unsigned FieldWidth = 1) {
[5446]164        return getStreamTy(getContext(), FieldWidth);
[5298]165    }
[5230]166
[5446]167    llvm::ArrayType * getStreamSetTy(const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
168        return getStreamSetTy(getContext(), NumElements, FieldWidth);
[5307]169    }
170
[5260]171    void CallPrintRegister(const std::string & regName, llvm::Value * const value);
[5435]172
173protected:
[5436]174    const unsigned              mBitBlockWidth;
175    const unsigned              mStride;
176    llvm::VectorType * const    mBitBlockType;
177    llvm::Constant * const      mZeroInitializer;
178    llvm::Constant * const      mOneInitializer;
179    llvm::Constant *            mPrintRegisterFunction;
[4651]180};
181
[4959]182}
[4651]183#endif // IDISA_BUILDER_H
Note: See TracBrowser for help on using the repository browser.