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

Last change on this file since 6144 was 6144, checked in by xwa163, 10 months ago

lz4_grep: Init checkin for utf8 character class multiplexing

File size: 4.8 KB
Line 
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
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    TwistByPDEPKernel::TwistByPDEPKernel(const std::unique_ptr <kernel::KernelBuilder> &b, unsigned numberOfInputStream, unsigned twistWidth)
45            : BlockOrientedKernel("TwistByPDEPKernel",
46                                  {Binding{b->getStreamSetTy(numberOfInputStream, 1), "basisBits"}},
47                                  {Binding{b->getStreamSetTy(1, twistWidth), "byteStream"}},
48                                  {}, {}, {}),
49              mNumberOfInputStream(numberOfInputStream),
50              mTwistWidth(twistWidth)
51    {
52        assert(twistWidth == 2 || twistWidth == 4);
53        assert(numberOfInputStream <= twistWidth);
54    }
55
56    void TwistByPDEPKernel::generateDoBlockMethod(const std::unique_ptr <kernel::KernelBuilder> &b) {
57        Value *inputBlocks[mTwistWidth];
58
59        for (unsigned i = 0; i < mTwistWidth; i++) {
60            if (i < mNumberOfInputStream) {
61                inputBlocks[i] = b->loadInputStreamBlock("basisBits", b->getInt32(i));
62            } else {
63                inputBlocks[i] = ConstantVector::getNullValue(b->getBitBlockType());
64            }
65        }
66
67        Value *outputBasePtr = b->CreatePointerCast(b->getOutputStreamBlockPtr("byteStream", b->getSize(0)),
68                                                    b->getInt64Ty()->getPointerTo());
69        twistByPDEP(b, inputBlocks, mTwistWidth, outputBasePtr);
70    }
71
72
73    TwistMultipleByPDEPKernel::TwistMultipleByPDEPKernel(const std::unique_ptr<kernel::KernelBuilder> &b,
74                     std::vector<unsigned> numberOfInputStreams, unsigned twistWidth)
75            : BlockOrientedKernel("TwistMultipleByPDEPKernel",
76                                  {},
77                                  {Binding{b->getStreamSetTy(1, twistWidth), "byteStream"}},
78                                  {}, {}, {}),
79              mNumberOfInputStreams(numberOfInputStreams),
80              mTwistWidth(twistWidth)
81    {
82        assert(twistWidth == 2 || twistWidth == 4);
83        size_t totalNumOfStreams = 0;
84        for (unsigned i = 0; i < numberOfInputStreams.size(); i++) {
85            totalNumOfStreams += numberOfInputStreams[i];
86            mStreamSetInputs.push_back(Binding{b->getStreamSetTy(numberOfInputStreams[i]), "basisBits_" + std::to_string(i) });
87        }
88        assert(totalNumOfStreams < twistWidth);
89    }
90
91    void TwistMultipleByPDEPKernel::generateDoBlockMethod(const std::unique_ptr<kernel::KernelBuilder> &b) {
92        Value *inputBlocks[mTwistWidth];
93
94        unsigned iStreamIndex = 0;
95        for (unsigned i = 0; i < mNumberOfInputStreams.size(); i++) {
96            for (unsigned j = 0; j < mNumberOfInputStreams[i]; j++) {
97                inputBlocks[iStreamIndex] = b->loadInputStreamBlock("basisBits_" + std::to_string(i), b->getInt32(j));
98                ++iStreamIndex;
99            }
100        }
101
102        for (; iStreamIndex < mTwistWidth; iStreamIndex++) {
103            inputBlocks[iStreamIndex] = ConstantVector::getNullValue(b->getBitBlockType());
104        }
105
106
107        Value *outputBasePtr = b->CreatePointerCast(b->getOutputStreamBlockPtr("byteStream", b->getSize(0)),
108                                                    b->getInt64Ty()->getPointerTo());
109        twistByPDEP(b, inputBlocks, mTwistWidth, outputBasePtr);
110    }
111}
Note: See TracBrowser for help on using the repository browser.