source: icGREP/icgrep-devel/icgrep/kernels/lzparabix/decoder/LZParabixSwizzledAioKernel.cpp @ 6133

Last change on this file since 6133 was 6133, checked in by xwa163, 12 months ago
  1. Add sourceCC in multiplexed CC
  2. Remove workaround FakeBasisBits? from ICGrep
  3. Implement Swizzled version of LZParabix
  4. Init checkin for SwizzleByGather? Kernel
File size: 9.2 KB
Line 
1
2#include "LZParabixSwizzledAioKernel.h"
3
4#include <kernels/kernel_builder.h>
5#include <iostream>
6#include <llvm/Support/raw_ostream.h>
7#include <kernels/streamset.h>
8
9using namespace llvm;
10using namespace kernel;
11using namespace std;
12
13namespace kernel{
14
15    LZParabixSwizzledAioKernel::LZParabixSwizzledAioKernel(const std::unique_ptr<kernel::KernelBuilder> &b)
16    : LZParabixAioBaseKernel(b, "LZParabixSwizzledAioKernel") {
17//        mStreamSetInputs.push_back(Binding{b->getStreamSetTy(8, 1), "inputBitStream", BoundedRate(0, 1), AlwaysConsume()});
18        mStreamSetInputs.push_back(Binding{b->getStreamSetTy(8, 1), "inputSwizzled0", BoundedRate(0, 1), AlwaysConsume()});
19        mStreamSetInputs.push_back(Binding{b->getStreamSetTy(8, 1), "inputSwizzled1", RateEqualTo("inputSwizzled0"), AlwaysConsume()});
20
21        mStreamSetOutputs.push_back(Binding{b->getStreamSetTy(4, 1), "outputSwizzle0", BoundedRate(0, 1)/*, Swizzled()*/});
22        mStreamSetOutputs.push_back(Binding{b->getStreamSetTy(4, 1), "outputSwizzle1", RateEqualTo("outputSwizzle0")/*, Swizzled()*/});
23
24        for (unsigned i = 0; i < 2; i++) {
25            this->addScalar(b->getBitBlockType()->getPointerTo(), "currentOutputPtr" + std::to_string(i));
26        }
27    }
28
29    void LZParabixSwizzledAioKernel::initDoSegmentMethod(const std::unique_ptr<KernelBuilder> &b) {
30        for (unsigned i = 0; i < 2; i++) {
31            Value* ptr = b->CreatePointerCast(b->getOutputStreamBlockPtr("outputSwizzle" + std::to_string(i), b->getSize(0)), b->getBitBlockType()->getPointerTo());
32            b->setScalarField("currentOutputPtr" + std::to_string(i), ptr);
33            b->CreateStore(ConstantVector::getNullValue(b->getBitBlockType()), ptr);
34        }
35    }
36
37    llvm::Value* LZParabixSwizzledAioKernel::isAllItemAvailable(const std::unique_ptr<KernelBuilder> &b, llvm::Value* literalLength) {
38        Value* literalStartPos = b->getProcessedItemCount("inputSwizzled0");
39        Value* literalEndPos = b->CreateAdd(literalStartPos, literalLength);
40        return b->CreateICmpULE(literalEndPos, b->getAvailableItemCount("inputSwizzled0"));
41    }
42
43    void LZParabixSwizzledAioKernel::doLiteralCopy(const std::unique_ptr<KernelBuilder> &b, llvm::Value *cursorPos,
44                                                   llvm::Value *literalLength) {
45        // TODO continue here
46        // ---- EntryBlock
47        BasicBlock* entryBlock = b->GetInsertBlock();
48        Value* remCursorPos = b->CreateURem(cursorPos, b->getCapacity("inputSwizzled0"));
49
50        BasicBlock* processLiteralConBlock = b->CreateBasicBlock("processLiteralConBlock");
51        BasicBlock* processLiteralBodyBlock = b->CreateBasicBlock("processLiteralBodyBlock");
52        BasicBlock* processLiteralExitBlock = b->CreateBasicBlock("processLiteralExitBlock");
53
54        b->CreateBr(processLiteralConBlock);
55
56        // ---- processLiteralConBlock
57        b->SetInsertPoint(processLiteralConBlock);
58        PHINode* phiRemCursorPos = b->CreatePHI(b->getSizeTy(), 2);
59        phiRemCursorPos->addIncoming(remCursorPos, entryBlock);
60        PHINode* phiRemainingLiteralLength = b->CreatePHI(b->getSizeTy(), 2);
61        phiRemainingLiteralLength->addIncoming(literalLength, entryBlock);
62
63        b->CreateCondBr(b->CreateICmpUGT(phiRemainingLiteralLength, b->getSize(0)), processLiteralBodyBlock, processLiteralExitBlock);
64
65        // ---- processLiteralBodyBlock
66        b->SetInsertPoint(processLiteralBodyBlock);
67
68        Value* targetLiteralLength = b->CreateSub(b->getSize(64), b->CreateURem(phiRemCursorPos, b->getSize(64)));
69        targetLiteralLength = b->CreateUMin(phiRemainingLiteralLength, targetLiteralLength);
70
71        Value* cursorI64BlockIndex = b->CreateUDiv(phiRemCursorPos, b->getSize(64));
72        Value* cursorI64BlockRem = b->CreateURem(phiRemCursorPos, b->getSize(64));
73        Value* literalMask = b->CreateSub(
74                b->CreateSelect(b->CreateICmpEQ(targetLiteralLength, b->getInt64(0x40)), b->getInt64(0), b->CreateShl(b->getInt64(1), targetLiteralLength)),
75                b->getInt64(1)
76        );
77
78
79        std::vector<llvm::Value*> swizzledValues;
80
81        for (unsigned i = 0; i < 2; i++) {
82            Value* bitStreamBasePtr = b->CreatePointerCast(b->getRawInputPointer("inputSwizzled" + std::to_string(i), b->getSize(0)), b->getBitBlockType()->getPointerTo());
83            Value* targetBlockBasePtr = b->CreateGEP(bitStreamBasePtr, cursorI64BlockIndex);
84
85            Value* swizzledValue = b->simd_srlv(64, b->CreateLoad(targetBlockBasePtr), b->simd_fill(64, cursorI64BlockRem));
86            swizzledValue = b->simd_and(swizzledValue, b->simd_fill(64, literalMask));
87            swizzledValues.push_back(swizzledValue);
88        }
89
90        this->appendBitStreamOutput(b, swizzledValues, targetLiteralLength);
91
92        phiRemCursorPos->addIncoming(b->CreateURem(b->CreateAdd(phiRemCursorPos, targetLiteralLength), b->getCapacity("inputSwizzled0")), b->GetInsertBlock());
93        phiRemainingLiteralLength->addIncoming(b->CreateSub(phiRemainingLiteralLength, targetLiteralLength), b->GetInsertBlock());
94
95        b->CreateBr(processLiteralConBlock);
96
97        // ---- processLiteralExitBlock
98        b->SetInsertPoint(processLiteralExitBlock);
99    }
100
101    void LZParabixSwizzledAioKernel::doMatchCopy(const std::unique_ptr<KernelBuilder> &b, llvm::Value *cursorPos,
102                                                 llvm::Value *matchOffset, llvm::Value *matchMask) {
103        Constant * PEXT_func = Intrinsic::getDeclaration(b->getModule(), Intrinsic::x86_bmi_pext_64);
104        std::vector<llvm::Value*> swizzledValues;
105
106        // TODO logic here is incorrect, since outputStream here is in swizzled form now
107        for (unsigned i = 0; i < 2; i++) {
108            Value* outputBasePtr = b->CreatePointerCast(b->getRawOutputPointer("outputSwizzle" + std::to_string(i), b->getSize(0)), b->getBitBlockType()->getPointerTo());
109            Value* currentOutputPtr = b->getScalarField("currentOutputPtr" + std::to_string(i));
110            Value* currentOutputBlockIndex = b->CreatePtrDiff(currentOutputPtr, outputBasePtr);
111            Value* targetOutputBlockIndex = b->CreateSub(currentOutputBlockIndex, matchOffset);
112
113            Value* targetPtr = b->CreateGEP(outputBasePtr, targetOutputBlockIndex);
114            Value* swizzledValue = b->CreateLoad(targetPtr);
115
116            for (unsigned j = 0; j < 4; j++) {
117                Value* value = b->CreateExtractElement(swizzledValue, j);
118                Value * extractV = b->CreateCall(PEXT_func, {value, matchMask});
119                swizzledValue = b->CreateInsertElement(swizzledValue, extractV, j);
120            }
121            swizzledValues.push_back(swizzledValue);
122        }
123
124        this->appendBitStreamOutput(b, swizzledValues, b->CreatePopcount(matchMask));
125    }
126
127    void LZParabixSwizzledAioKernel::appendBitStreamOutput(const unique_ptr<KernelBuilder> &b,
128                                                           vector<Value *, allocator<Value *>> &swizzledValues,
129                                                           Value *valueLength) {
130        BasicBlock* exitBlock = b->CreateBasicBlock("exitBlock");
131
132        Value* oldOutputPos = b->getScalarField("outputPos");
133        Value* oldOutputPosRem64 = b->CreateURem(oldOutputPos, b->getSize(64));
134
135        for (unsigned i = 0; i < 2; i++) {
136            Value* outputPtr = b->getScalarField("currentOutputPtr" + std::to_string(i));
137            Value* newValue = b->simd_or(
138                    b->CreateLoad(outputPtr),
139                    b->simd_sllv(64, swizzledValues[i], b->simd_fill(64, oldOutputPosRem64))
140            );
141            b->CreateStore(newValue, outputPtr);
142        }
143
144        BasicBlock* exceedOutputBlock =b->CreateBasicBlock("exceedOutputBlock");
145        b->CreateCondBr(b->CreateICmpULT(b->CreateAdd(oldOutputPosRem64, valueLength), b->getSize(64)), exitBlock, exceedOutputBlock);
146
147        // ---- storeOutputBlock
148        b->SetInsertPoint(exceedOutputBlock);
149
150        Value* shiftAmount = b->CreateSub(b->getSize(0x40), oldOutputPosRem64);
151        Value* fullyShift = b->CreateICmpEQ(shiftAmount, b->getSize(0x40));
152
153        for (unsigned i = 0; i < 2; i++) {
154            Value* oldOutputPtr = b->getScalarField("currentOutputPtr" + std::to_string(i));
155            Value* newOutputPtr = b->CreateGEP(oldOutputPtr, b->getSize(1));
156
157            b->setScalarField("currentOutputPtr" + std::to_string(i), newOutputPtr);
158            Value* newValue = b->CreateSelect(
159                    fullyShift,
160                    ConstantVector::getNullValue(b->getBitBlockType()),
161                    b->simd_srlv(64, swizzledValues[i], b->simd_fill(64, shiftAmount))
162            );
163            b->CreateStore(newValue, newOutputPtr);
164        }
165
166        b->CreateBr(exitBlock);
167
168        b->SetInsertPoint(exitBlock);
169        b->setScalarField("outputPos", b->CreateAdd(oldOutputPos, valueLength));
170    }
171
172    void
173    LZParabixSwizzledAioKernel::setProducedOutputItemCount(const std::unique_ptr<KernelBuilder> &b, llvm::Value *c) {
174        b->setProducedItemCount("outputSwizzle0", c);
175    }
176
177    llvm::Value* LZParabixSwizzledAioKernel::getProcessedInputItemCount(const std::unique_ptr<KernelBuilder> &b) {
178        return b->getProcessedItemCount("inputSwizzled0");
179    }
180    void LZParabixSwizzledAioKernel::setProcessedInputItemCount(const std::unique_ptr<KernelBuilder> &b, llvm::Value* c) {
181        b->setProcessedItemCount("inputSwizzled0", c);
182    }
183}
Note: See TracBrowser for help on using the repository browser.