source: icGREP/icgrep-devel/icgrep/kernels/cc_kernel.cpp @ 5847

Last change on this file since 5847 was 5847, checked in by cameron, 20 months ago

Unify Parabix CC compiler and Direct CC compiler with a common superclass

File size: 5.1 KB
RevLine 
[5140]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#include "cc_kernel.h"
[5217]7#include <re/re_cc.h>
8#include <cc/cc_compiler.h>
[5436]9#include <kernels/kernel_builder.h>
[5140]10
[5217]11using namespace cc;
[5140]12using namespace kernel;
[5217]13using namespace pablo;
14using namespace re;
[5267]15using namespace llvm;
[5140]16
[5435]17DirectCharacterClassKernelBuilder::DirectCharacterClassKernelBuilder(
[5436]18        const std::unique_ptr<kernel::KernelBuilder> & b, std::string ccSetName, std::vector<re::CC *> charClasses, unsigned codeUnitSize)
[5435]19: BlockOrientedKernel(std::move(ccSetName),
[5823]20              {Binding{b->getStreamSetTy(1, 8 * codeUnitSize), "codeUnitStream", FixedRate(), Principal()}},
[5435]21              {Binding{b->getStreamSetTy(charClasses.size(), 1), "ccStream"}},
22              {}, {}, {})
23, mCharClasses(charClasses)
24, mCodeUnitSize(codeUnitSize) {
25
26}
27
[5440]28void DirectCharacterClassKernelBuilder::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & iBuilder) {
[5140]29    unsigned packCount = 8 * mCodeUnitSize; 
30    unsigned codeUnitWidth = 8 * mCodeUnitSize;
[5823]31    unsigned topBit = 1 << codeUnitWidth;
32    unsigned maxCodeVal = (topBit - 1) | topBit;
[5140]33    Value * codeUnitPack[packCount];
34    for (unsigned i = 0; i < packCount; i++) {
[5440]35        codeUnitPack[i] = iBuilder->loadInputStreamPack("codeUnitStream", iBuilder->getInt32(0), iBuilder->getInt32(i));
[5140]36    }
37    for (unsigned j = 0; j < mCharClasses.size();  j++) {
38        Value * theCCstream = iBuilder->allZeroes();
39        for (const auto & interval : *mCharClasses[j]) {
40            Value * strmPack[packCount];
41            unsigned lo = re::lo_codepoint(interval);
42            unsigned hi = re::hi_codepoint(interval);
43            if (lo == hi) {
44                Value * cp = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), lo);
45                Value * cp_splat = iBuilder->simd_fill(codeUnitWidth, cp);
46                for (unsigned k = 0; k < packCount; k++) {
47                    strmPack[k] = iBuilder->simd_eq(codeUnitWidth, codeUnitPack[k], cp_splat);
48                }
[5823]49            } else if (lo == 0) {
50                if (hi == maxCodeVal) {
51                    for (unsigned k = 0; k < packCount; k++) {
52                        strmPack[k] = iBuilder->allOnes();
53                    }
54                } else {
55                    Value * cp = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), hi + 1);
56                    Value * cp_splat = iBuilder->simd_fill(codeUnitWidth, cp);
57                    for (unsigned k = 0; k < packCount; k++) {
58                        strmPack[k] = iBuilder->simd_ult(codeUnitWidth, codeUnitPack[k], cp_splat);
59                    }
60                }
61            } else if (hi == maxCodeVal) {
62                Value * cp = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), lo - 1);
63                Value * cp_splat = iBuilder->simd_fill(codeUnitWidth, cp);
64                for (unsigned k = 0; k < packCount; k++) {
65                    strmPack[k] = iBuilder->simd_ugt(codeUnitWidth, codeUnitPack[k], cp_splat);
66                }
67            } else {
[5140]68                Value * v1 = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), lo-1);
69                Value * lo_splat = iBuilder->simd_fill(codeUnitWidth, v1);
70                Value * v2 = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), hi+1);
71                Value * hi_splat = iBuilder->simd_fill(codeUnitWidth, v2);
72                for (unsigned k = 0; k < packCount; k++) {
73                    Value * lo_test = iBuilder->simd_ugt(codeUnitWidth, codeUnitPack[k], lo_splat);
74                    Value * hi_test = iBuilder->simd_ult(codeUnitWidth, codeUnitPack[k], hi_splat);
75                    strmPack[k] = iBuilder->simd_and(lo_test, hi_test);
76                }
77            }
78            unsigned packFields = iBuilder->getBitBlockWidth()/packCount;
79            Value * pack = iBuilder->allZeroes();
80            for (unsigned k = 0; k < packCount; k++) {
81                pack = iBuilder->mvmd_insert(packFields, pack, iBuilder->CreateTrunc(iBuilder->hsimd_signmask(codeUnitWidth, strmPack[k]), iBuilder->getIntNTy(packFields)), k);
82            }
83
84            theCCstream = iBuilder->simd_or(theCCstream, pack);
85        }
[5440]86        iBuilder->storeOutputStreamBlock("ccStream", iBuilder->getInt32(j), theCCstream);
[5140]87    }
88}
89
[5828]90
[5217]91ParabixCharacterClassKernelBuilder::ParabixCharacterClassKernelBuilder (
[5436]92        const std::unique_ptr<kernel::KernelBuilder> & b, std::string ccSetName, const std::vector<CC *> & charClasses, unsigned codeUnitSize)
[5828]93: PabloKernel(b, ccSetName +"_kernel",
94// stream inputs
95{Binding{b->getStreamSetTy(codeUnitSize), "basis"}}
96// stream outputs
[5844]97, {Binding(b->getStreamSetTy((unsigned int)charClasses.size()), "outputStream")}
[5828]98)
[5435]99, mCharClasses(charClasses) {
[5828]100
[5435]101}
102
[5436]103void ParabixCharacterClassKernelBuilder::generatePabloMethod() {
[5842]104    PabloBuilder pb(getEntryScope());
[5847]105    cc::Parabix_CC_Compiler ccc(this, getInputStreamSet("basis"));
[5844]106    Var * outputVar = getOutputStreamVar("outputStream");
[5435]107    for (unsigned i = 0; i < mCharClasses.size(); ++i) {
[5844]108        pb.createAssign(pb.createExtract(outputVar, i), ccc.compileCC("cc", mCharClasses[i], pb));
[5217]109    }
110}
Note: See TracBrowser for help on using the repository browser.