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

Last change on this file was 6261, checked in by nmedfort, 10 months ago

Work on OptimizationBranch?; revisited pipeline termination

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