source: icGREP/icgrep-devel/icgrep/icgrep.cpp

Last change on this file was 6229, checked in by nmedfort, 3 months ago

Potential stall fix for -include=7*

File size: 5.9 KB
Line 
1/*
2 *  Copyright (c) 2014-8 International Characters.
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
7#include <cstdio>
8#include <vector>
9#include <llvm/Support/CommandLine.h>
10#include <llvm/Support/ErrorHandling.h>
11#include <llvm/Support/PrettyStackTrace.h>
12#include <llvm/Support/Signals.h>
13#include <llvm/Support/ManagedStatic.h>
14#include <llvm/Support/raw_ostream.h>
15#include <re/re_alt.h>
16#include <re/re_seq.h>
17#include <re/re_start.h>
18#include <re/re_end.h>
19#include <re/parsers/parser.h>
20#include <re/re_utility.h>
21#include <grep/grep_engine.h>
22#include <grep_interface.h>
23#include <fstream>
24#include <string>
25#include <toolchain/toolchain.h>
26#include <re/re_toolchain.h>
27#include <pablo/pablo_toolchain.h>
28#include <boost/filesystem.hpp>
29#include <util/file_select.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <llvm/ADT/STLExtras.h> // for make_unique
33#include <toolchain/cpudriver.h>
34
35using namespace llvm;
36
37static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<regex> <input file ...>"), cl::OneOrMore);
38
39static cl::opt<bool> ByteMode("enable-byte-mode", cl::desc("Process regular expressions in byte mode"));
40
41static cl::opt<int> REsPerGroup("re-num", cl::desc("Number of regular expressions processed by each kernel."), cl::init(0));
42
43static re::ModeFlagSet globalFlags = re::MULTILINE_MODE_FLAG;
44
45std::vector<re::RE *> readExpressions() {
46
47    if (argv::FileFlag != "") {
48        std::ifstream regexFile(argv::FileFlag.c_str());
49        std::string r;
50        if (regexFile.is_open()) {
51            while (std::getline(regexFile, r)) {
52                argv::RegexpVector.push_back(r);
53            }
54            regexFile.close();
55        }
56    }
57
58    // if there are no regexes specified through -e or -f, the first positional argument
59    // must be a regex, not an input file.
60
61    if (argv::RegexpVector.size() == 0) {
62        argv::RegexpVector.push_back(inputFiles[0]);
63        inputFiles.erase(inputFiles.begin());
64    }
65    if (argv::IgnoreCaseFlag) {
66        globalFlags |= re::CASE_INSENSITIVE_MODE_FLAG;
67    }
68
69    std::vector<re::RE *> REs;
70    for (unsigned i = 0; i < argv::RegexpVector.size(); i++) {
71        re::RE * re_ast = re::RE_Parser::parse(argv::RegexpVector[i], globalFlags, argv::RegexpSyntax, ByteMode);
72        REs.push_back(re_ast);
73    }
74
75
76    // If there are multiple REs, combine them into groups.
77    // A separate kernel will be created for each group.
78    if (REs.size() > 1) {
79        codegen::SegmentPipelineParallel = true;
80        if (REsPerGroup == 0) {
81            // If no grouping factor is specified, we use a default formula.
82            REsPerGroup = (REs.size() + codegen::ThreadNum) / (codegen::ThreadNum + 1);
83        }
84        std::vector<re::RE *> groups;
85        auto start = REs.begin();
86        auto end = start + REsPerGroup;
87        while (end < REs.end()) {
88            groups.push_back(re::makeAlt(start, end));
89            start = end;
90            end += REsPerGroup;
91        }
92        if ((REs.end() - start) > 1) {
93            groups.push_back(re::makeAlt(start, REs.end()));
94        } else {
95            groups.push_back(*start);
96        }
97    REs.swap(groups);
98    }
99    for (re::RE *& re_ast : REs) {
100        assert (re_ast);
101        if (argv::WordRegexpFlag) {
102            re_ast = re::makeSeq({re::makeWordBoundary(), re_ast, re::makeWordBoundary()});
103        }
104        if (argv::LineRegexpFlag) {
105            re_ast = re::makeSeq({re::makeStart(), re_ast, re::makeEnd()});
106        }
107    }
108
109    return REs;
110}
111
112namespace fs = boost::filesystem;
113
114int main(int argc, char *argv[]) {
115
116    argv::InitializeCommandLineInterface(argc, argv);
117
118    auto REs = readExpressions();
119
120    const auto allFiles = argv::getFullFileList(inputFiles);
121    if (inputFiles.empty()) {
122        argv::UseStdIn = true;
123    } else if ((allFiles.size() > 1) && !argv::NoFilenameFlag) {
124        argv::WithFilenameFlag = true;
125    }
126
127    CPUDriver driver("icgrep");
128    std::unique_ptr<grep::GrepEngine> grep;
129    switch (argv::Mode) {
130        case argv::NormalMode:
131            grep = make_unique<grep::EmitMatchesEngine>(driver);
132            if (argv::MaxCountFlag) grep->setMaxCount(argv::MaxCountFlag);
133            if (argv::WithFilenameFlag) grep->showFileNames();
134            if (argv::LineNumberFlag) grep->showLineNumbers();
135            if (argv::InitialTabFlag) grep->setInitialTab();
136           break;
137        case argv::CountOnly:
138            grep = make_unique<grep::CountOnlyEngine>(driver);
139            if (argv::WithFilenameFlag) grep->showFileNames();
140            if (argv::MaxCountFlag) grep->setMaxCount(argv::MaxCountFlag);
141           break;
142        case argv::FilesWithMatch:
143        case argv::FilesWithoutMatch:
144            grep = make_unique<grep::MatchOnlyEngine>(driver, argv::Mode == argv::FilesWithMatch, argv::NullFlag);
145            break;
146        case argv::QuietMode:
147            grep = make_unique<grep::QuietModeEngine>(driver);
148            break;
149        default: llvm_unreachable("Invalid grep mode!");
150    }
151    if (argv::IgnoreCaseFlag) grep->setCaseInsensitive();
152    if (argv::InvertMatchFlag) grep->setInvertMatches();
153    if (argv::UnicodeLinesFlag) {
154        grep->setRecordBreak(grep::GrepRecordBreakKind::Unicode);
155    } else if (argv::NullDataFlag) {
156        grep->setRecordBreak(grep::GrepRecordBreakKind::Null);
157    } else {
158        grep->setRecordBreak(grep::GrepRecordBreakKind::LF);
159    }
160
161    grep->setStdinLabel(argv::LabelFlag);
162    if (argv::UseStdIn) grep->setGrepStdIn();
163    if (argv::NoMessagesFlag) grep->suppressFileMessages();
164    if (argv::MmapFlag) grep->setPreferMMap();
165    grep->setBinaryFilesOption(argv::BinaryFilesFlag);
166    grep->initREs(REs);
167    grep->grepCodeGen();
168    grep->initFileResult(allFiles); // unnecessary copy!
169    const bool matchFound = grep->searchAllFiles();
170
171    return matchFound ? argv::MatchFoundExitCode : argv::MatchNotFoundExitCode;
172}
Note: See TracBrowser for help on using the repository browser.