source: icGREP/icgrep-devel/icgrep/grep_engine.cpp @ 5679

Last change on this file since 5679 was 5679, checked in by cameron, 19 months ago

Refactoring progress: \N uses name property; delay resolution of recursive property expressions, property object regexp support

File size: 21.2 KB
RevLine 
[4324]1/*
[5476]2 *  Copyright (c) 2017 International Characters.
[4324]3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
[5234]7#include "grep_engine.h"
[5476]8#include "grep_interface.h"
[5267]9#include <llvm/IR/Module.h>
[5234]10#include <boost/filesystem.hpp>
[5206]11#include <UCD/resolve_properties.h>
[5585]12#include <kernels/charclasses.h>
[5142]13#include <kernels/cc_kernel.h>
[5404]14#include <kernels/grep_kernel.h>
[5357]15#include <kernels/linebreak_kernel.h>
[5338]16#include <kernels/streams_merge.h>
[5429]17#include <kernels/source_kernel.h>
[5234]18#include <kernels/s2p_kernel.h>
19#include <kernels/scanmatchgen.h>
20#include <kernels/streamset.h>
[5450]21#include <kernels/until_n.h>
[5436]22#include <kernels/kernel_builder.h>
[5087]23#include <pablo/pablo_kernel.h>
[5234]24#include <re/re_cc.h>
25#include <re/re_toolchain.h>
[5425]26#include <toolchain/toolchain.h>
[5585]27#include <re/re_name_resolve.h>   
28#include <re/re_collect_unicodesets.h>
29#include <re/re_multiplex.h>
[5464]30#include <toolchain/cpudriver.h>
31#include <toolchain/NVPTXDriver.h>
[5234]32#include <iostream>
[4324]33#include <sstream>
[5369]34#include <cc/multiplex_CCs.h>
[5377]35#include <llvm/Support/raw_ostream.h>
[5418]36#include <util/aligned_allocator.h>
[5386]37#include <sys/stat.h>
[5418]38#include <fcntl.h>
[5484]39#include <errno.h>
40#include <mutex>
[5458]41#ifdef CUDA_ENABLED
42#include <preprocess.cpp>
43#include <IR_Gen/CudaDriver.h>
44#endif
[5377]45
[5241]46using namespace parabix;
[5267]47using namespace llvm;
[5241]48
[5473]49namespace grep {
50
[5484]51static std::stringstream * resultStrs = nullptr;
52static std::vector<std::string> inputFiles;
53static std::vector<std::string> linePrefix;
54static bool grepMatchFound;
[5473]55
[5458]56size_t * startPoints = nullptr;
57size_t * accumBytes = nullptr;
58
[5473]59
[5484]60std::mutex count_mutex;
61size_t fileCount;
62
63// DoGrep thread function.
64void *DoGrepThreadFunction(void *args)
65{
66    size_t fileIdx;
67    grep::GrepEngine * grepEngine = (grep::GrepEngine *)args;
68
69    count_mutex.lock();
70    fileIdx = fileCount;
71    fileCount++;
72    count_mutex.unlock();
73
74    while (fileIdx < inputFiles.size()) {
75        size_t grepResult = grepEngine->doGrep(inputFiles[fileIdx], fileIdx);
76       
77        count_mutex.lock();
78        if (grepResult > 0) grepMatchFound = true;
79        fileIdx = fileCount;
80        fileCount++;
81        count_mutex.unlock();
82        if (QuietMode && grepMatchFound) pthread_exit(nullptr);
83    }
84
85    pthread_exit(nullptr);
86}
87
[5574]88bool matchesNeedToBeMovedToEOL() {
[5548]89    if ((Mode == QuietMode) | (Mode == FilesWithMatch) | (Mode == FilesWithoutMatch)) {
90        return false;
91    }
92    else if (LineRegexpFlag) {
93        return false;
94    }
95    // TODO: return false for other cases based on regexp analysis, e.g., regexp ends with $.
96    return true;
97}
98   
[5550]99void GrepEngine::doGrep(const std::string & fileName, std::string & PTXFilename) const{
[5458]100#ifdef CUDA_ENABLED
101    const bool CountOnly = true;
102    boost::filesystem::path file(fileName);
103    if (exists(file)) {
104        if (is_directory(file)) {
105            return;
106        }
107    } else {
[5478]108        if (!NoMessagesFlag) {
[5458]109            std::cerr << "Error: cannot open " << fileName << " for processing. Skipped.\n";
110            return;
111        }
112    }
113
114    const auto fileSize = file_size(file);
115   
116    if (fileSize > 0) {
117        try {
118            boost::iostreams::mapped_file_source source(fileName, fileSize, 0);
119            char * fileBuffer = const_cast<char *>(source.data());
120           
121            codegen::BlockSize = 128;
122            std::vector<size_t> LFPositions = preprocess(fileBuffer, fileSize);
123           
124            const unsigned numOfGroups = codegen::GroupNum;
125            if (posix_memalign((void**)&startPoints, 8, (numOfGroups+1)*sizeof(size_t)) ||
126                posix_memalign((void**)&accumBytes, 8, (numOfGroups+1)*sizeof(size_t))) {
127                std::cerr << "Cannot allocate memory for startPoints or accumBytes.\n";
128                exit(-1);
129            }
[5550]130            if(PTXFilename=="")
131                PTXFilename = mGrepDriver->getBuilder()->getModule()->getModuleIdentifier() + ".ptx";
[5486]132            RunPTX(PTXFilename, fileBuffer, fileSize, CountOnly, LFPositions, startPoints, accumBytes);
[5458]133            source.close();
134        } catch (std::exception & e) {
[5478]135            if (!NoMessagesFlag) {
[5458]136                std::cerr << "Boost mmap error: " + fileName + ": " + e.what() + " Skipped.\n";
137                return;
138            }
139        }
140    } else {
141        std::cout << 0 << std::endl;
142    }
143#endif
144}
145
[5419]146uint64_t GrepEngine::doGrep(const std::string & fileName, const uint32_t fileIdx) const {
[5484]147    struct stat sb;
[5419]148    const int32_t fd = open(fileName.c_str(), O_RDONLY);
[5418]149    if (LLVM_UNLIKELY(fd == -1)) {
[5484]150        if (!NoMessagesFlag  && !(Mode == QuietMode)) {
151            if (errno == EACCES) {
152                resultStrs[fileIdx] << "icgrep: " << fileName << ": Permission denied.\n";
153            }
154            else if (errno == ENOENT) {
155                resultStrs[fileIdx] << "icgrep: " << fileName << ": No such file.\n";
156            }
157            else {
158                resultStrs[fileIdx] << "icgrep: " << fileName << ": Failed.\n";
159            }
160        }
[5418]161        return 0;
[4788]162    }
[5484]163    if (stat(fileName.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
164        if (!NoMessagesFlag  && !(Mode == QuietMode)) {
165            resultStrs[fileIdx] << "icgrep: " << fileName << ": Is a directory.\n";
166        }
167        close(fd);
168        return 0;
169    }
[5418]170    const auto result = doGrep(fd, fileIdx);
171    close(fd);
172    return result;
[4949]173}
174
[5419]175uint64_t GrepEngine::doGrep(const int32_t fileDescriptor, const uint32_t fileIdx) const {
[5474]176    assert (mGrepDriver);
[5419]177    typedef uint64_t (*GrepFunctionType)(int32_t fileDescriptor, const uint32_t fileIdx);
[5474]178    auto f = reinterpret_cast<GrepFunctionType>(mGrepDriver->getMain());
[5484]179   
180    uint64_t grepResult = f(fileDescriptor, fileIdx);
181    if (grepResult > 0) grepMatchFound = true;
182    else if ((Mode == NormalMode) && !resultStrs[fileIdx].str().empty()) grepMatchFound = true;
183   
184    if (Mode == CountOnly) {
185        resultStrs[fileIdx] << linePrefix[fileIdx] << grepResult << "\n";
186    }
187    else if (Mode == FilesWithMatch || Mode == FilesWithoutMatch ) {
188        size_t requiredCount = Mode == FilesWithMatch ? 1 : 0;
189        if (grepResult == requiredCount) {
190            resultStrs[fileIdx] << linePrefix[fileIdx];
191        }
192    }
193    else if (Mode == QuietMode) {
194        if (grepMatchFound) exit(MatchFoundExitCode);
195    }
196    return grepResult;
[5377]197}
[5314]198
[5398]199void initFileResult(std::vector<std::string> filenames){
[5484]200    grepMatchFound = false;
[5398]201    const int n = filenames.size();
[5483]202    linePrefix.resize(n);
[5476]203    if ((n > 1) && !NoFilenameFlag) {
204        WithFilenameFlag = true;
[5398]205    }
[5484]206    std::string fileSuffix = "";
207    bool setLinePrefix = WithFilenameFlag || (Mode == FilesWithMatch) || (Mode == FilesWithoutMatch);
208    if (setLinePrefix) {
[5483]209        if (NullFlag) {
210            fileSuffix = std::string("\0", 1);
211        }
212        else if ((Mode == NormalMode) && InitialTabFlag && !(LineNumberFlag || ByteOffsetFlag)) {
213            fileSuffix = "\t:";
214        }
[5485]215        else if ((Mode == NormalMode) || (Mode == CountOnly)) {
[5483]216            fileSuffix = ":";
217        }
[5484]218        else if ((Mode == FilesWithMatch) || (Mode == FilesWithoutMatch)) {
219            fileSuffix = "\n";
220        }
[5483]221    }
[5398]222    inputFiles = filenames;
223    resultStrs = new std::stringstream[n];
[5483]224    for (unsigned i = 0; i < inputFiles.size(); ++i) {
[5484]225        if (setLinePrefix) {
[5483]226            if (inputFiles[i] == "-") {
227                linePrefix[i] = LabelFlag + fileSuffix;
228            }
229            else {
230                linePrefix[i] = inputFiles[i] + fileSuffix;
231            }
232        }
[5398]233    }
234}
[5338]235
[5398]236template<typename CodeUnit>
237void wrapped_report_match(const size_t lineNum, size_t line_start, size_t line_end, const CodeUnit * const buffer, const size_t filesize, const size_t fileIdx) {
[5418]238
239//    errs().write_hex((size_t)buffer) << " : " << lineNum << " (" << line_start << ", " << line_end << ", " << filesize << ")\n";
240
[5398]241    assert (buffer);
242    assert (line_start <= line_end);
243    assert (line_end <= filesize);
[5338]244
[5476]245    if (WithFilenameFlag) {
[5483]246        resultStrs[fileIdx] << linePrefix[fileIdx];
[5398]247    }
[5476]248    if (LineNumberFlag) {
[5450]249        // Internally line numbers are counted from 0.  For display, adjust
250        // the line number so that lines are numbered from 1.
[5483]251        if (InitialTabFlag) {
252            resultStrs[fileIdx] << lineNum+1 << "\t:";
253        }
254        else {
255            resultStrs[fileIdx] << lineNum+1 << ":";
256        }
[5398]257    }
[5338]258
[5398]259    // If the line "starts" on the LF of a CRLF, it is actually the end of the last line.
260    if ((buffer[line_start] == 0xA) && (line_start != line_end)) {
261        ++line_start;
[5338]262    }
[5343]263
[5398]264    if (LLVM_UNLIKELY(line_end == filesize)) {
265        // The match position is at end-of-file.   We have a final unterminated line.
266        resultStrs[fileIdx].write((char *)&buffer[line_start], (line_end - line_start) * sizeof(CodeUnit));
[5476]267        if (NormalizeLineBreaksFlag) {
[5398]268            resultStrs[fileIdx] << '\n';  // terminate it
269        }
[5361]270    } else {
[5398]271        const auto end_byte = buffer[line_end];
[5476]272        if (grep::NormalizeLineBreaksFlag) {
[5398]273            if (LLVM_UNLIKELY(end_byte == 0x85)) {
274                // Line terminated with NEL, on the second byte.  Back up 1.
275                line_end -= 1;
276            } else if (LLVM_UNLIKELY(end_byte > 0xD)) {
277                // Line terminated with PS or LS, on the third byte.  Back up 2.
278                line_end -= 2;
279            }
280            resultStrs[fileIdx].write((char *)&buffer[line_start], (line_end - line_start) * sizeof(CodeUnit));
281            resultStrs[fileIdx] << '\n';
282        } else {
283            if (end_byte == 0x0D) {
284                // Check for line_end on first byte of CRLF; we don't want to access past the end of buffer.
285                if ((line_end + 1) < filesize) {
286                    if (buffer[line_end + 1] == 0x0A) {
287                        // Found CRLF; preserve both bytes.
288                        ++line_end;
289                    }
290                }
291            }
292            resultStrs[fileIdx].write((char *)&buffer[line_start], (line_end - line_start + 1) * sizeof(CodeUnit));
293        }
[5343]294    }
[5398]295}
[5338]296
[5484]297void PrintResults(){
298   
299    for (unsigned i = 0; i < inputFiles.size(); ++i){
300        std::cout << resultStrs[i].str();
[5473]301    }
[5484]302    exit(grepMatchFound ? MatchFoundExitCode : MatchNotFoundExitCode);
[5398]303}
[5338]304
[5574]305   
[5620]306std::pair<StreamSetBuffer *, StreamSetBuffer *> grepPipeline(Driver * grepDriver, std::vector<re::RE *> & REs, const GrepModeType grepMode, unsigned encodingBits, StreamSetBuffer * ByteStream) {
[5574]307    auto & idb = grepDriver->getBuilder();
308    const unsigned segmentSize = codegen::SegmentSize;
309    const unsigned bufferSegments = codegen::BufferSegments * codegen::ThreadNum;
310    size_t MatchLimit = ((grepMode == QuietMode) | (grepMode == FilesWithMatch) | (grepMode == FilesWithoutMatch)) ? 1 : MaxCountFlag;
311   
312
313    StreamSetBuffer * BasisBits = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(encodingBits, 1), segmentSize * bufferSegments));
314    kernel::Kernel * s2pk = grepDriver->addKernelInstance(make_unique<kernel::S2PKernel>(idb));
315    grepDriver->makeKernelCall(s2pk, {ByteStream}, {BasisBits});
316   
317    StreamSetBuffer * LineBreakStream = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), segmentSize * bufferSegments));
318    kernel::Kernel * linebreakK = grepDriver->addKernelInstance(make_unique<kernel::LineBreakKernelBuilder>(idb, encodingBits));
319    grepDriver->makeKernelCall(linebreakK, {BasisBits}, {LineBreakStream});
320   
321    kernel::Kernel * requiredStreamsK = grepDriver->addKernelInstance(make_unique<kernel::RequiredStreams_UTF8>(idb));
322    StreamSetBuffer * RequiredStreams = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(4, 1), segmentSize * bufferSegments));
323    grepDriver->makeKernelCall(requiredStreamsK, {BasisBits}, {RequiredStreams});
324   
325    const auto n = REs.size();
326   
[5646]327    std::vector<std::vector<UCD::UnicodeSet>> charclasses(n);
[5585]328
329    for (unsigned i = 0; i < n; i++) {
[5646]330        REs[i] = re::resolveNames(REs[i]);
[5631]331        std::vector<UCD::UnicodeSet> UnicodeSets = re::collect_UnicodeSets(REs[i]);
[5585]332        std::vector<std::vector<unsigned>> exclusiveSetIDs;
[5646]333        doMultiplexCCs(UnicodeSets, exclusiveSetIDs, charclasses[i]);
[5620]334        REs[i] = multiplex(REs[i], UnicodeSets, exclusiveSetIDs);
[5585]335    } 
336
[5574]337    std::vector<StreamSetBuffer *> MatchResultsBufs(n);
[5585]338
[5574]339    for(unsigned i = 0; i < n; ++i){
[5620]340        const auto numOfCharacterClasses = charclasses[i].size();
341        StreamSetBuffer * CharClasses = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(numOfCharacterClasses), segmentSize * bufferSegments));
342        kernel::Kernel * ccK = grepDriver->addKernelInstance(make_unique<kernel::CharClassesKernel>(idb, std::move(charclasses[i])));
[5585]343        grepDriver->makeKernelCall(ccK, {BasisBits}, {CharClasses});
[5574]344        StreamSetBuffer * MatchResults = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), segmentSize * bufferSegments));
[5646]345        kernel::Kernel * icgrepK = grepDriver->addKernelInstance(make_unique<kernel::ICGrepKernel>(idb, REs[i], numOfCharacterClasses));
[5585]346        grepDriver->makeKernelCall(icgrepK, {CharClasses, LineBreakStream, RequiredStreams}, {MatchResults});
[5574]347        MatchResultsBufs[i] = MatchResults;
348    }
349    StreamSetBuffer * MergedResults = MatchResultsBufs[0];
350    if (REs.size() > 1) {
351        MergedResults = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), segmentSize * bufferSegments));
352        kernel::Kernel * streamsMergeK = grepDriver->addKernelInstance(make_unique<kernel::StreamsMerge>(idb, 1, REs.size()));
353        grepDriver->makeKernelCall(streamsMergeK, MatchResultsBufs, {MergedResults});
354    }
355    StreamSetBuffer * Matches = MergedResults;
356   
357    if (matchesNeedToBeMovedToEOL()) {
358        StreamSetBuffer * OriginalMatches = Matches;
359        kernel::Kernel * matchedLinesK = grepDriver->addKernelInstance(make_unique<kernel::MatchedLinesKernel>(idb));
360        Matches = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), segmentSize * bufferSegments));
361        grepDriver->makeKernelCall(matchedLinesK, {OriginalMatches, LineBreakStream}, {Matches});
362    }
363   
364    if (InvertMatchFlag) {
365        kernel::Kernel * invertK = grepDriver->addKernelInstance(make_unique<kernel::InvertMatchesKernel>(idb));
366        StreamSetBuffer * OriginalMatches = Matches;
367        Matches = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), segmentSize * bufferSegments));
368        grepDriver->makeKernelCall(invertK, {OriginalMatches, LineBreakStream}, {Matches});
369    }
370    if (MatchLimit > 0) {
371        kernel::Kernel * untilK = grepDriver->addKernelInstance(make_unique<kernel::UntilNkernel>(idb));
372        untilK->setInitialArguments({idb->getSize(MatchLimit)});
373        StreamSetBuffer * AllMatches = Matches;
374        Matches = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), segmentSize * bufferSegments));
375        grepDriver->makeKernelCall(untilK, {AllMatches}, {Matches});
376    }
377    return std::pair<StreamSetBuffer *, StreamSetBuffer *>(LineBreakStream, Matches);
378}
379
380
381   
[5473]382void GrepEngine::grepCodeGen_nvptx(std::vector<re::RE *> REs, const GrepModeType grepMode, const bool UTF_16) {
[5458]383
[5474]384    assert (mGrepDriver == nullptr);
385
386    mGrepDriver = new NVPTXDriver("engine");
387    auto & idb = mGrepDriver->getBuilder();
[5458]388    Module * M = idb->getModule();
389
390    const unsigned segmentSize = codegen::SegmentSize;
391    const unsigned encodingBits = UTF_16 ? 16 : 8;
392
393    Type * const int64Ty = idb->getInt64Ty();
394    Type * const int32Ty = idb->getInt32Ty();
395    Type * const size_ty = idb->getSizeTy();
396    Type * const sizeTyPtr = PointerType::get(size_ty, 1);
397    Type * const int64tyPtr = PointerType::get(int64Ty, 1);
398    Type * const voidTy = idb->getVoidTy();
[5548]399   
[5458]400    Function * mainFunc = cast<Function>(M->getOrInsertFunction("Main", voidTy, int64tyPtr, sizeTyPtr, sizeTyPtr, int64tyPtr, nullptr));
401    mainFunc->setCallingConv(CallingConv::C);
402    idb->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", mainFunc, 0));
403    auto args = mainFunc->arg_begin();
404
405    Value * const inputPtr = &*(args++);
406    inputPtr->setName("inputPtr");
407    Value * const startPointsPtr = &*(args++);
408    startPointsPtr->setName("startPointsPtr");
409    Value * const bufferSizesPtr = &*(args++);
410    bufferSizesPtr->setName("bufferSizesPtr");
411    Value * const outputPtr = &*(args++);
412    outputPtr->setName("outputPtr");
413
414    Function * tidFunc = M->getFunction("llvm.nvvm.read.ptx.sreg.tid.x");
415    Value * tid = idb->CreateCall(tidFunc);
416    Function * bidFunc = cast<Function>(M->getOrInsertFunction("llvm.nvvm.read.ptx.sreg.ctaid.x", int32Ty, nullptr));
417    Value * bid = idb->CreateCall(bidFunc);
418
419    Value * startPoint = idb->CreateLoad(idb->CreateGEP(startPointsPtr, bid));
420    Value * startBlock = idb->CreateUDiv(startPoint, ConstantInt::get(int64Ty, idb->getBitBlockWidth()));
421    Type * const inputStreamType = PointerType::get(ArrayType::get(ArrayType::get(idb->getBitBlockType(), 8), 1), 1);   
422    Value * inputStreamPtr = idb->CreateGEP(idb->CreateBitCast(inputPtr, inputStreamType), startBlock);
423    Value * inputStream = idb->CreateGEP(inputStreamPtr, tid);
424    Value * bufferSize = idb->CreateLoad(idb->CreateGEP(bufferSizesPtr, bid));
425
[5474]426    StreamSetBuffer * ByteStream = mGrepDriver->addBuffer(make_unique<SourceBuffer>(idb, idb->getStreamSetTy(1, 8), 1));
427    kernel::Kernel * sourceK = mGrepDriver->addKernelInstance(make_unique<kernel::MemorySourceKernel>(idb, inputStreamType, segmentSize));
[5458]428    sourceK->setInitialArguments({inputStream, bufferSize});
[5474]429    mGrepDriver->makeKernelCall(sourceK, {}, {ByteStream});
[5458]430
[5574]431    StreamSetBuffer * Matches = std::get<1>(grepPipeline(mGrepDriver, REs, grepMode, encodingBits, ByteStream));
[5458]432   
[5491]433    kernel::Kernel * matchCountK = mGrepDriver->addKernelInstance(make_unique<kernel::PopcountKernel>(idb));
[5548]434    mGrepDriver->makeKernelCall(matchCountK, {Matches}, {});
[5474]435    mGrepDriver->generatePipelineIR();
[5491]436    idb->setKernel(matchCountK);
437    Value * matchedLineCount = idb->getAccumulator("countResult");
[5458]438    matchedLineCount = idb->CreateZExt(matchedLineCount, int64Ty);
439   
440    Value * strideBlocks = ConstantInt::get(int32Ty, idb->getStride() / idb->getBitBlockWidth());
441    Value * outputThreadPtr = idb->CreateGEP(outputPtr, idb->CreateAdd(idb->CreateMul(bid, strideBlocks), tid));
442    idb->CreateStore(matchedLineCount, outputThreadPtr);
[5597]443    mGrepDriver->deallocateBuffers();
[5458]444    idb->CreateRetVoid();
445
[5474]446    mGrepDriver->finalizeObject();
[5458]447}
448
[5481]449void GrepEngine::grepCodeGen(std::vector<re::RE *> REs, const GrepModeType grepMode, const bool UTF_16, GrepSource grepSource) {
[5401]450
[5474]451    assert (mGrepDriver == nullptr);
452    mGrepDriver = new ParabixDriver("engine");
453    auto & idb = mGrepDriver->getBuilder();
[5425]454    Module * M = idb->getModule();
[5151]455
[5135]456    const unsigned segmentSize = codegen::SegmentSize;
[5246]457    const unsigned encodingBits = UTF_16 ? 16 : 8;
[5033]458
[5425]459    Type * const int64Ty = idb->getInt64Ty();
460    Type * const int32Ty = idb->getInt32Ty();
[5151]461
[5435]462    kernel::Kernel * sourceK = nullptr;
[5473]463   
[5482]464    Function * mainFunc = cast<Function>(M->getOrInsertFunction("Main", int64Ty, idb->getInt32Ty(), int32Ty, nullptr));
465    mainFunc->setCallingConv(CallingConv::C);
466    idb->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", mainFunc, 0));
467    auto args = mainFunc->arg_begin();
[5398]468
[5482]469    Value * const fileDescriptor = &*(args++);
470    fileDescriptor->setName("fileDescriptor");
471    Value * fileIdx = &*(args++);
472    fileIdx->setName("fileIdx");
[5398]473
[5482]474    StreamSetBuffer * ByteStream = mGrepDriver->addBuffer(make_unique<SourceBuffer>(idb, idb->getStreamSetTy(1, 8)));
[5419]475
[5482]476    if (grepSource == GrepSource::File) {
477        sourceK = mGrepDriver->addKernelInstance(make_unique<kernel::MMapSourceKernel>(idb, segmentSize));
[5489]478    } else {
[5482]479        sourceK = mGrepDriver->addKernelInstance(make_unique<kernel::ReadSourceKernel>(idb, segmentSize));
[5135]480    }
[5489]481    sourceK->setInitialArguments({fileDescriptor});
[5151]482
[5474]483    mGrepDriver->makeKernelCall(sourceK, {}, {ByteStream});
[5416]484   
[5574]485    StreamSetBuffer * LineBreakStream;
486    StreamSetBuffer * Matches;
487    std::tie(LineBreakStream, Matches) = grepPipeline(mGrepDriver, REs, grepMode, encodingBits, ByteStream);
[5416]488   
[5482]489    if (grepMode == NormalMode) {
[5481]490        kernel::Kernel * scanMatchK = mGrepDriver->addKernelInstance(make_unique<kernel::ScanMatchKernel>(idb, GrepType::Normal, encodingBits));
[5474]491        scanMatchK->setInitialArguments({fileIdx});
[5548]492        mGrepDriver->makeKernelCall(scanMatchK, {Matches, LineBreakStream, ByteStream}, {});
[5481]493        if (UTF_16) {
494            mGrepDriver->LinkFunction(*scanMatchK, "matcher", &wrapped_report_match<uint16_t>);
495        } else {
496            mGrepDriver->LinkFunction(*scanMatchK, "matcher", &wrapped_report_match<uint8_t>);
[5425]497        }
[5474]498        mGrepDriver->generatePipelineIR();
[5548]499        mGrepDriver->deallocateBuffers();
500
[5425]501        idb->CreateRet(idb->getInt64(0));
[5482]502    } else {
[5491]503        kernel::Kernel * matchCountK = mGrepDriver->addKernelInstance(make_unique<kernel::PopcountKernel>(idb));
[5548]504        mGrepDriver->makeKernelCall(matchCountK, {Matches}, {});
[5482]505        mGrepDriver->generatePipelineIR();
506        idb->setKernel(matchCountK);
[5491]507        Value * matchedLineCount = idb->getAccumulator("countResult");
[5482]508        matchedLineCount = idb->CreateZExt(matchedLineCount, int64Ty);
[5548]509        mGrepDriver->deallocateBuffers();
[5482]510        idb->CreateRet(matchedLineCount);
[5398]511    }
[5474]512    mGrepDriver->finalizeObject();
[5135]513}
514
[5481]515GrepEngine::GrepEngine()
516: mGrepDriver(nullptr) {
517
[4946]518}
[4968]519
[5481]520GrepEngine::~GrepEngine() {
521    delete mGrepDriver;
522}
523
524}
Note: See TracBrowser for help on using the repository browser.