source: icGREP/icgrep-devel/icgrep/compiler.cpp @ 4611

Last change on this file since 4611 was 4594, checked in by nmedfort, 4 years ago

Added ability to infer mutual exclusivity / subset relationships based on already proven relationships. Simplifer can now eliminate If nodes whenever all of the defined vars are Zeroes.

File size: 8.4 KB
RevLine 
[3850]1/*
[4388]2 *  Copyright (c) 2015 International Characters.
[3850]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
[4237]7#include <compiler.h>
[4337]8#include <re/re_cc.h>
[4237]9#include <re/re_nullable.h>
10#include <re/re_simplifier.h>
[4328]11#include <re/re_alt.h>
[4237]12#include <re/parsefailure.h>
13#include <re/re_parser.h>
14#include <re/re_compiler.h>
15#include <utf8_encoder.h>
16#include <cc/cc_compiler.h>
[4249]17#include <cc/cc_namemap.hpp>
[4237]18#include <pablo/pablo_compiler.h>
[4416]19#include <pablo/optimizers/pablo_simplifier.hpp>
[4521]20#include <pablo/optimizers/pablo_codesinking.hpp>
[4583]21#ifdef ENABLE_MULTIPLEXING
22#include <pablo/optimizers/pablo_automultiplexing.hpp>
23#endif
[4385]24#include "UCD/precompiled_gc.h"
25#include "UCD/precompiled_sc.h"
[4386]26#include "UCD/precompiled_scx.h"
27#include "UCD/precompiled_blk.h"
[4388]28#include "UCD/precompiled_derivedcoreproperties.h"
[4392]29#include "UCD/precompiled_proplist.h"
[4383]30
[4380]31#include "resolve_properties.cpp"
32
[4348]33#include "llvm/Support/CommandLine.h"
[4227]34#include <re/printer_re.h>
35#include <pablo/printer_pablos.h>
[4197]36
[4348]37
[4353]38cl::OptionCategory cRegexOutputOptions("Regex Dump Options",
39                                      "These options control printing of intermediate regular expression structures.");
[4348]40
[4353]41cl::OptionCategory dPabloDumpOptions("Pablo Dump Options",
42                                      "These options control printing of intermediate Pablo code.");
43
44static cl::opt<bool> PrintAllREs("print-REs", cl::init(false), cl::desc("print regular expression passes"), cl::cat(cRegexOutputOptions));
45static cl::opt<bool> PrintParsedREs("print-parsed-REs", cl::init(false), cl::desc("print out parsed regular expressions"), cl::cat(cRegexOutputOptions));
46static cl::opt<bool> PrintStrippedREs("print-stripped-REs", cl::init(false), cl::desc("print out REs with nullable prefixes/suffixes removed"), cl::cat(cRegexOutputOptions));
47static cl::opt<bool> PrintNamedREs("print-named-REs", cl::init(false), cl::desc("print out named REs"), cl::cat(cRegexOutputOptions));
48static cl::opt<bool> PrintUTF8REs("print-utf8-REs", cl::init(false), cl::desc("print out UTF-8 REs"), cl::cat(cRegexOutputOptions));
49static cl::opt<bool> PrintSimplifiedREs("print-simplified-REs", cl::init(false), cl::desc("print out final simplified REs"), cl::cat(cRegexOutputOptions));
50static cl::opt<bool> PrintCompiledCCcode("print-CC-pablo", cl::init(false), cl::desc("print Pablo output from character class compiler"), cl::cat(dPabloDumpOptions));
51static cl::opt<bool> PrintCompiledREcode("print-RE-pablo", cl::init(false), cl::desc("print Pablo output from the regular expression compiler"), cl::cat(dPabloDumpOptions));
[4513]52static cl::opt<bool> PrintOptimizedREcode("print-pablo", cl::init(false), cl::desc("print final optimized Pablo code"), cl::cat(dPabloDumpOptions));
[4353]53
54
[4521]55cl::OptionCategory cPabloOptimizationsOptions("Pablo Optimizations",
[4523]56                                              "These options control Pablo optimization passes.");
[4521]57
[4523]58static cl::opt<bool> DisablePabloCSE("disable-CSE", cl::init(false),
59                                      cl::desc("Disable Pablo common subexpression elimination/dead code elimination"),
60                                      cl::cat(cPabloOptimizationsOptions));
[4521]61static cl::opt<bool> PabloSinkingPass("sinking", cl::init(false),
62                                      cl::desc("Moves all instructions into the innermost legal If-scope so that they are only executed when needed."),
63                                      cl::cat(cPabloOptimizationsOptions));
[4588]64#ifdef ENABLE_MULTIPLEXING
[4594]65static cl::opt<bool> PabloMutualExclusionPass("csme", cl::init(true),
[4592]66                                      cl::desc("Multiplex Advances whose inputs are mutual exclusive and replace any contradictory stream with Zero."),
[4588]67                                      cl::cat(cPabloOptimizationsOptions));
68#endif
[4521]69
[4197]70using namespace re;
[4198]71using namespace cc;
[4237]72using namespace pablo;
[4197]73
74namespace icgrep {
75
[4516]76CompiledPabloFunction compile(const Encoding encoding, const std::vector<std::string> regexps, const ModeFlagSet initialFlags) {
[4328]77    std::vector<RE *> REs;
[4197]78    RE * re_ast = nullptr;
[4328]79    for (int i = 0; i < regexps.size(); i++) {
80        try
81        {
[4412]82            re_ast = RE_Parser::parse(regexps[i], initialFlags);
[4328]83        }
84        catch (ParseFailure failure)
85        {
[4431]86            std::cerr << "Regex parsing failure: " << failure.what() << std::endl;
[4328]87            std::cerr << regexps[i] << std::endl;
88            exit(1);
89        }
90        REs.push_back(re_ast);
[4197]91    }
[4328]92    if (REs.size() > 1) {
93        re_ast = makeAlt(REs.begin(), REs.end());
[4197]94    }
[3850]95
[4348]96    if (PrintAllREs || PrintParsedREs) {
[4588]97        std::cerr << "Parser:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
[4348]98    }
[3850]99
[4246]100    //Optimization passes to simplify the AST.
101    re_ast = RE_Nullable::removeNullablePrefix(re_ast);
[4348]102    if (PrintAllREs || PrintStrippedREs) {
[4588]103        std::cerr << "RemoveNullablePrefix:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
[4348]104    }
[4246]105    re_ast = RE_Nullable::removeNullableSuffix(re_ast);
[4348]106    if (PrintAllREs || PrintStrippedREs) {
[4588]107        std::cerr << "RemoveNullableSuffix:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
[4348]108    }
109   
[4380]110    resolveProperties(re_ast);
111   
112   
[4249]113    CC_NameMap nameMap;
[4337]114    re_ast = nameMap.process(re_ast, UnicodeClass);
[3850]115
[4348]116    if (PrintAllREs || PrintNamedREs) {
[4588]117        std::cerr << "Namer:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
118        std::cerr << "NameMap:\n" << nameMap.printMap() << std::endl;
[4348]119    }
[4197]120
[4249]121    //Add the UTF encoding.
122    if (encoding.getType() == Encoding::Type::UTF_8) {
123        re_ast = UTF8_Encoder::toUTF8(nameMap, re_ast);
[4348]124        if (PrintAllREs || PrintUTF8REs) {
[4588]125            //Print to the terminal the AST that was generated by the utf8 encoder.
126            std::cerr << "UTF8-encoder:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
127            std::cerr << "NameMap:\n" << nameMap.printMap() << std::endl;
[4348]128        }
[4249]129    }
[4331]130   
[4197]131    re_ast = RE_Simplifier::simplify(re_ast);
[4348]132    if (PrintAllREs || PrintSimplifiedREs) {
133      //Print to the terminal the AST that was generated by the simplifier.
134      std::cerr << "Simplifier:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
135    }
[4197]136
[4510]137    SymbolGenerator symbolGenerator;
138    PabloBlock & main = PabloBlock::Create(symbolGenerator);
[4210]139
[4412]140    CC_Compiler cc_compiler(main, encoding);
[4337]141   
142    cc_compiler.compileByteClasses(re_ast);
143   
144    auto basisBits = cc_compiler.getBasisBits(nameMap);
[4513]145    if (PrintCompiledCCcode) {
[4348]146      //Print to the terminal the AST that was generated by the character class compiler.
[4567]147      llvm::raw_os_ostream cerr(std::cerr);
148      cerr << "CC AST:" << "\n";
149      PabloPrinter::print(main.statements(), cerr);
[4348]150    }
[4337]151   
[4438]152    RE_Compiler re_compiler(main);
[4334]153    re_compiler.initializeRequiredStreams(cc_compiler);
[4330]154    re_compiler.finalizeMatchResult(re_compiler.compile(re_ast));
[4588]155
[4513]156    if (PrintCompiledREcode) {
[4588]157        //Print to the terminal the AST that was generated by the pararallel bit-stream compiler.
158        llvm::raw_os_ostream cerr(std::cerr);
159        cerr << "Initial Pablo AST:\n";
160        PabloPrinter::print(main.statements(), cerr);
[4348]161    }
[4197]162
[4280]163    // Scan through the pablo code and perform DCE and CSE
[4523]164    if (!DisablePabloCSE) {
165        Simplifier::optimize(main);
166    }
[4521]167    if (PabloSinkingPass) {
168        CodeSinking::optimize(main);
169    }
[4583]170    #ifdef ENABLE_MULTIPLEXING
[4588]171    if (PabloMutualExclusionPass) {
[4594]172        if (AutoMultiplexing::optimize(basisBits, main) && !DisablePabloCSE) {
173            Simplifier::optimize(main);
174        }
[4588]175    }
[4583]176    #endif
[4513]177    if (PrintOptimizedREcode) {
[4348]178      //Print to the terminal the AST that was generated by the pararallel bit-stream compiler.
[4567]179      llvm::raw_os_ostream cerr(std::cerr);
180      cerr << "Final Pablo AST:\n";
181      PabloPrinter::print(main.statements(), cerr);
[4348]182    }
[4280]183
[4270]184    PabloCompiler pablo_compiler(basisBits);
[4383]185   
[4385]186    install_property_gc_fn_ptrs(pablo_compiler);
187    install_property_sc_fn_ptrs(pablo_compiler);
[4386]188    install_property_scx_fn_ptrs(pablo_compiler);
189    install_property_blk_fn_ptrs(pablo_compiler);
[4388]190    install_property_DerivedCoreProperties_fn_ptrs(pablo_compiler);
[4392]191    install_property_PropList_fn_ptrs(pablo_compiler);
[4197]192
[4522]193    try {
194        CompiledPabloFunction retVal = pablo_compiler.compile(main);
[4526]195        releaseSlabAllocatorMemory();
[4522]196        return retVal;
197    }
[4526]198    catch (std::runtime_error e) {
199        releaseSlabAllocatorMemory();
[4522]200        std::cerr << "Runtime error: " << e.what() << std::endl;
201        exit(1);
202    }
[4197]203}
204
205}
Note: See TracBrowser for help on using the repository browser.