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

Last change on this file since 5998 was 5998, checked in by nmedfort, 12 months ago

Added temporary buffer functionality to the pipeline for single stream source buffers. Fixed memory leak from UCD::UnicodeBreakRE()

File size: 23.4 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_multiplex.h>
66#include <re/re_utility.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(re::makeUnicodeBreak());
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<CircularCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
366    StreamSetBuffer * depositedSwizzle1 = pxDriver.addBuffer<CircularCopybackBuffer>(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    StreamSetBuffer * matchCopiedSwizzle0 = pxDriver.addBuffer<CircularCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
372    StreamSetBuffer * matchCopiedSwizzle1 = pxDriver.addBuffer<CircularCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
373
374    Kernel * swizzledMatchCopyK = pxDriver.addKernelInstance<LZ4SwizzledMatchCopyKernel>(iBuilder, 4, 2, 4);
375    pxDriver.makeKernelCall(swizzledMatchCopyK, {MatchOffsetMarker, M0Marker, M0CountMarker, ByteStream, depositedSwizzle0, depositedSwizzle1}, {matchCopiedSwizzle0, matchCopiedSwizzle1});
376
377
378    // Produce unswizzled bit streams
379    StreamSetBuffer * extractedbits = pxDriver.addBuffer<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(8), this->getInputBufferBlocks());
380    Kernel * unSwizzleK = pxDriver.addKernelInstance<SwizzleGenerator>(iBuilder, 8, 1, 2);
381    pxDriver.makeKernelCall(unSwizzleK, {matchCopiedSwizzle0, matchCopiedSwizzle1}, {extractedbits});
382
383
384
385    Kernel * p2sK = pxDriver.addKernelInstance<P2SKernel>(iBuilder);
386    pxDriver.makeKernelCall(p2sK, {extractedbits}, {DecompressedByteStream});
387
388    StreamSetBuffer * LineBreakStream;
389    StreamSetBuffer * Matches;
390    std::vector<re::RE*> res = {regex};
391    std::tie(LineBreakStream, Matches) = grepPipeline(res, extractedbits);
392
393    kernel::Kernel * scanMatchK = pxDriver.addKernelInstance<kernel::ScanMatchKernel>(iBuilder);
394    scanMatchK->setInitialArguments({match_accumulator});
395    pxDriver.makeKernelCall(scanMatchK, {Matches, LineBreakStream, DecompressedByteStream}, {});
396    pxDriver.LinkFunction(*scanMatchK, "accumulate_match_wrapper", &accumulate_match_wrapper);
397    pxDriver.LinkFunction(*scanMatchK, "finalize_match_wrapper", &finalize_match_wrapper);
398
399    pxDriver.generatePipelineIR();
400    pxDriver.deallocateBuffers();
401
402    iBuilder->CreateRetVoid();
403
404    pxDriver.finalizeObject();
405}
406
407void LZ4GrepGenerator::generateCountOnlyGrepPipeline(re::RE* regex) {
408    auto & iBuilder = pxDriver.getBuilder();
409    this->generateMainFunc(iBuilder);
410
411
412    // GeneratePipeline
413    this->generateLoadByteStreamAndBitStream(iBuilder);
414    this->generateExtractAndDepositMarkers(iBuilder);
415
416    auto swizzle = this->generateSwizzleExtractData(iBuilder);
417
418    StreamSetBuffer * depositedSwizzle0 = pxDriver.addBuffer<CircularCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
419    StreamSetBuffer * depositedSwizzle1 = pxDriver.addBuffer<CircularCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
420
421    Kernel * multiplePdepK = pxDriver.addKernelInstance<LZ4MultiplePDEPkernel>(iBuilder, 4, 2, 4);
422    pxDriver.makeKernelCall(multiplePdepK, {DepositMarker, swizzle.first, swizzle.second}, {depositedSwizzle0, depositedSwizzle1});
423
424
425    StreamSetBuffer * matchCopiedSwizzle0 = pxDriver.addBuffer<CircularCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
426    StreamSetBuffer * matchCopiedSwizzle1 = pxDriver.addBuffer<CircularCopybackBuffer>(iBuilder, iBuilder->getStreamSetTy(4), this->getInputBufferBlocks(), 1);
427
428    Kernel * swizzledMatchCopyK = pxDriver.addKernelInstance<LZ4SwizzledMatchCopyKernel>(iBuilder, 4, 2, 4);
429    pxDriver.makeKernelCall(swizzledMatchCopyK, {MatchOffsetMarker, M0Marker, M0CountMarker, ByteStream, depositedSwizzle0, depositedSwizzle1}, {matchCopiedSwizzle0, matchCopiedSwizzle1});
430
431
432    // Produce unswizzled bit streams
433    StreamSetBuffer * extractedbits = pxDriver.addBuffer<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(8), this->getInputBufferBlocks());
434    Kernel * unSwizzleK = pxDriver.addKernelInstance<SwizzleGenerator>(iBuilder, 8, 1, 2);
435    pxDriver.makeKernelCall(unSwizzleK, {matchCopiedSwizzle0, matchCopiedSwizzle1}, {extractedbits});
436
437    StreamSetBuffer * LineBreakStream;
438    StreamSetBuffer * Matches;
439    std::vector<re::RE*> res = {regex};
440    std::tie(LineBreakStream, Matches) = grepPipeline(res, extractedbits);
441
442
443    kernel::Kernel * matchCountK = pxDriver.addKernelInstance<kernel::PopcountKernel>(iBuilder);
444    pxDriver.makeKernelCall(matchCountK, {Matches}, {});
445    pxDriver.generatePipelineIR();
446
447
448    iBuilder->setKernel(matchCountK);
449    Value * matchedLineCount = iBuilder->getAccumulator("countResult");
450    matchedLineCount = iBuilder->CreateZExt(matchedLineCount, iBuilder->getInt64Ty());
451    iBuilder->CallPrintInt("aaa", matchedLineCount);
452
453    pxDriver.deallocateBuffers();
454
455    // TODO return matchedLineCount
456//        idb->CreateRet(matchedLineCount);
457
458
459    iBuilder->CreateRetVoid();
460
461    pxDriver.finalizeObject();
462}
463
464ScanMatchGrepMainFunctionType LZ4GrepGenerator::getScanMatchGrepMainFunction() {
465    return reinterpret_cast<ScanMatchGrepMainFunctionType>(pxDriver.getMain());
466}
467
468void LZ4GrepGenerator::generateScanMatchMainFunc(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
469    Module * M = iBuilder->getModule();
470    Type * const sizeTy = iBuilder->getSizeTy();
471    Type * const boolTy = iBuilder->getIntNTy(sizeof(bool) * 8);
472    Type * const voidTy = iBuilder->getVoidTy();
473    Type * const inputType = iBuilder->getInt8PtrTy();
474    Type * const intAddrTy = iBuilder->getIntAddrTy();
475
476    Function * const main = cast<Function>(M->getOrInsertFunction("Main", voidTy, inputType, sizeTy, sizeTy, boolTy, intAddrTy, nullptr));
477    main->setCallingConv(CallingConv::C);
478    Function::arg_iterator args = main->arg_begin();
479    inputStream = &*(args++);
480    inputStream->setName("input");
481
482    headerSize = &*(args++);
483    headerSize->setName("headerSize");
484
485    fileSize = &*(args++);
486    fileSize->setName("fileSize");
487
488    hasBlockChecksum = &*(args++);
489    hasBlockChecksum->setName("hasBlockChecksum");
490
491    match_accumulator = &*(args++);
492    match_accumulator->setName("match_accumulator");
493
494    iBuilder->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", main, 0));
495}
Note: See TracBrowser for help on using the repository browser.