source: icGREP/icgrep-devel/icgrep/IDISA/idisa_avx_builder.cpp @ 4955

Last change on this file since 4955 was 4955, checked in by cameron, 3 years ago

Improved implementation of simd_pack on AVX2

File size: 3.7 KB
Line 
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_avx_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
13namespace IDISA {
14
15Value * IDISA_AVX_Builder::hsimd_signmask(unsigned fw, Value * a) {
16    if (fw == 64) {
17        Value * signmask_f64func = Intrinsic::getDeclaration(mMod, Intrinsic::x86_avx_movmsk_pd_256);
18        Type * bitBlock_f64type = VectorType::get(getDoubleTy(), mBitBlockWidth/64);
19        Value * a_as_pd = CreateBitCast(a, bitBlock_f64type);
20        Value * mask = CreateCall(signmask_f64func, std::vector<Value *>({a_as_pd}));
21        return mask;
22    }
23    else if (fw == 32) {
24        Value * signmask_f32func = Intrinsic::getDeclaration(mMod, Intrinsic::x86_avx_movmsk_ps_256);
25        Type * bitBlock_f32type = VectorType::get(getFloatTy(), mBitBlockWidth/32);
26        Value * a_as_ps = CreateBitCast(a, bitBlock_f32type);
27        Value * mask = CreateCall(signmask_f32func, std::vector<Value *>({a_as_ps}));
28        return mask;
29    }
30    Value * mask = CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
31    return CreateBitCast(mask, getIntNTy(mBitBlockWidth/fw));
32}
33   
34Value * IDISA_AVX2_Builder::hsimd_packh(unsigned fw, Value * a, Value * b) {
35    unsigned field_count = 2 * mBitBlockWidth/fw;
36    Value * aVec = fwCast(fw/2, a);
37    Value * bVec = fwCast(fw/2, b);
38    if (fw <= 64) {
39        std::vector<Constant*> Idxs;
40        for (unsigned i = 0; i < field_count/4; i++) {
41            Idxs.push_back(getInt32(2*i + 1));
42        }
43        for (unsigned i = 0; i < field_count/4; i++) {
44            Idxs.push_back(getInt32(2*i));
45        }
46        for (unsigned i = 0; i < field_count/4; i++) {
47            Idxs.push_back(getInt32(field_count/2 + 2*i + 1));
48        }
49        for (unsigned i = 0; i < field_count/4; i++) {
50            Idxs.push_back(getInt32(field_count/2 + 2*i));
51        }
52        Value * shufa = CreateShuffleVector(aVec, aVec, ConstantVector::get(Idxs));
53        Value * shufb = CreateShuffleVector(bVec, bVec, ConstantVector::get(Idxs));
54        Value * pk = hsimd_packh(128, shufa, shufb);
55        return pk;
56    }
57    else {
58        std::vector<Constant*> Idxs;
59        for (unsigned i = 0; i < field_count; i++) {
60            Idxs.push_back(getInt32(2*i));
61        }
62        return CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
63    }
64}
65
66Value * IDISA_AVX2_Builder::hsimd_packl(unsigned fw, Value * a, Value * b) {
67    unsigned field_count = 2 * mBitBlockWidth/fw;
68    Value * aVec = fwCast(fw/2, a);
69    Value * bVec = fwCast(fw/2, b);
70    if (fw <= 64) {
71        std::vector<Constant*> Idxs;
72        for (unsigned i = 0; i < field_count/4; i++) {
73            Idxs.push_back(getInt32(2*i + 1));
74        }
75        for (unsigned i = 0; i < field_count/4; i++) {
76            Idxs.push_back(getInt32(2*i));
77        }
78        for (unsigned i = 0; i < field_count/4; i++) {
79            Idxs.push_back(getInt32(field_count/2 + 2*i + 1));
80        }
81        for (unsigned i = 0; i < field_count/4; i++) {
82            Idxs.push_back(getInt32(field_count/2 + 2*i));
83        }
84        Value * shufa = CreateShuffleVector(aVec, aVec, ConstantVector::get(Idxs));
85        Value * shufb = CreateShuffleVector(bVec, bVec, ConstantVector::get(Idxs));
86        return hsimd_packl(128, shufa, shufb);
87    }
88    else {
89        std::vector<Constant*> Idxs;
90        for (unsigned i = 0; i < field_count; i++) {
91            Idxs.push_back(getInt32(2*i+1));
92        }
93        return CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
94    }
95}
96}
Note: See TracBrowser for help on using the repository browser.