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

Last change on this file since 6135 was 6135, checked in by xwa163, 9 months ago
  1. Implement twist_kernel and untwist_kernel by PEXT and PDEP
  2. Use twist form for multiplexing lz4 grep
File size: 2.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    TwistByPDEPKernel::TwistByPDEPKernel(const std::unique_ptr <kernel::KernelBuilder> &b, unsigned numberOfInputStream, unsigned twistWidth)
18            : BlockOrientedKernel("TwistByPDEPKernel",
19                                  {Binding{b->getStreamSetTy(numberOfInputStream, 1), "basisBits"}},
20                                  {Binding{b->getStreamSetTy(1, twistWidth), "byteStream"}},
21                                  {}, {}, {}),
22              mNumberOfInputStream(numberOfInputStream),
23              mTwistWidth(twistWidth)
24    {
25        assert(twistWidth == 2 || twistWidth == 4);
26        assert(numberOfInputStream <= twistWidth);
27    }
28
29    void TwistByPDEPKernel::generateDoBlockMethod(const std::unique_ptr <kernel::KernelBuilder> &b) {
30        Function *PDEPFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::x86_bmi_pdep_64);
31        uint64_t pdepBaseMask = mTwistWidth == 2? 0x5555555555555555 : 0x1111111111111111;
32
33        Value *inputBlocks[mTwistWidth];
34        for (unsigned i = 0; i < mTwistWidth; i++) {
35            if (i < mNumberOfInputStream) {
36                inputBlocks[i] = b->loadInputStreamBlock("basisBits", b->getInt32(i));
37//            b->CallPrintRegister("input" + std::to_string(i), inputBlocks[i]);
38
39            } else {
40                inputBlocks[i] = ConstantVector::getNullValue(b->getBitBlockType());
41            }
42        }
43
44        Value *outputBasePtr = b->CreatePointerCast(b->getOutputStreamBlockPtr("byteStream", b->getSize(0)),
45                                                    b->getInt64Ty()->getPointerTo());
46
47        for (unsigned i = 0; i < b->getBitBlockWidth() / 64; i++) {
48            Value *currentInput[mTwistWidth];
49            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
50                currentInput[iIndex] = b->CreateExtractElement(inputBlocks[iIndex], i);
51            }
52
53            for (unsigned j = 0; j < mTwistWidth; j++) {
54                unsigned outputIndex = i * mTwistWidth + j;
55                Value *retI64 = b->getInt64(0);
56                for (unsigned k = 0; k < mTwistWidth; k++) {
57                    Value *newBits = b->CreateCall(
58                            PDEPFunc, {
59                                    b->CreateLShr(currentInput[k], b->getInt64(j * 64 / mTwistWidth)),
60                                    b->getInt64(pdepBaseMask << k)
61                            }
62                    );
63                    retI64 = b->CreateOr(retI64, newBits);
64                }
65                b->CreateStore(retI64, b->CreateGEP(outputBasePtr, b->getInt32(outputIndex)));
66            }
67        }
68    }
69
70}
Note: See TracBrowser for help on using the repository browser.