source: icGREP/icgrep-devel/icgrep/kernels/lz4/twist_kernel.cpp @ 6140

Last change on this file since 6140 was 6140, checked in by xwa163, 15 months ago

UTF-8 support for Multiplexing LZ4 Grep

File size: 4.6 KB
RevLine 
[6136]1
2
3#include "twist_kernel.h"
4#include <llvm/IR/Intrinsics.h>
5#include <kernels/streamset.h>
6#include <kernels/kernel_builder.h>
7#include <toolchain/toolchain.h>
8#include <llvm/Support/Compiler.h>
9
10namespace llvm { class Value; }
11
12using namespace llvm;
13using namespace parabix;
14
15namespace kernel {
16
[6140]17    void twistByPDEP(const std::unique_ptr <kernel::KernelBuilder> &b, Value *inputBlocks[], unsigned mTwistWidth, Value* outputBasePtr) {
18        Function *PDEPFunc = Intrinsic::getDeclaration(b->getModule(), Intrinsic::x86_bmi_pdep_64);
19        uint64_t pdepBaseMask = mTwistWidth == 2? 0x5555555555555555 : 0x1111111111111111;
20
21        for (unsigned i = 0; i < b->getBitBlockWidth() / 64; i++) {
22            Value *currentInput[mTwistWidth];
23            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
24                currentInput[iIndex] = b->CreateExtractElement(inputBlocks[iIndex], i);
25            }
26
27            for (unsigned j = 0; j < mTwistWidth; j++) {
28                unsigned outputIndex = i * mTwistWidth + j;
29                Value *retI64 = b->getInt64(0);
30                for (unsigned k = 0; k < mTwistWidth; k++) {
31                    Value *newBits = b->CreateCall(
32                            PDEPFunc, {
33                                    b->CreateLShr(currentInput[k], b->getInt64(j * 64 / mTwistWidth)),
34                                    b->getInt64(pdepBaseMask << k)
35                            }
36                    );
37                    retI64 = b->CreateOr(retI64, newBits);
38                }
39                b->CreateStore(retI64, b->CreateGEP(outputBasePtr, b->getInt32(outputIndex)));
40            }
41        }
42    }
43
44
45
46
[6136]47    TwistByPDEPKernel::TwistByPDEPKernel(const std::unique_ptr <kernel::KernelBuilder> &b, unsigned numberOfInputStream, unsigned twistWidth)
48            : BlockOrientedKernel("TwistByPDEPKernel",
49                                  {Binding{b->getStreamSetTy(numberOfInputStream, 1), "basisBits"}},
50                                  {Binding{b->getStreamSetTy(1, twistWidth), "byteStream"}},
51                                  {}, {}, {}),
52              mNumberOfInputStream(numberOfInputStream),
53              mTwistWidth(twistWidth)
54    {
55        assert(twistWidth == 2 || twistWidth == 4);
56        assert(numberOfInputStream <= twistWidth);
57    }
58
59    void TwistByPDEPKernel::generateDoBlockMethod(const std::unique_ptr <kernel::KernelBuilder> &b) {
[6140]60        Value *inputBlocks[mTwistWidth];
[6136]61
62        for (unsigned i = 0; i < mTwistWidth; i++) {
63            if (i < mNumberOfInputStream) {
64                inputBlocks[i] = b->loadInputStreamBlock("basisBits", b->getInt32(i));
65            } else {
66                inputBlocks[i] = ConstantVector::getNullValue(b->getBitBlockType());
67            }
68        }
69
70        Value *outputBasePtr = b->CreatePointerCast(b->getOutputStreamBlockPtr("byteStream", b->getSize(0)),
71                                                    b->getInt64Ty()->getPointerTo());
[6140]72        twistByPDEP(b, inputBlocks, mTwistWidth, outputBasePtr);
73    }
[6136]74
75
[6140]76    TwistMultipleByPDEPKernel::TwistMultipleByPDEPKernel(const std::unique_ptr<kernel::KernelBuilder> &b,
77                                                         unsigned numberOfInputStreamSet, unsigned twistWidth)
78            : BlockOrientedKernel("TwistMultipleByPDEPKernel",
79                                  {},
80                                  {Binding{b->getStreamSetTy(1, twistWidth), "byteStream"}},
81                                  {}, {}, {}),
82              mNumberOfInputStreamSet(numberOfInputStreamSet),
83              mTwistWidth(twistWidth)
84    {
85        for (unsigned i = 0; i < numberOfInputStreamSet; i++) {
86            mStreamSetInputs.push_back(Binding{b->getStreamSetTy(1), "basisBits_" + std::to_string(i) });
87        }
88    }
89
90    void TwistMultipleByPDEPKernel::generateDoBlockMethod(const std::unique_ptr<kernel::KernelBuilder> &b) {
91        Value *inputBlocks[mTwistWidth];
92
93        for (unsigned i = 0; i < mTwistWidth; i++) {
94            if (i < mNumberOfInputStreamSet) {
95                inputBlocks[i] = b->loadInputStreamBlock("basisBits_" + std::to_string(i), b->getInt32(0));
96                if (i == 0) {
97                    b->CallPrintRegister("basisBits_" + std::to_string(i), inputBlocks[i]);
[6136]98                }
[6140]99            } else {
100                inputBlocks[i] = ConstantVector::getNullValue(b->getBitBlockType());
[6136]101            }
102        }
[6140]103
104        Value *outputBasePtr = b->CreatePointerCast(b->getOutputStreamBlockPtr("byteStream", b->getSize(0)),
105                                                    b->getInt64Ty()->getPointerTo());
106        twistByPDEP(b, inputBlocks, mTwistWidth, outputBasePtr);
[6136]107    }
108}
Note: See TracBrowser for help on using the repository browser.