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

Last change on this file since 5861 was 5861, checked in by cameron, 16 months ago

Using DirectCC builder updates; speedup wc -l

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