source: icGREP/icgrep-devel/icgrep/kernels/lz4/untwist_kernel.cpp @ 6136

Last change on this file since 6136 was 6136, checked in by xwa163, 12 months ago
  1. Cleanup legacy slow LZ4 related kernels
  2. Rename lz4d_ext_dep to lz4_decompression
  3. Rename LZ4 AIO related kernels to LZ4 Decompression Kernel
File size: 2.8 KB
Line 
1
2#include "untwist_kernel.h"
3#include <kernels/kernel_builder.h>
4
5using namespace llvm;
6
7namespace kernel {
8    UntwistByPEXTKernel::UntwistByPEXTKernel(const std::unique_ptr<kernel::KernelBuilder> &b, unsigned numberOfOutputStream, unsigned twistWidth)
9            :BlockOrientedKernel("UntwistByPEXTKernel",
10                                 {
11                                         Binding{b->getStreamSetTy(1, twistWidth), "byteStream", FixedRate(), Principal()}
12                                 },
13                                 {
14                                         Binding{b->getStreamSetTy(numberOfOutputStream, 1), "basisBits"}
15                                 }, {}, {}, {}),
16             mNumberOfOutputStream(numberOfOutputStream),
17             mTwistWidth(twistWidth)
18    {
19        assert(twistWidth == 2 || twistWidth == 4);
20        assert(numberOfInputStream <= twistWidth);
21
22    }
23
24    void UntwistByPEXTKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> &b) {
25        Function* PEXT_func = Intrinsic::getDeclaration(b->getModule(), Intrinsic::x86_bmi_pext_64);
26
27        uint64_t pextBaseMask = mTwistWidth == 2 ? 0x5555555555555555: 0x1111111111111111;
28
29        Value* inputBasePtr = b->CreatePointerCast(b->getInputStreamBlockPtr("byteStream", b->getSize(0)), b->getInt64Ty()->getPointerTo());
30
31        Value* outputBlocks[mTwistWidth];
32        for (unsigned i = 0; i < mTwistWidth; i++) {
33            outputBlocks[i] = ConstantVector::getNullValue(b->getBitBlockType());
34        }
35
36        for (unsigned i = 0; i < b->getBitBlockWidth() / 64; i++) {
37            Value* currentOutput[mTwistWidth];
38
39            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
40                currentOutput[iIndex] = b->getInt64(0);
41            }
42
43            for (unsigned j = 0; j < mTwistWidth; j++) {
44                unsigned inputIndex = i * mTwistWidth + j;
45
46                Value* currentInput = b->CreateLoad(b->CreateGEP(inputBasePtr, b->getInt32(inputIndex)));
47                for (unsigned k = 0; k < mTwistWidth; k++) {
48
49                    Value* newBits = b->CreateCall(
50                            PEXT_func,{
51                                    currentInput,
52                                    b->getInt64(pextBaseMask << k)
53                            }
54                    );
55
56                    currentOutput[k] = b->CreateOr(currentOutput[k], b->CreateShl(newBits, 64 / mTwistWidth * j));
57                }
58            }
59
60            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
61                outputBlocks[iIndex] = b->CreateInsertElement(outputBlocks[iIndex], currentOutput[iIndex], i);
62            }
63        }
64
65        for (unsigned i = 0; i < mNumberOfOutputStream; i++) {
66            b->storeOutputStreamBlock("basisBits", b->getInt32(i), outputBlocks[i]);
67        }
68    }
69}
Note: See TracBrowser for help on using the repository browser.