]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
eod: consolidate eod anchor programs
authorJustin Viiret <justin.viiret@intel.com>
Fri, 10 Jun 2016 00:09:15 +0000 (10:09 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Fri, 8 Jul 2016 00:54:07 +0000 (10:54 +1000)
src/rose/eod.c
src/rose/rose_build_bytecode.cpp

index 4961a728c704ab7b59158040a1b94c1902719e14..30b8db0ea6b07288ec8bf956fbc9b77e55926c00 100644 (file)
@@ -210,16 +210,6 @@ void roseEodExec_i(const struct RoseEngine *t, u64a offset,
         return;
     }
 
-    if (!t->eodIterProgramOffset && !t->ematcherOffset) {
-        DEBUG_PRINTF("no eod accepts\n");
-        return;
-    }
-
-    // Handle pending EOD reports.
-    if (roseEodRunIterator(t, offset, scratch) == MO_HALT_MATCHING) {
-        return;
-    }
-
     // Run the EOD anchored matcher if there is one.
     if (t->ematcherOffset) {
         assert(t->ematcherRegionSize);
index 904f8df9a30598a93f6b6ac5d3bca448bc1f49a1..1c8e8cd0d930f33673e86a5514f8e641fbea00a5 100644 (file)
@@ -4005,6 +4005,11 @@ pair<u32, u32> buildEodAnchorProgram(RoseBuildImpl &build, build_context &bc) {
         for (const auto &e : in_edges_range(v, g)) {
             RoseVertex u = source(e, g);
 
+            if (!build.isInETable(u)) {
+                DEBUG_PRINTF("pred %zu is not in etable\n", g[u].idx);
+                continue;
+            }
+
             if (canEagerlyReportAtEod(build, e)) {
                 DEBUG_PRINTF("already done report for vertex %zu\n", g[u].idx);
                 continue;
@@ -4034,6 +4039,57 @@ pair<u32, u32> buildEodAnchorProgram(RoseBuildImpl &build, build_context &bc) {
     return {writeProgram(bc, program), iter_offset};
 }
 
+static
+void addGeneralEodAnchorProgram(RoseBuildImpl &build, build_context &bc,
+                                vector<RoseInstruction> &program) {
+    const RoseGraph &g = build.g;
+
+    // pred state id -> list of programs
+    map<u32, vector<vector<RoseInstruction>>> predProgramLists;
+
+    for (auto v : vertices_range(g)) {
+        if (!g[v].eod_accept) {
+            continue;
+        }
+
+        DEBUG_PRINTF("vertex %zu (with %zu preds) fires on EOD\n", g[v].idx,
+                     in_degree(v, g));
+
+        for (const auto &e : in_edges_range(v, g)) {
+            RoseVertex u = source(e, g);
+
+            if (build.isInETable(u)) {
+                DEBUG_PRINTF("pred %zu is in etable\n", g[u].idx);
+                continue;
+            }
+
+            if (canEagerlyReportAtEod(build, e)) {
+                DEBUG_PRINTF("already done report for vertex %zu\n", g[u].idx);
+                continue;
+            }
+
+            assert(contains(bc.roleStateIndices, u));
+            u32 predStateIdx = bc.roleStateIndices.at(u);
+
+            auto program = makeEodAnchorProgram(build, bc, e);
+            predProgramLists[predStateIdx].push_back(program);
+        }
+    }
+
+    if (predProgramLists.empty()) {
+        DEBUG_PRINTF("no eod anchored roles\n");
+        return;
+    }
+
+    if (!program.empty()) {
+        assert(program.back().code() == ROSE_INSTR_END);
+        program.pop_back();
+    }
+    // TODO: don't force sparse iter, be more careful with generating
+    // CHECK_NOT_HANDLED.
+    addPredBlocks(bc, predProgramLists, program, true);
+}
+
 static
 u32 writeEodProgram(RoseBuildImpl &build, build_context &bc,
                     u32 eodNfaIterOffset) {
@@ -4076,6 +4132,8 @@ u32 writeEodProgram(RoseBuildImpl &build, build_context &bc,
         program = flattenProgram({program});
     }
 
+    addGeneralEodAnchorProgram(build, bc, program);
+
     if (program.empty()) {
         return 0;
     }