source: icGREP/icgrep-devel/icgrep/lz4/LZ4GrepGenerator.cpp @ 5974

Last change on this file since 5974 was 5974, checked in by xwa163, 17 months ago
  1. Use i1 bit stream instead of i64 number stream in M0 related streams and Match Offset related stream
  2. Improve the performance of lz4_index_builder
File size: 24.7 KB
Line 
1//
2// Created by wxy325 on 2018/3/15.
3//
4
5#include "LZ4GrepGenerator.h"
6
7#include <boost/filesystem.hpp>
8#include <boost/iostreams/device/mapped_file.hpp>
9
10#include <llvm/Support/CommandLine.h>
11#include <llvm/Support/PrettyStackTrace.h>
12
13#include <cc/cc_compiler.h>
14
15#include <lz4FrameDecoder.h>
16#include <kernels/streamset.h>
17#include <kernels/cc_kernel.h>
18#include <kernels/s2p_kernel.h>
19#include <kernels/p2s_kernel.h>
20#include <kernels/source_kernel.h>
21#include <kernels/stdout_kernel.h>
22#include <kernels/lz4/lz4_generate_deposit_stream.h>
23#include <kernels/kernel_builder.h>
24#include <kernels/deletion.h>
25#include <kernels/swizzle.h>
26#include <kernels/pdep_kernel.h>
27#include <kernels/lz4/lz4_multiple_pdep_kernel.h>
28#include <kernels/lz4/lz4_match_copy_kernel.h>
29#include <kernels/lz4/lz4_swizzled_match_copy_kernel.h>
30#include <re/re_toolchain.h>
31
32#include <re/collect_ccs.h>
33#include <re/replaceCC.h>
34
35#include <set>
36#include "grep/grep_engine.h"
37#include "grep_interface.h"
38#include <llvm/IR/Module.h>
39#include <boost/filesystem.hpp>
40#include <UCD/resolve_properties.h>
41#include <kernels/charclasses.h>
42#include <kernels/cc_kernel.h>
43#include <kernels/grep_kernel.h>
44#include <kernels/UCD_property_kernel.h>
45#include <kernels/grapheme_kernel.h>
46#include <kernels/linebreak_kernel.h>
47#include <kernels/streams_merge.h>
48#include <kernels/source_kernel.h>
49#include <kernels/s2p_kernel.h>
50#include <kernels/scanmatchgen.h>
51#include <kernels/streamset.h>
52#include <kernels/until_n.h>
53#include <kernels/kernel_builder.h>
54#include <pablo/pablo_kernel.h>
55#include <re/re_cc.h>
56#include <re/re_name.h>
57#include <re/casing.h>
58#include <re/exclude_CC.h>
59#include <re/to_utf8.h>
60#include <re/re_toolchain.h>
61#include <toolchain/toolchain.h>
62#include <re/re_analysis.h>
63#include <re/re_name_resolve.h>
64#include <re/re_name_gather.h>
65//#include <re/re_collect_unicodesets.h>
66#include <re/re_multiplex.h>
67#include <re/grapheme_clusters.h>
68#include <re/printer_re.h>
69#include <toolchain/toolchain.h>
70#include <toolchain/cpudriver.h>
71#include <iostream>
72#include <cc/multiplex_CCs.h>
73#include <llvm/Support/raw_ostream.h>
74#include <util/aligned_allocator.h>
75#include <sys/stat.h>
76#include <fcntl.h>
77#include <errno.h>
78#include <llvm/ADT/STLExtras.h> // for make_unique
79#include <llvm/Support/CommandLine.h>
80#include <llvm/Support/Debug.h>
81#include <sched.h>
82#include <cstdio>
83#include <cc/multiplex_CCs.h>
84
85
86namespace re { class CC; }
87
88using namespace llvm;
89using namespace parabix;
90using namespace kernel;
91using namespace grep;
92
93
94const unsigned ByteCClimit = 6;
95
96
97LZ4GrepGenerator::LZ4GrepGenerator(): LZ4Generator() {
98    mGrepRecordBreak = grep::GrepRecordBreakKind::LF;
99    mMoveMatchesToEOL = true;
100}
101
102void LZ4GrepGenerator::initREs(std::vector<re::RE *> & REs) {
103    if (mGrepRecordBreak == GrepRecordBreakKind::Unicode) {
104        mBreakCC = re::makeCC(re::makeCC(0x0A, 0x0D), re::makeCC(re::makeCC(0x85), re::makeCC(0x2028, 0x2029)));
105    } else if (mGrepRecordBreak == GrepRecordBreakKind::Null) {
106        mBreakCC = re::makeByte(0);  // Null
107    } else {
108        mBreakCC = re::makeByte(0x0A); // LF
109    }
110    re::RE * anchorRE = mBreakCC;
111    if (mGrepRecordBreak == GrepRecordBreakKind::Unicode) {
112        re::Name * anchorName = re::makeName("UTF8_LB", re::Name::Type::Unicode);
113        anchorName->setDefinition(UCD::UnicodeBreakRE());
114        anchorRE = anchorName;
115    }
116
117    mREs = REs;
118    bool allAnchored = true;
119    for(unsigned i = 0; i < mREs.size(); ++i) {
120        if (!hasEndAnchor(mREs[i])) allAnchored = false;
121        mREs[i] = resolveModesAndExternalSymbols(mREs[i]);
122        mREs[i] = re::exclude_CC(mREs[i], mBreakCC);
123        mREs[i] = resolveAnchors(mREs[i], anchorRE);
124        re::gatherUnicodeProperties(mREs[i], mUnicodeProperties);
125        mREs[i] = regular_expression_passes(mREs[i]);
126    }
127    if (allAnchored && (mGrepRecordBreak != GrepRecordBreakKind::Unicode)) mMoveMatchesToEOL = false;
128
129}
130
131
132
133std::pair<parabix::StreamSetBuffer *, parabix::StreamSetBuffer *> LZ4GrepGenerator::grepPipeline(
134        std::vector<re::RE *> &REs, parabix::StreamSetBuffer *BasisBits) {
135
136    this->initREs(REs);
137    auto mGrepDriver = &pxDriver;
138
139
140    auto & idb = mGrepDriver->getBuilder();
141    // TODO: until we automate stream buffer sizing, use this calculation to determine how large our matches buffer needs to be.
142    const unsigned baseBufferSize = this->getInputBufferBlocks();
143    bool MultithreadedSimpleRE = false;
144    bool PropertyKernels = false;
145    bool CC_Multiplexing = false;
146    bool InvertMatchFlag = false;
147    int MaxCountFlag = 0;
148
149
150
151
152    //  Regular Expression Processing and Analysis Phase
153    const auto nREs = mREs.size();
154    bool hasGCB[nREs];
155    bool anyGCB = false;
156
157    for(unsigned i = 0; i < nREs; ++i) {
158        hasGCB[i] = hasGraphemeClusterBoundary(mREs[i]);
159        anyGCB |= hasGCB[i];
160    }
161    StreamSetBuffer * LineBreakStream = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
162    std::vector<StreamSetBuffer *> MatchResultsBufs(nREs);
163
164    re::RE * prefixRE;
165    re::RE * suffixRE;
166    // For simple regular expressions with a small number of characters, we
167    // can bypass transposition and use the Direct CC compiler.
168//    bool isSimple = (nREs == 1) && (mGrepRecordBreak != GrepRecordBreakKind::Unicode) && (!anyGCB);
169    bool isSimple = false;
170    if (isSimple) {
171        mREs[0] = toUTF8(mREs[0]);
172    }
173    if (isSimple && byteTestsWithinLimit(mREs[0], ByteCClimit)) {
174        std::vector<std::string> externalStreamNames;
175        std::vector<StreamSetBuffer *> icgrepInputSets = {ByteStream};
176        if (MultithreadedSimpleRE && hasTriCCwithinLimit(mREs[0], ByteCClimit, prefixRE, suffixRE)) {
177            auto CCs = re::collectCCs(prefixRE, &cc::Byte);
178            for (auto cc : CCs) {
179                auto ccName = makeName(cc);
180                mREs[0] = re::replaceCC(mREs[0], cc, ccName);
181                std::string ccNameStr = ccName->getFullName();
182                StreamSetBuffer * ccStream = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
183                kernel::Kernel * ccK = mGrepDriver->addKernelInstance<kernel::DirectCharacterClassKernelBuilder>(idb, ccNameStr, std::vector<re::CC *>{cc});
184                mGrepDriver->makeKernelCall(ccK, {ByteStream}, {ccStream});
185                externalStreamNames.push_back(ccNameStr);
186                icgrepInputSets.push_back(ccStream);
187            }
188        }
189        StreamSetBuffer * MatchResults = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
190        kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ByteGrepKernel>(idb, mREs[0], externalStreamNames);
191        mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
192        MatchResultsBufs[0] = MatchResults;
193        kernel::Kernel * breakK = mGrepDriver->addKernelInstance<kernel::DirectCharacterClassKernelBuilder>(idb, "breakCC", std::vector<re::CC *>{mBreakCC});
194        mGrepDriver->makeKernelCall(breakK, {ByteStream}, {LineBreakStream});
195    } else if (isSimple && hasTriCCwithinLimit(mREs[0], ByteCClimit, prefixRE, suffixRE)) {
196        std::vector<std::string> externalStreamNames;
197        std::vector<StreamSetBuffer *> icgrepInputSets = {ByteStream};
198        if (MultithreadedSimpleRE) {
199            auto CCs = re::collectCCs(prefixRE, &cc::Byte);
200            for (auto cc : CCs) {
201                auto ccName = makeName(cc);
202                mREs[0] = re::replaceCC(mREs[0], cc, ccName);
203                std::string ccNameStr = ccName->getFullName();
204                StreamSetBuffer * ccStream = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
205                kernel::Kernel * ccK = mGrepDriver->addKernelInstance<kernel::DirectCharacterClassKernelBuilder>(idb, ccNameStr, std::vector<re::CC *>{cc});
206                mGrepDriver->makeKernelCall(ccK, {ByteStream}, {ccStream});
207                externalStreamNames.push_back(ccNameStr);
208                icgrepInputSets.push_back(ccStream);
209            }
210        }
211        StreamSetBuffer * MatchResults = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
212        kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ByteBitGrepKernel>(idb, prefixRE, suffixRE, externalStreamNames);
213        mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
214        MatchResultsBufs[0] = MatchResults;
215        kernel::Kernel * breakK = mGrepDriver->addKernelInstance<kernel::DirectCharacterClassKernelBuilder>(idb, "breakCC", std::vector<re::CC *>{mBreakCC});
216        mGrepDriver->makeKernelCall(breakK, {ByteStream}, {LineBreakStream});
217    } else {
218        StreamSetBuffer * RequiredStreams = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
219        StreamSetBuffer * UnicodeLB = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
220
221        StreamSetBuffer * LineFeedStream = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
222        kernel::Kernel * linefeedK = mGrepDriver->addKernelInstance<kernel::LineFeedKernelBuilder>(idb, Binding{idb->getStreamSetTy(8), "basis", FixedRate(), Principal()});
223        mGrepDriver->makeKernelCall(linefeedK, {BasisBits}, {LineFeedStream});
224
225        kernel::Kernel * requiredStreamsK = mGrepDriver->addKernelInstance<kernel::RequiredStreams_UTF8>(idb);
226        mGrepDriver->makeKernelCall(requiredStreamsK, {BasisBits, LineFeedStream}, {RequiredStreams, UnicodeLB});
227
228        if (mGrepRecordBreak == GrepRecordBreakKind::LF) {
229            LineBreakStream = LineFeedStream;
230        } else if (mGrepRecordBreak == GrepRecordBreakKind::Null) {
231            kernel::Kernel * breakK = mGrepDriver->addKernelInstance<kernel::ParabixCharacterClassKernelBuilder>(idb, "Null", std::vector<re::CC *>{mBreakCC}, 8);
232            mGrepDriver->makeKernelCall(breakK, {BasisBits}, {LineBreakStream});
233        } else {
234            LineBreakStream = UnicodeLB;
235        }
236
237        std::map<std::string, StreamSetBuffer *> propertyStream;
238        if (PropertyKernels) {
239            for (auto p : mUnicodeProperties) {
240                auto name = p->getFullName();
241                StreamSetBuffer * s = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
242                propertyStream.emplace(std::make_pair(name, s));
243                kernel::Kernel * propertyK = mGrepDriver->addKernelInstance<kernel::UnicodePropertyKernelBuilder>(idb, p);
244                mGrepDriver->makeKernelCall(propertyK, {BasisBits}, {s});
245            }
246        }
247        StreamSetBuffer * GCB_stream = nullptr;
248        if (anyGCB) {
249            GCB_stream = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
250            kernel::Kernel * gcbK = mGrepDriver->addKernelInstance<kernel::GraphemeClusterBreakKernel>(idb);
251            mGrepDriver->makeKernelCall(gcbK, {BasisBits, RequiredStreams}, {GCB_stream});
252        }
253
254        for(unsigned i = 0; i < nREs; ++i) {
255            std::vector<std::string> externalStreamNames;
256            std::vector<StreamSetBuffer *> icgrepInputSets = {BasisBits};
257            if (mGrepRecordBreak == GrepRecordBreakKind::Unicode) {
258                externalStreamNames.push_back("UTF8_LB");
259                icgrepInputSets.push_back(LineBreakStream);
260                externalStreamNames.push_back("UTF8_nonfinal");
261                icgrepInputSets.push_back(RequiredStreams);
262            }
263            std::set<re::Name *> UnicodeProperties;
264            if (PropertyKernels) {
265                re::gatherUnicodeProperties(mREs[i], UnicodeProperties);
266                for (auto p : UnicodeProperties) {
267                    auto name = p->getFullName();
268                    auto f = propertyStream.find(name);
269                    if (f == propertyStream.end()) report_fatal_error(name + " not found\n");
270                    externalStreamNames.push_back(name);
271                    icgrepInputSets.push_back(f->second);
272                }
273            }
274            if (hasGCB[i]) {
275                externalStreamNames.push_back("\\b{g}");
276                icgrepInputSets.push_back(GCB_stream);
277            }
278            if (CC_Multiplexing) {
279                const auto UnicodeSets = re::collectCCs(mREs[i], &cc::Unicode, std::set<re::Name *>({re::makeZeroWidth("\\b{g}")}));
280                StreamSetBuffer * const MatchResults = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
281                if (UnicodeSets.size() <= 1) {
282                    kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, mREs[i], externalStreamNames);
283                    mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
284                    MatchResultsBufs[i] = MatchResults;
285                } else {
286                    mpx = make_unique<cc::MultiplexedAlphabet>("mpx", UnicodeSets);
287                    mREs[i] = transformCCs(mpx.get(), mREs[i]);
288                    std::vector<re::CC *> mpx_basis = mpx->getMultiplexedCCs();
289                    auto numOfCharacterClasses = mpx_basis.size();
290                    StreamSetBuffer * CharClasses = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(numOfCharacterClasses), baseBufferSize);
291                    kernel::Kernel * ccK = mGrepDriver->addKernelInstance<kernel::CharClassesKernel>(idb, std::move(mpx_basis));
292                    mGrepDriver->makeKernelCall(ccK, {BasisBits}, {CharClasses});
293                    //                kernel::Kernel * ccK = mGrepDriver->addKernelInstance<kernel::CharClassesKernel>(idb, std::move(mpx_basis), true);
294                    //                mGrepDriver->makeKernelCall(ccK, {ByteStream}, {CharClasses});
295                    kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, mREs[i], externalStreamNames, std::vector<cc::Alphabet *>{mpx.get()});
296                    icgrepInputSets.push_back(CharClasses);
297                    mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
298                    MatchResultsBufs[i] = MatchResults;
299                }
300            } else {
301                StreamSetBuffer * MatchResults = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
302                kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, mREs[i], externalStreamNames);
303                mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
304                MatchResultsBufs[i] = MatchResults;
305            }
306        }
307    }
308
309    StreamSetBuffer * MergedResults = MatchResultsBufs[0];
310    if (mREs.size() > 1) {
311        MergedResults = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
312        kernel::Kernel * streamsMergeK = mGrepDriver->addKernelInstance<kernel::StreamsMerge>(idb, 1, mREs.size());
313        mGrepDriver->makeKernelCall(streamsMergeK, MatchResultsBufs, {MergedResults});
314    }
315    StreamSetBuffer * Matches = MergedResults;
316    if (mMoveMatchesToEOL) {
317        StreamSetBuffer * OriginalMatches = Matches;
318        kernel::Kernel * matchedLinesK = mGrepDriver->addKernelInstance<kernel::MatchedLinesKernel>(idb);
319        Matches = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
320        mGrepDriver->makeKernelCall(matchedLinesK, {OriginalMatches, LineBreakStream}, {Matches});
321    }
322    if (InvertMatchFlag) {
323        kernel::Kernel * invertK = mGrepDriver->addKernelInstance<kernel::InvertMatchesKernel>(idb);
324        StreamSetBuffer * OriginalMatches = Matches;
325        Matches = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
326        mGrepDriver->makeKernelCall(invertK, {OriginalMatches, LineBreakStream}, {Matches});
327    }
328    if (MaxCountFlag > 0) {
329        kernel::Kernel * untilK = mGrepDriver->addKernelInstance<kernel::UntilNkernel>(idb);
330        untilK->setInitialArguments({idb->getSize(MaxCountFlag)});
331        StreamSetBuffer * const AllMatches = Matches;
332        Matches = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
333        mGrepDriver->makeKernelCall(untilK, {AllMatches}, {Matches});
334    }
335
336    return std::pair<StreamSetBuffer *, StreamSetBuffer *>(LineBreakStream, Matches);
337
338}
339
340
341
342
343void LZ4GrepGenerator::invokeScanMatchGrep(char* fileBuffer, size_t blockStart, size_t blockEnd, bool hasBlockChecksum) {
344    auto main = this->getScanMatchGrepMainFunction();
345    std::ostringstream s;
346    EmitMatch accum("", false, false, s);
347
348    main(fileBuffer, blockStart, blockEnd, hasBlockChecksum, reinterpret_cast<intptr_t>(&accum));
349    llvm::outs() << s.str();
350}
351
352void LZ4GrepGenerator::generateScanMatchGrepPipeline(re::RE* regex) {
353    auto & iBuilder = pxDriver.getBuilder();
354    this->generateScanMatchMainFunc(iBuilder);
355
356    StreamSetBuffer * const DecompressedByteStream = pxDriver.addBuffer<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8), this->getDecompressedBufferBlocks());
357
358    // GeneratePipeline
359    this->generateLoadByteStreamAndBitStream(iBuilder);
360    this->generateExtractAndDepositMarkers(iBuilder);
361
362    auto swizzle = this->generateSwizzleExtractData(iBuilder);
363
364    //TODO buffer blocks should be decompressedBufferBlocks
365    StreamSetBuffer * depositedSwizzle0 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
366    StreamSetBuffer * depositedSwizzle1 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
367
368    Kernel * multiplePdepK = pxDriver.addKernelInstance<LZ4MultiplePDEPkernel>(iBuilder, 4, 2, 4);
369    pxDriver.makeKernelCall(multiplePdepK, {DepositMarker, swizzle.first, swizzle.second}, {depositedSwizzle0, depositedSwizzle1});
370
371
372    StreamSetBuffer * matchCopiedSwizzle0 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
373    StreamSetBuffer * matchCopiedSwizzle1 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
374
375    Kernel * swizzledMatchCopyK = pxDriver.addKernelInstance<LZ4SwizzledMatchCopyKernel>(iBuilder, 4, 2, 4);
376    pxDriver.makeKernelCall(swizzledMatchCopyK, {MatchOffsetMarker, M0Marker, M0CountMarker, ByteStream, depositedSwizzle0, depositedSwizzle1}, {matchCopiedSwizzle0, matchCopiedSwizzle1});
377
378
379    // Produce unswizzled bit streams
380    StreamSetBuffer * extractedbits = pxDriver.addBuffer<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(8), this->getInputBufferBlocks());
381    Kernel * unSwizzleK = pxDriver.addKernelInstance<SwizzleGenerator>(iBuilder, 8, 1, 2);
382    pxDriver.makeKernelCall(unSwizzleK, {matchCopiedSwizzle0, matchCopiedSwizzle1}, {extractedbits});
383
384
385
386    Kernel * p2sK = pxDriver.addKernelInstance<P2SKernel>(iBuilder);
387    p2sK->addAttribute(MustConsumeAll());
388    pxDriver.makeKernelCall(p2sK, {extractedbits}, {DecompressedByteStream});
389
390/*
391    Kernel * outK = pxDriver.addKernelInstance<FileSink>(iBuilder, 8);
392    outK->setInitialArguments({iBuilder->GetString("/Users/wxy325/Desktop/c.txt")});
393    pxDriver.makeKernelCall(outK, {DecompressedByteStream}, {});
394*/
395
396//    StreamSetBuffer * const Extenders = pxDriver.addBuffer<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 1), this->get4MbBufferBlocks());
397
398
399//    Kernel * extenderK = pxDriver.addKernelInstance<ParabixCharacterClassKernelBuilder>(iBuilder, "extenders", std::vector<re::CC *>{re::makeCC(0xFF)}, 8);
400//    pxDriver.makeKernelCall(extenderK, {extractedbits}, {Extenders});
401
402    StreamSetBuffer * LineBreakStream;
403    StreamSetBuffer * Matches;
404    std::vector<re::RE*> res = {regex};
405    std::tie(LineBreakStream, Matches) = grepPipeline(res, extractedbits);
406
407    kernel::Kernel * scanMatchK = pxDriver.addKernelInstance<kernel::ScanMatchKernel>(iBuilder);
408    scanMatchK->setInitialArguments({match_accumulator});
409    pxDriver.makeKernelCall(scanMatchK, {Matches, LineBreakStream, DecompressedByteStream}, {});
410    pxDriver.LinkFunction(*scanMatchK, "accumulate_match_wrapper", &accumulate_match_wrapper);
411    pxDriver.LinkFunction(*scanMatchK, "finalize_match_wrapper", &finalize_match_wrapper);
412
413    pxDriver.generatePipelineIR();
414    pxDriver.deallocateBuffers();
415
416    iBuilder->CreateRetVoid();
417
418    pxDriver.finalizeObject();
419}
420
421void LZ4GrepGenerator::generateCountOnlyGrepPipeline(re::RE* regex) {
422    auto & iBuilder = pxDriver.getBuilder();
423    this->generateMainFunc(iBuilder);
424
425    // GeneratePipeline
426    this->generateLoadByteStreamAndBitStream(iBuilder);
427    this->generateExtractAndDepositMarkers(iBuilder);
428
429    auto swizzle = this->generateSwizzleExtractData(iBuilder);
430
431    StreamSetBuffer * depositedSwizzle0 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
432    StreamSetBuffer * depositedSwizzle1 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
433
434    Kernel * multiplePdepK = pxDriver.addKernelInstance<LZ4MultiplePDEPkernel>(iBuilder, 4, 2, 4);
435    pxDriver.makeKernelCall(multiplePdepK, {DepositMarker, swizzle.first, swizzle.second}, {depositedSwizzle0, depositedSwizzle1});
436
437
438    StreamSetBuffer * matchCopiedSwizzle0 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
439    StreamSetBuffer * matchCopiedSwizzle1 = pxDriver.addBuffer<SwizzledCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
440
441    Kernel * swizzledMatchCopyK = pxDriver.addKernelInstance<LZ4SwizzledMatchCopyKernel>(iBuilder, 4, 2, 4);
442    pxDriver.makeKernelCall(swizzledMatchCopyK, {MatchOffsetMarker, M0Marker, M0CountMarker, ByteStream, depositedSwizzle0, depositedSwizzle1}, {matchCopiedSwizzle0, matchCopiedSwizzle1});
443
444
445    // Produce unswizzled bit streams
446    StreamSetBuffer * extractedbits = pxDriver.addBuffer<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(8), this->getInputBufferBlocks());
447    Kernel * unSwizzleK = pxDriver.addKernelInstance<SwizzleGenerator>(iBuilder, 8, 1, 2);
448    pxDriver.makeKernelCall(unSwizzleK, {matchCopiedSwizzle0, matchCopiedSwizzle1}, {extractedbits});
449
450/*
451    Kernel * p2sK = pxDriver.addKernelInstance<P2SKernel>(iBuilder);
452    pxDriver.makeKernelCall(p2sK, {extractedbits}, {DecompressedByteStream});
453    Kernel * outK = pxDriver.addKernelInstance<FileSink>(iBuilder, 8);
454    outK->setInitialArguments({iBuilder->GetString("/Users/wxy325/Desktop/c.txt")});
455    pxDriver.makeKernelCall(outK, {DecompressedByteStream}, {});
456*/
457
458//    StreamSetBuffer * const Extenders = pxDriver.addBuffer<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 1), this->get4MbBufferBlocks());
459
460
461//    Kernel * extenderK = pxDriver.addKernelInstance<ParabixCharacterClassKernelBuilder>(iBuilder, "extenders", std::vector<re::CC *>{re::makeCC(0xFF)}, 8);
462//    pxDriver.makeKernelCall(extenderK, {extractedbits}, {Extenders});
463
464    StreamSetBuffer * LineBreakStream;
465    StreamSetBuffer * Matches;
466    std::vector<re::RE*> res = {regex};
467    std::tie(LineBreakStream, Matches) = grepPipeline(res, extractedbits);
468
469
470    kernel::Kernel * matchCountK = pxDriver.addKernelInstance<kernel::PopcountKernel>(iBuilder);
471    pxDriver.makeKernelCall(matchCountK, {Matches}, {});
472    pxDriver.generatePipelineIR();
473
474
475    iBuilder->setKernel(matchCountK);
476    Value * matchedLineCount = iBuilder->getAccumulator("countResult");
477    matchedLineCount = iBuilder->CreateZExt(matchedLineCount, iBuilder->getInt64Ty());
478    iBuilder->CallPrintInt("aaa", matchedLineCount);
479
480    pxDriver.deallocateBuffers();
481
482    // TODO return matchedLineCount
483//        idb->CreateRet(matchedLineCount);
484
485
486    iBuilder->CreateRetVoid();
487
488    pxDriver.finalizeObject();
489}
490
491ScanMatchGrepMainFunctionType LZ4GrepGenerator::getScanMatchGrepMainFunction() {
492    return reinterpret_cast<ScanMatchGrepMainFunctionType>(pxDriver.getMain());
493}
494
495void LZ4GrepGenerator::generateScanMatchMainFunc(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
496    Module * M = iBuilder->getModule();
497    Type * const sizeTy = iBuilder->getSizeTy();
498    Type * const boolTy = iBuilder->getIntNTy(sizeof(bool) * 8);
499    Type * const voidTy = iBuilder->getVoidTy();
500    Type * const inputType = iBuilder->getInt8PtrTy();
501    Type * const intAddrTy = iBuilder->getIntAddrTy();
502
503    Function * const main = cast<Function>(M->getOrInsertFunction("Main", voidTy, inputType, sizeTy, sizeTy, boolTy, intAddrTy, nullptr));
504    main->setCallingConv(CallingConv::C);
505    Function::arg_iterator args = main->arg_begin();
506    inputStream = &*(args++);
507    inputStream->setName("input");
508
509    headerSize = &*(args++);
510    headerSize->setName("headerSize");
511
512    fileSize = &*(args++);
513    fileSize->setName("fileSize");
514
515    hasBlockChecksum = &*(args++);
516    hasBlockChecksum->setName("hasBlockChecksum");
517
518    match_accumulator = &*(args++);
519    match_accumulator->setName("match_accumulator");
520
521    iBuilder->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", main, 0));
522}
Note: See TracBrowser for help on using the repository browser.