]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
dfa: only accel init states from smwr path
authorJustin Viiret <justin.viiret@intel.com>
Tue, 11 Apr 2017 00:56:22 +0000 (10:56 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Tue, 30 May 2017 03:57:32 +0000 (13:57 +1000)
If the small-write DFA has been built from literals, then we only need
to look for accel states at init.

src/nfa/accel_dfa_build_strat.cpp
src/nfa/accel_dfa_build_strat.h
src/nfa/goughcompile.cpp
src/nfa/mcclellancompile.cpp
src/nfa/mcclellancompile.h
src/nfa/mcsheng_compile.cpp
src/nfa/shengcompile.cpp
src/nfa/shengcompile.h
src/rose/rose_build_anchored.cpp
src/rose/rose_build_bytecode.cpp
src/smallwrite/smallwrite_build.cpp

index 019edc503cb42c84d9201819f373d00a7910b91f..7c56ba72366462d027ea6c58e8badae1ceaf2c2d 100644 (file)
@@ -541,17 +541,17 @@ accel_dfa_build_strat::getAccelInfo(const Grey &grey) {
     dstate_id_t sds_proxy = get_sds_or_proxy(rdfa);
     DEBUG_PRINTF("sds %hu\n", sds_proxy);
 
-    for (size_t i = 0; i < rdfa.states.size(); i++) {
+    /* Find accel info for a single state. */
+    auto do_state = [&](size_t i) {
         if (i == DEAD_STATE) {
-            continue;
+            return;
         }
 
         /* Note on report acceleration states: While we can't accelerate while
-         * we
-         * are spamming out callbacks, the QR code paths don't raise reports
+         * we are spamming out callbacks, the QR code paths don't raise reports
          * during scanning so they can accelerate report states. */
         if (generates_callbacks(rdfa.kind) && !rdfa.states[i].reports.empty()) {
-            continue;
+            return;
         }
 
         size_t single_limit =
@@ -562,15 +562,28 @@ accel_dfa_build_strat::getAccelInfo(const Grey &grey) {
         if (ei.cr.count() > single_limit) {
             DEBUG_PRINTF("state %zu is not accelerable has %zu\n", i,
                          ei.cr.count());
-            continue;
+            return;
         }
 
         DEBUG_PRINTF("state %zu should be accelerable %zu\n", i, ei.cr.count());
 
         rv[i] = ei;
+    };
+
+    if (only_accel_init) {
+        DEBUG_PRINTF("only computing accel for init states\n");
+        do_state(rdfa.start_anchored);
+        if (rdfa.start_floating != rdfa.start_anchored) {
+            do_state(rdfa.start_floating);
+        }
+    } else {
+        DEBUG_PRINTF("computing accel for all states\n");
+        for (size_t i = 0; i < rdfa.states.size(); i++) {
+            do_state(i);
+        }
     }
 
-    /* provide accleration states to states in the region of sds */
+    /* provide acceleration states to states in the region of sds */
     if (contains(rv, sds_proxy)) {
         AccelScheme sds_ei = rv[sds_proxy];
         sds_ei.double_byte.clear(); /* region based on single byte scheme
index 3cfaf272530a80224bfdecc14d0bc8426bd58f24..881892ed4db41923562d77d236dcffd0ab692fc9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, Intel Corporation
+ * Copyright (c) 2015-2017, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -43,8 +43,8 @@ struct Grey;
 
 class accel_dfa_build_strat : public dfa_build_strat {
 public:
-    explicit accel_dfa_build_strat(const ReportManager &rm_in)
-        : dfa_build_strat(rm_in) {}
+    accel_dfa_build_strat(const ReportManager &rm_in, bool only_accel_init_in)
+        : dfa_build_strat(rm_in), only_accel_init(only_accel_init_in) {}
     virtual AccelScheme find_escape_strings(dstate_id_t this_idx) const;
     virtual size_t accelSize(void) const = 0;
     virtual u32 max_allowed_offset_accel() const = 0;
@@ -53,6 +53,8 @@ public:
     virtual void buildAccel(dstate_id_t this_idx, const AccelScheme &info,
                             void *accel_out);
     virtual std::map<dstate_id_t, AccelScheme> getAccelInfo(const Grey &grey);
+private:
+    bool only_accel_init;
 };
 
 } // namespace ue2
index d92f285fcfba149ece99c0ca4548cac5e0e37d74..58b05d3d17d526f73a8ef58c18b8fbd357f3c102 100644 (file)
@@ -80,7 +80,7 @@ public:
     gough_build_strat(
         raw_som_dfa &r, const GoughGraph &g, const ReportManager &rm_in,
         const map<dstate_id_t, gough_accel_state_info> &accel_info)
-        : mcclellan_build_strat(r, rm_in), rdfa(r), gg(g),
+        : mcclellan_build_strat(r, rm_in, false), rdfa(r), gg(g),
           accel_gough_info(accel_info) {}
     unique_ptr<raw_report_info> gatherReports(vector<u32> &reports /* out */,
                             vector<u32> &reports_eod /* out */,
index 0aff6006faffc20f713ef38ba67131efbf7db3e1..781a72381f60d27561c1d13e96efb23d4c9a662a 100644 (file)
@@ -981,8 +981,9 @@ bytecode_ptr<NFA> mcclellanCompile_i(raw_dfa &raw, accel_dfa_build_strat &strat,
 
 bytecode_ptr<NFA> mcclellanCompile(raw_dfa &raw, const CompileContext &cc,
                                    const ReportManager &rm,
+                                   bool only_accel_init,
                                    set<dstate_id_t> *accel_states) {
-    mcclellan_build_strat mbs(raw, rm);
+    mcclellan_build_strat mbs(raw, rm, only_accel_init);
     return mcclellanCompile_i(raw, mbs, cc, accel_states);
 }
 
index be0a18c54c9c49af7cf3251d7666c08daf9becb1..c204e03cbe55e1dc44fd9430e087aa1ca73ef087 100644 (file)
@@ -48,8 +48,9 @@ struct CompileContext;
 
 class mcclellan_build_strat : public accel_dfa_build_strat {
 public:
-    mcclellan_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in)
-        : accel_dfa_build_strat(rm_in), rdfa(rdfa_in) {}
+    mcclellan_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in,
+                          bool only_accel_init_in)
+        : accel_dfa_build_strat(rm_in, only_accel_init_in), rdfa(rdfa_in) {}
     raw_dfa &get_raw() const override { return rdfa; }
     std::unique_ptr<raw_report_info> gatherReports(
                                   std::vector<u32> &reports /* out */,
@@ -69,7 +70,7 @@ private:
  * states */
 bytecode_ptr<NFA>
 mcclellanCompile(raw_dfa &raw, const CompileContext &cc,
-                 const ReportManager &rm,
+                 const ReportManager &rm, bool only_accel_init,
                  std::set<dstate_id_t> *accel_states = nullptr);
 
 /* used internally by mcclellan/haig/gough compile process */
index e4e4173a1216055be9e89f90acb01172e2414130..2d9658f2775e1ea3bbf88b3f994d146568ef591d 100644 (file)
@@ -1025,7 +1025,7 @@ bytecode_ptr<NFA> mcshengCompile(raw_dfa &raw, const CompileContext &cc,
         return nullptr;
     }
 
-    mcclellan_build_strat mbs(raw, rm);
+    mcclellan_build_strat mbs(raw, rm, false);
     dfa_info info(mbs);
     bool using8bit = cc.grey.allowMcClellan8 && info.size() <= 256;
 
index 8c061913ad68d394cff0f04088e29811ba856f2d..c4094cedc720968fecc0ed0c9e6dfb58431c807c 100644 (file)
@@ -451,14 +451,14 @@ bool has_accel_sheng(const NFA *) {
 }
 
 bytecode_ptr<NFA> shengCompile(raw_dfa &raw, const CompileContext &cc,
-                               const ReportManager &rm,
+                               const ReportManager &rm, bool only_accel_init,
                                set<dstate_id_t> *accel_states) {
     if (!cc.grey.allowSheng) {
         DEBUG_PRINTF("Sheng is not allowed!\n");
         return nullptr;
     }
 
-    sheng_build_strat strat(raw, rm);
+    sheng_build_strat strat(raw, rm, only_accel_init);
     dfa_info info(strat);
 
     DEBUG_PRINTF("Trying to compile a %zu state Sheng\n", raw.states.size());
index 6afc1dd19381a823d6bb1632c5477ccd3a6dfe42..9885cd16fc5e713b70c139484e9dc04288b946e5 100644 (file)
@@ -45,8 +45,9 @@ struct raw_dfa;
 
 class sheng_build_strat : public accel_dfa_build_strat {
 public:
-    sheng_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in)
-        : accel_dfa_build_strat(rm_in), rdfa(rdfa_in) {}
+    sheng_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in,
+                      bool only_accel_init_in)
+        : accel_dfa_build_strat(rm_in, only_accel_init_in), rdfa(rdfa_in) {}
     raw_dfa &get_raw() const override { return rdfa; }
     std::unique_ptr<raw_report_info> gatherReports(
                                   std::vector<u32> &reports /* out */,
@@ -63,7 +64,7 @@ private:
 };
 
 bytecode_ptr<NFA> shengCompile(raw_dfa &raw, const CompileContext &cc,
-                               const ReportManager &rm,
+                               const ReportManager &rm, bool only_accel_init,
                                std::set<dstate_id_t> *accel_states = nullptr);
 
 struct sheng_escape_info {
index 6d56ee007383fef2960a61ce4df294411d7548b7..a2af160e4908e079bc261c3a228a1639ce61bcac 100644 (file)
@@ -829,7 +829,7 @@ size_t buildNfas(vector<raw_dfa> &anchored_dfas,
 
         minimize_hopcroft(rdfa, cc.grey);
 
-        auto nfa = mcclellanCompile(rdfa, cc, rm);
+        auto nfa = mcclellanCompile(rdfa, cc, rm, false);
         if (!nfa) {
             assert(0);
             throw std::bad_alloc();
index e7b001268562fff24dd3d201e3278292228873c3..1155b50a43a3cd94ac9dfe551e8aca63578804c9 100644 (file)
@@ -720,7 +720,7 @@ bytecode_ptr<NFA> getDfa(raw_dfa &rdfa, bool is_transient,
                                const CompileContext &cc,
                                const ReportManager &rm) {
     // Unleash the Sheng!!
-    auto dfa = shengCompile(rdfa, cc, rm);
+    auto dfa = shengCompile(rdfa, cc, rm, false);
     if (!dfa && !is_transient) {
         // Sheng wasn't successful, so unleash McClellan!
         /* We don't try the hybrid for transient prefixes due to the extra
@@ -729,7 +729,7 @@ bytecode_ptr<NFA> getDfa(raw_dfa &rdfa, bool is_transient,
     }
     if (!dfa) {
         // Sheng wasn't successful, so unleash McClellan!
-        dfa = mcclellanCompile(rdfa, cc, rm);
+        dfa = mcclellanCompile(rdfa, cc, rm, false);
     }
     return dfa;
 }
index bcdd12bb2a3c0029fc2374c9cf66e80fc0e9b418..ffd3fe0f4577ba6141ec1f875b67ceb1863caf09 100644 (file)
@@ -692,14 +692,18 @@ bool is_slow(const raw_dfa &rdfa, const set<dstate_id_t> &accel,
 
 static
 bytecode_ptr<NFA> getDfa(raw_dfa &rdfa, const CompileContext &cc,
-                         const ReportManager &rm,
+                         const ReportManager &rm, bool has_literals,
                          set<dstate_id_t> &accel_states) {
+    // If we determinised literals, then we only need to consider the init
+    // states for acceleration.
+    bool only_accel_init = has_literals;
+
     bytecode_ptr<NFA> dfa = nullptr;
     if (cc.grey.allowSmallWriteSheng) {
-        dfa = shengCompile(rdfa, cc, rm, &accel_states);
+        dfa = shengCompile(rdfa, cc, rm, only_accel_init, &accel_states);
     }
     if (!dfa) {
-        dfa = mcclellanCompile(rdfa, cc, rm, &accel_states);
+        dfa = mcclellanCompile(rdfa, cc, rm, only_accel_init, &accel_states);
     }
     return dfa;
 }
@@ -707,13 +711,14 @@ bytecode_ptr<NFA> getDfa(raw_dfa &rdfa, const CompileContext &cc,
 static
 bytecode_ptr<NFA> prepEngine(raw_dfa &rdfa, u32 roseQuality,
                              const CompileContext &cc, const ReportManager &rm,
-                             u32 *start_offset, u32 *small_region) {
+                             bool has_literals, u32 *start_offset,
+                             u32 *small_region) {
     *start_offset = remove_leading_dots(rdfa);
 
     // Unleash the McClellan!
     set<dstate_id_t> accel_states;
 
-    auto nfa = getDfa(rdfa, cc, rm, accel_states);
+    auto nfa = getDfa(rdfa, cc, rm, has_literals, accel_states);
     if (!nfa) {
         DEBUG_PRINTF("DFA compile failed for smallwrite NFA\n");
         return nullptr;
@@ -732,7 +737,7 @@ bytecode_ptr<NFA> prepEngine(raw_dfa &rdfa, u32 roseQuality,
                 return nullptr;
             }
 
-            nfa = getDfa(rdfa, cc, rm, accel_states);
+            nfa = getDfa(rdfa, cc, rm, has_literals, accel_states);
             if (!nfa) {
                 DEBUG_PRINTF("DFA compile failed for smallwrite NFA\n");
                 assert(0); /* able to build orig dfa but not the trimmed? */
@@ -762,7 +767,8 @@ unique_ptr<SmallWriteBuild> makeSmallWriteBuilder(size_t num_patterns,
 }
 
 bytecode_ptr<SmallWriteEngine> SmallWriteBuildImpl::build(u32 roseQuality) {
-    if (!rdfa && is_empty(lit_trie) && is_empty(lit_trie_nocase)) {
+    const bool has_literals = !is_empty(lit_trie) || !is_empty(lit_trie_nocase);
+    if (!rdfa && !has_literals) {
         DEBUG_PRINTF("no smallwrite engine\n");
         poisoned = true;
         return nullptr;
@@ -782,8 +788,8 @@ bytecode_ptr<SmallWriteEngine> SmallWriteBuildImpl::build(u32 roseQuality) {
 
     u32 start_offset;
     u32 small_region;
-    auto nfa =
-        prepEngine(*rdfa, roseQuality, cc, rm, &start_offset, &small_region);
+    auto nfa = prepEngine(*rdfa, roseQuality, cc, rm, has_literals,
+                          &start_offset, &small_region);
     if (!nfa) {
         DEBUG_PRINTF("some smallwrite outfix could not be prepped\n");
         /* just skip the smallwrite optimization */