source: icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.cpp @ 4843

Last change on this file since 4843 was 4843, checked in by cameron, 4 years ago

Move genPrintRegister into IDISA builder; fix GCB defs

File size: 8.8 KB
RevLine 
[4651]1/*
2 *  Copyright (c) 2015 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include "idisa_builder.h"
8#include <llvm/IR/IRBuilder.h>
9#include <llvm/IR/Constants.h>
10#include <llvm/IR/Intrinsics.h>
11#include <llvm/IR/Function.h>
12
[4665]13namespace IDISA {
[4651]14
15Value * IDISA_Builder::bitBlockCast(Value * a) {
[4837]16    return a->getType() == mBitBlockType ? a : mLLVMBuilder->CreateBitCast(a, mBitBlockType);
[4651]17}
18
19VectorType * IDISA_Builder::fwVectorType(unsigned fw) {
[4827]20    int fieldCount = mBitBlockWidth/fw;
[4665]21    return VectorType::get(mLLVMBuilder->getIntNTy(fw), fieldCount);
[4651]22}
23
24Value * IDISA_Builder::fwCast(unsigned fw, Value * a) {
[4837]25    return a->getType() == fwVectorType(fw) ? a : mLLVMBuilder->CreateBitCast(a, fwVectorType(fw));
[4651]26}
27
[4843]28void IDISA_Builder::genPrintRegister(std::string regName, Value * bitblockValue) {
29    if (mPrintRegisterFunction == nullptr) {
30        mPrintRegisterFunction = mMod->getOrInsertFunction("wrapped_print_register", Type::getVoidTy(mMod->getContext()), Type::getInt8PtrTy(mMod->getContext()), mBitBlockType, NULL);
31    }
32    Constant * regNameData = ConstantDataArray::getString(mMod->getContext(), regName);
33    GlobalVariable *regStrVar = new GlobalVariable(*mMod,
34                                                   ArrayType::get(IntegerType::get(mMod->getContext(), 8), regName.length()+1),
35                                                   /*isConstant=*/ true,
36                                                   /*Linkage=*/ GlobalValue::PrivateLinkage,
37                                                   /*Initializer=*/ regNameData);
38    Value * regStrPtr = mLLVMBuilder->CreateGEP(regStrVar, std::vector<Value *>({mLLVMBuilder->getInt64(0), mLLVMBuilder->getInt32(0)}));
39    mLLVMBuilder->CreateCall(mPrintRegisterFunction, std::vector<Value *>({regStrPtr, bitblockValue}));
40}
41
42   
[4651]43Value * IDISA_Builder::simd_add(unsigned fw, Value * a, Value * b) {
[4837]44    return mLLVMBuilder->CreateAdd(fwCast(fw, a), fwCast(fw, b));
[4651]45}
46
47Value * IDISA_Builder::simd_sub(unsigned fw, Value * a, Value * b) {
[4837]48    return mLLVMBuilder->CreateSub(fwCast(fw, a), fwCast(fw, b));
[4651]49}
50
51Value * IDISA_Builder::simd_mult(unsigned fw, Value * a, Value * b) {
[4837]52    return mLLVMBuilder->CreateMul(fwCast(fw, a), fwCast(fw, b));
[4651]53}
54
55Value * IDISA_Builder::simd_eq(unsigned fw, Value * a, Value * b) {
[4837]56    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpEQ(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
[4651]57}
58
59Value * IDISA_Builder::simd_gt(unsigned fw, Value * a, Value * b) {
[4837]60    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
[4651]61}
62
63Value * IDISA_Builder::simd_ugt(unsigned fw, Value * a, Value * b) {
[4837]64    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpUGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
[4651]65}
66
67Value * IDISA_Builder::simd_lt(unsigned fw, Value * a, Value * b) {
[4837]68    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
[4651]69}
70
71Value * IDISA_Builder::simd_ult(unsigned fw, Value * a, Value * b) {
[4837]72    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpULT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
[4651]73}
74
75Value * IDISA_Builder::simd_max(unsigned fw, Value * a, Value * b) {
76    Value * aVec = fwCast(fw, a);
77    Value * bVec = fwCast(fw, b);
[4837]78    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSGT(aVec, bVec), aVec, bVec);
[4651]79}
80
81Value * IDISA_Builder::simd_umax(unsigned fw, Value * a, Value * b) {
82    Value * aVec = fwCast(fw, a);
83    Value * bVec = fwCast(fw, b);
[4837]84    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpUGT(aVec, bVec), aVec, bVec);
[4651]85}
86
87Value * IDISA_Builder::simd_min(unsigned fw, Value * a, Value * b) {
88    Value * aVec = fwCast(fw, a);
89    Value * bVec = fwCast(fw, b);
[4837]90    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSLT(aVec, bVec), aVec, bVec);
[4651]91}
92
93Value * IDISA_Builder::simd_umin(unsigned fw, Value * a, Value * b) {
94    Value * aVec = fwCast(fw, a);
95    Value * bVec = fwCast(fw, b);
[4837]96    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpULT(aVec, bVec), aVec, bVec);
[4651]97}
98
99Value * IDISA_Builder::simd_slli(unsigned fw, Value * a, unsigned shift) {
[4837]100    return mLLVMBuilder->CreateShl(fwCast(fw, a), shift);
[4651]101}
102
103Value * IDISA_Builder::simd_srli(unsigned fw, Value * a, unsigned shift) {
[4837]104    return mLLVMBuilder->CreateLShr(fwCast(fw, a), shift);
[4651]105}
106
107Value * IDISA_Builder::simd_srai(unsigned fw, Value * a, unsigned shift) {
[4837]108    return mLLVMBuilder->CreateAShr(fwCast(fw, a), shift);
[4651]109}
110
111Value * IDISA_Builder::simd_cttz(unsigned fw, Value * a) {
112    Value * cttzFunc = Intrinsic::getDeclaration(mMod, Intrinsic::cttz, fwVectorType(fw));
[4750]113    Value * rslt = mLLVMBuilder->CreateCall(cttzFunc, std::vector<Value *>({fwCast(fw, a), ConstantInt::get(mLLVMBuilder->getInt1Ty(), 0)}));
[4837]114    return rslt;
[4651]115}
116
[4720]117Value * IDISA_Builder::simd_popcount(unsigned fw, Value * a) {
118    Value * ctpopFunc = Intrinsic::getDeclaration(mMod, Intrinsic::ctpop, fwVectorType(fw));
[4750]119    Value * rslt = mLLVMBuilder->CreateCall(ctpopFunc, std::vector<Value *>({fwCast(fw, a)}));
[4837]120    return rslt;
[4720]121}
122
[4652]123Value * IDISA_Builder::esimd_mergeh(unsigned fw, Value * a, Value * b) {
[4827]124    unsigned field_count = mBitBlockWidth/fw;
[4652]125    Value * aVec = fwCast(fw, a);
126    Value * bVec = fwCast(fw, b);
127    std::vector<Constant*> Idxs;
128    for (unsigned i = field_count/2; i < field_count; i++) {
[4665]129        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
130        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
[4652]131    }
[4837]132    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
[4652]133}
134
135Value * IDISA_Builder::esimd_mergel(unsigned fw, Value * a, Value * b) {
[4827]136    unsigned field_count = mBitBlockWidth/fw;
[4652]137    Value * aVec = fwCast(fw, a);
138    Value * bVec = fwCast(fw, b);
139    std::vector<Constant*> Idxs;
140    for (unsigned i = 0; i < field_count/2; i++) {
[4665]141        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
142        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
[4652]143    }
[4837]144    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
[4652]145}
146
[4653]147Value * IDISA_Builder::hsimd_packh(unsigned fw, Value * a, Value * b) {
[4827]148    unsigned field_count = 2 * mBitBlockWidth/fw;
[4653]149    Value * aVec = fwCast(fw/2, a);
150    Value * bVec = fwCast(fw/2, b);
151    std::vector<Constant*> Idxs;
152    for (unsigned i = 0; i < field_count; i++) {
[4665]153        Idxs.push_back(mLLVMBuilder->getInt32(2*i));
[4653]154    }
[4837]155    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
[4653]156}
[4652]157
[4653]158Value * IDISA_Builder::hsimd_packl(unsigned fw, Value * a, Value * b) {
[4827]159    unsigned field_count = 2 * mBitBlockWidth/fw;
[4653]160    Value * aVec = fwCast(fw/2, a);
161    Value * bVec = fwCast(fw/2, b);
162    std::vector<Constant*> Idxs;
163    for (unsigned i = 0; i < field_count; i++) {
[4665]164        Idxs.push_back(mLLVMBuilder->getInt32(2*i+1));
[4653]165    }
[4837]166    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
[4653]167}
[4652]168
[4653]169Value * IDISA_Builder::hsimd_signmask(unsigned fw, Value * a) {
[4665]170    Value * mask = mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
[4827]171    return mLLVMBuilder->CreateBitCast(mask, mLLVMBuilder->getIntNTy(mBitBlockWidth/fw));
[4653]172}
173
[4697]174Value * IDISA_Builder::mvmd_extract(unsigned fw, Value * a, unsigned fieldIndex) {
175    Value * aVec = fwCast(fw, a);
176    return mLLVMBuilder->CreateExtractElement(aVec, mLLVMBuilder->getInt32(fieldIndex));
177}
178
[4655]179Value * IDISA_Builder::mvmd_dslli(unsigned fw, Value * a, Value * b, unsigned shift) {
[4827]180    unsigned field_count = mBitBlockWidth/fw;
[4655]181    Value * aVec = fwCast(fw, a);
182    Value * bVec = fwCast(fw, b);
183    std::vector<Constant*> Idxs;
184    for (unsigned i = shift; i < field_count + shift; i++) {
[4665]185        Idxs.push_back(mLLVMBuilder->getInt32(i));
[4655]186    }
[4837]187    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
[4655]188}
[4653]189
[4662]190Value * IDISA_Builder::bitblock_any(Value * a) {
[4827]191    Type * iBitBlock = mLLVMBuilder->getIntNTy(mBitBlockWidth);
[4665]192    return mLLVMBuilder->CreateICmpNE(mLLVMBuilder->CreateBitCast(a, iBitBlock),  ConstantInt::get(iBitBlock, 0));
[4662]193}
[4665]194
[4837]195Value * IDISA_Builder::simd_and(Value * a, Value * b) {
196    return a->getType() == b->getType() ? mLLVMBuilder->CreateAnd(a, b) : mLLVMBuilder->CreateAnd(bitBlockCast(a), bitBlockCast(b));
[4665]197}
[4837]198
199Value * IDISA_Builder::simd_or(Value * a, Value * b) {
200    return a->getType() == b->getType() ? mLLVMBuilder->CreateOr(a, b) : mLLVMBuilder->CreateOr(bitBlockCast(a), bitBlockCast(b));
201}
202   
203Value * IDISA_Builder::simd_xor(Value * a, Value * b) {
204    return a->getType() == b->getType() ? mLLVMBuilder->CreateXor(a, b) : mLLVMBuilder->CreateXor(bitBlockCast(a), bitBlockCast(b));
205}
206
207Value * IDISA_Builder::simd_not(Value * a) {
208    return simd_xor(a, Constant::getAllOnesValue(a->getType()));
209}
210
211}
Note: See TracBrowser for help on using the repository browser.