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

Last change on this file since 5350 was 5350, checked in by nmedfort, 3 years ago

First attempt at inlining all DoBlock? and FinalBlock? functions by using indirect jumps. Disabled for NVPTX until Linda can check whether they're supported by the LLVM NVPTX library.

File size: 7.4 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::Module * m, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride, const bool SupportsIndirectBr=true, unsigned CacheAlignment=64);
23
24    virtual ~IDISA_Builder();
25   
26    std::string getBitBlockTypeName() const;  // A short string such as v4i64 or i256.
27
28    llvm::Value * bitCast(llvm::Value * a) {
29        return (a->getType() == mBitBlockType) ? a : 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(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   
84    virtual llvm::Value * esimd_mergeh(unsigned fw, llvm::Value * a, llvm::Value * b);
85    virtual llvm::Value * esimd_mergel(unsigned fw, llvm::Value * a, llvm::Value * b);
86    virtual llvm::Value * esimd_bitspread(unsigned fw, llvm::Value * bitmask);
87   
88    virtual llvm::Value * hsimd_packh(unsigned fw, llvm::Value * a, llvm::Value * b);
89    virtual llvm::Value * hsimd_packl(unsigned fw, llvm::Value * a, llvm::Value * b);
90    virtual llvm::Value * hsimd_packh_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
91    virtual llvm::Value * hsimd_packl_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b);
92
93    virtual llvm::Value * hsimd_signmask(unsigned fw, llvm::Value * a);
94   
95    virtual llvm::Value * mvmd_extract(unsigned fw, llvm::Value * a, unsigned fieldIndex);
96    virtual llvm::Value * mvmd_insert(unsigned fw, llvm::Value * blk, llvm::Value * elt, unsigned fieldIndex);
97    virtual llvm::Value * mvmd_slli(unsigned fw, llvm::Value * a, unsigned shift);
98    virtual llvm::Value * mvmd_srli(unsigned fw, llvm::Value * a, unsigned shift);
99    virtual llvm::Value * mvmd_dslli(unsigned fw, llvm::Value * a, llvm::Value * b, unsigned shift);
100   
101   
102    virtual llvm::Value * bitblock_any(llvm::Value * a);
103    // full add producing {carryout, sum}
104    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_add_with_carry(llvm::Value * a, llvm::Value * b, llvm::Value * carryin);
105    // full shift producing {shiftout, shifted}
106    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_advance(llvm::Value * a, llvm::Value * shiftin, unsigned shift);
107    virtual llvm::Value * bitblock_mask_from(llvm::Value * pos);
108    virtual llvm::Value * bitblock_set_bit(llvm::Value * pos);
109   
110    llvm::Value * simd_and(llvm::Value * a, llvm::Value * b);
111    llvm::Value * simd_or(llvm::Value * a, llvm::Value * b);
112    llvm::Value * simd_xor(llvm::Value * a, llvm::Value * b);
113    llvm::Value * simd_not(llvm::Value * a);
114    llvm::Value * fwCast(unsigned fw, llvm::Value * a);
115   
116    inline llvm::VectorType * getBitBlockType() const {
117        return mBitBlockType;
118    }
119
120    llvm::VectorType * getStreamTy(const unsigned FieldWidth = 1) {
121        return llvm::VectorType::get(llvm::IntegerType::getIntNTy(getContext(), FieldWidth), 0);
122    }
123
124    inline llvm::ArrayType * getStreamSetTy(const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
125        return llvm::ArrayType::get(getStreamTy(FieldWidth), NumElements);
126    }
127
128    void CallPrintRegister(const std::string & regName, llvm::Value * const value);
129   
130protected:
131    unsigned            mBitBlockWidth;
132    unsigned            mStride;
133    llvm::VectorType *  mBitBlockType;
134    llvm::Constant *    mZeroInitializer;
135    llvm::Constant *    mOneInitializer;
136    llvm::Constant *    mPrintRegisterFunction;
137};
138
139inline llvm::LoadInst * IDISA_Builder::CreateBlockAlignedLoad(llvm::Value * const ptr) {
140    return CreateAlignedLoad(ptr, mBitBlockWidth / 8);
141}
142
143inline llvm::LoadInst * IDISA_Builder::CreateBlockAlignedLoad(llvm::Value * const ptr, llvm::Value * const index) {
144    return CreateBlockAlignedLoad(CreateGEP(ptr, index));
145}
146
147inline llvm::LoadInst * IDISA_Builder::CreateBlockAlignedLoad(llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
148    return CreateBlockAlignedLoad(CreateGEP(ptr, indices));
149}
150
151inline void IDISA_Builder::CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr) {
152    CreateAlignedStore(value, ptr, mBitBlockWidth / 8);
153}
154
155inline void IDISA_Builder::CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, llvm::Value * const index) {
156    CreateBlockAlignedStore(value, CreateGEP(ptr, index));
157}
158
159inline void IDISA_Builder::CreateBlockAlignedStore(llvm::Value * const value, llvm::Value * const ptr, std::initializer_list<llvm::Value *> indices) {
160    CreateBlockAlignedStore(value, CreateGEP(ptr, indices));
161}
162   
163
164   
165}
166#endif // IDISA_BUILDER_H
Note: See TracBrowser for help on using the repository browser.