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

Last change on this file since 5489 was 5489, checked in by nmedfort, 22 months ago

Bug fix for memory check and issues found parsing internal 'files'. Added backtrace option from execinfo.h

File size: 7.5 KB
Line 
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 */
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
18class IDISA_Builder : public CBuilder {
19
20public:
21
22    IDISA_Builder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride);
23
24    virtual ~IDISA_Builder();
25   
26    virtual std::string getBuilderUniqueName() = 0;  // A name uniquely identifying builder/bitBlockWidth/stride.
27   
28    llvm::Value * bitCast(llvm::Value * a) {
29        return CreateBitCast(a, mBitBlockType);
30    }
31
32    unsigned getBitBlockWidth() const {
33        return mBitBlockWidth;
34    }
35
36    unsigned getStride() const {
37        return mStride;
38    }
39
40    llvm::Constant * allZeroes() const {
41        return mZeroInitializer;
42    }
43
44    llvm::Constant * allOnes() const {
45        return mOneInitializer;
46    }
47   
48    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr);
49    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr, llvm::Value * const index);
50    llvm::LoadInst * CreateBlockAlignedLoad(llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices);
51
52    void CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr);
53    void CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, llvm::Value * const index);
54    void CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices);
55
56    llvm::VectorType * fwVectorType(const unsigned fw);
57
58    llvm::Constant * simd_himask(unsigned fw);
59    llvm::Constant * simd_lomask(unsigned fw);
60   
61    virtual llvm::Value * simd_fill(unsigned fw, llvm::Value * a);
62
63    virtual llvm::Value * simd_add(unsigned fw, llvm::Value * a, llvm::Value * b);
64    virtual llvm::Value * simd_sub(unsigned fw, llvm::Value * a, llvm::Value * b);
65    virtual llvm::Value * simd_mult(unsigned fw, llvm::Value * a, llvm::Value * b);
66    virtual llvm::Value * simd_eq(unsigned fw, llvm::Value * a, llvm::Value * b);
67    virtual llvm::Value * simd_gt(unsigned fw, llvm::Value * a, llvm::Value * b);
68    virtual llvm::Value * simd_ugt(unsigned fw, llvm::Value * a, llvm::Value * b);
69    virtual llvm::Value * simd_lt(unsigned fw, llvm::Value * a, llvm::Value * b);
70    virtual llvm::Value * simd_ult(unsigned fw, llvm::Value * a, llvm::Value * b);
71    virtual llvm::Value * simd_max(unsigned fw, llvm::Value * a, llvm::Value * b);
72    virtual llvm::Value * simd_umax(unsigned fw, llvm::Value * a, llvm::Value * b);
73    virtual llvm::Value * simd_min(unsigned fw, llvm::Value * a, llvm::Value * b);
74    virtual llvm::Value * simd_umin(unsigned fw, llvm::Value * a, llvm::Value * b);
75    virtual llvm::Value * simd_if(unsigned fw, llvm::Value * cond, llvm::Value * a, llvm::Value * b);
76   
77    virtual llvm::Value * simd_slli(unsigned fw, llvm::Value * a, unsigned shift);
78    virtual llvm::Value * simd_srli(unsigned fw, llvm::Value * a, unsigned shift);
79    virtual llvm::Value * simd_srai(unsigned fw, llvm::Value * a, unsigned shift);
80   
81    virtual llvm::Value * simd_cttz(unsigned fw, llvm::Value * a);
82    virtual llvm::Value * simd_popcount(unsigned fw, llvm::Value * a);
83    virtual llvm::Value * simd_bitreverse(unsigned fw, llvm::Value * a);
84   
85    virtual llvm::Value * esimd_mergeh(unsigned fw, llvm::Value * a, llvm::Value * b);
86    virtual llvm::Value * esimd_mergel(unsigned fw, llvm::Value * a, llvm::Value * b);
87    virtual llvm::Value * esimd_bitspread(unsigned fw, llvm::Value * bitmask);
88   
89    virtual llvm::Value * hsimd_packh(unsigned fw, llvm::Value * a, llvm::Value * b);
90    virtual llvm::Value * hsimd_packl(unsigned fw, llvm::Value * a, llvm::Value * b);
91    virtual llvm::Value * hsimd_packh_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
92    virtual llvm::Value * hsimd_packl_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
93
94    virtual llvm::Value * hsimd_signmask(unsigned fw, llvm::Value * a);
95   
96    virtual llvm::Value * mvmd_extract(unsigned fw, llvm::Value * a, unsigned fieldIndex);
97    virtual llvm::Value * mvmd_insert(unsigned fw, llvm::Value * blk, llvm::Value * elt, unsigned fieldIndex);
98    virtual llvm::Value * mvmd_slli(unsigned fw, llvm::Value * a, unsigned shift);
99    virtual llvm::Value * mvmd_srli(unsigned fw, llvm::Value * a, unsigned shift);
100    virtual llvm::Value * mvmd_dslli(unsigned fw, llvm::Value * a, llvm::Value * b, unsigned shift);
101   
102   
103    virtual llvm::Value * bitblock_any(llvm::Value * a);
104    // full add producing {carryout, sum}
105    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_add_with_carry(llvm::Value * a, llvm::Value * b, llvm::Value * carryin);
106    // full shift producing {shiftout, shifted}
107    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_advance(llvm::Value * a, llvm::Value * shiftin, unsigned shift);
108    virtual llvm::Value * bitblock_mask_from(llvm::Value * pos);
109    virtual llvm::Value * bitblock_set_bit(llvm::Value * pos);
110
111    virtual void CreateBaseFunctions() {}
112   
113    llvm::Value * simd_and(llvm::Value * a, llvm::Value * b);
114    llvm::Value * simd_or(llvm::Value * a, llvm::Value * b);
115    llvm::Value * simd_xor(llvm::Value * a, llvm::Value * b);
116    llvm::Value * simd_not(llvm::Value * a);
117    llvm::Value * fwCast(unsigned fw, llvm::Value * a);
118   
119    inline llvm::VectorType * getBitBlockType() const {
120        return mBitBlockType;
121    }
122
123    static llvm::VectorType * getStreamTy(llvm::LLVMContext & C, const unsigned FieldWidth = 1) {
124        return llvm::VectorType::get(llvm::IntegerType::getIntNTy(C, FieldWidth), 0);
125    }
126
127    static llvm::ArrayType * getStreamSetTy(llvm::LLVMContext & C, const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
128        return llvm::ArrayType::get(getStreamTy(C, FieldWidth), NumElements);
129    }
130
131    llvm::VectorType * getStreamTy(const unsigned FieldWidth = 1) {
132        return getStreamTy(getContext(), FieldWidth);
133    }
134
135    llvm::ArrayType * getStreamSetTy(const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
136        return getStreamSetTy(getContext(), NumElements, FieldWidth);
137    }
138
139    void CallPrintRegister(const std::string & regName, llvm::Value * const value);
140
141protected:
142    const unsigned              mBitBlockWidth;
143    const unsigned              mStride;
144    llvm::VectorType * const    mBitBlockType;
145    llvm::Constant * const      mZeroInitializer;
146    llvm::Constant * const      mOneInitializer;
147
148    llvm::Constant *            mPrintRegisterFunction;
149};
150
151inline llvm::LoadInst * IDISA_Builder::CreateBlockAlignedLoad(llvm::Value * const ptr, llvm::Value * const index) {
152    return CreateBlockAlignedLoad(CreateGEP(ptr, index));
153}
154
155inline llvm::LoadInst * IDISA_Builder::CreateBlockAlignedLoad(llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
156    return CreateBlockAlignedLoad(CreateGEP(ptr, indices));
157}
158
159inline void IDISA_Builder::CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, llvm::Value * const index) {
160    CreateBlockAlignedStore(value, CreateGEP(ptr, index));
161}
162
163inline void IDISA_Builder::CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
164    CreateBlockAlignedStore(value, CreateGEP(ptr, indices));
165}
166
167}
168#endif // IDISA_BUILDER_H
Note: See TracBrowser for help on using the repository browser.