]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
rose_program: merge RECORD_ANCHORED instruction into ANCHORED_DELAY
authorAlex Coyte <a.coyte@intel.com>
Tue, 25 Apr 2017 23:31:04 +0000 (09:31 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Tue, 30 May 2017 03:58:32 +0000 (13:58 +1000)
src/rose/program_runtime.h
src/rose/rose_build_bytecode.cpp
src/rose/rose_build_dump.cpp
src/rose/rose_build_program.cpp
src/rose/rose_build_program.h
src/rose/rose_program.h

index 090913ae6fa341c34a294cd3d08a2e92c103d898..dac8345ea6cad86b5059df824c4940e7c7b34970 100644 (file)
@@ -1892,6 +1892,8 @@ hwlmcb_rv_t roseRunProgram_i(const struct RoseEngine *t,
                     DEBUG_PRINTF("delay until playback\n");
                     tctxt->groups |= ri->groups;
                     work_done = 1;
+                    recordAnchoredLiteralMatch(t, scratch, ri->anch_id, end);
+
                     assert(ri->done_jump); // must progress
                     pc += ri->done_jump;
                     continue;
@@ -2085,8 +2087,8 @@ hwlmcb_rv_t roseRunProgram_i(const struct RoseEngine *t,
             }
             PROGRAM_NEXT_INSTRUCTION
 
-            PROGRAM_CASE(RECORD_ANCHORED) {
-                recordAnchoredLiteralMatch(t, scratch, ri->id, end);
+            PROGRAM_CASE(DUMMY_NOP) {
+                assert(0);
             }
             PROGRAM_NEXT_INSTRUCTION
 
index 0f41da71339addc0b6bd3c3654445aeee0bb2b06..ae352e2ea0b57fb52130e56398627f79a79fb24b 100644 (file)
@@ -3615,22 +3615,37 @@ void makeRoleCheckLeftfix(const RoseBuildImpl &build,
 }
 
 static
-void makeRoleAnchoredDelay(const RoseBuildImpl &build,
-                           u32 floatingMinLiteralMatchOffset,
-                           RoseVertex v, RoseProgram &program) {
-    // Only relevant for roles that can be triggered by the anchored table.
-    if (!build.isAnchored(v)) {
+void makeAnchoredLiteralDelay(const RoseBuildImpl &build,
+                              const ProgramBuild &prog_build, u32 lit_id,
+                              RoseProgram &program) {
+    // Only relevant for literals in the anchored table.
+    const rose_literal_id &lit = build.literals.right.at(lit_id);
+    if (lit.table != ROSE_ANCHORED) {
         return;
     }
 
-    // If this match cannot occur after floatingMinLiteralMatchOffset, we do
-    // not need this check.
-    if (build.g[v].max_offset <= floatingMinLiteralMatchOffset) {
+    // If this literal match cannot occur after floatingMinLiteralMatchOffset,
+    // we do not need this check.
+    bool all_too_early = true;
+    rose_group groups = 0;
+
+    const auto &lit_vertices = build.literal_info.at(lit_id).vertices;
+    for (RoseVertex v : lit_vertices) {
+         if (build.g[v].max_offset > prog_build.floatingMinLiteralMatchOffset) {
+             all_too_early = false;
+         }
+         groups |= build.g[v].groups;
+    }
+
+    if (all_too_early) {
         return;
     }
 
+    assert(contains(prog_build.anchored_programs, lit_id));
+    u32 anch_id = prog_build.anchored_programs.at(lit_id);
+
     const auto *end_inst = program.end_instruction();
-    auto ri = make_unique<RoseInstrAnchoredDelay>(build.g[v].groups, end_inst);
+    auto ri = make_unique<RoseInstrAnchoredDelay>(groups, anch_id, end_inst);
     program.add_before_end(move(ri));
 }
 
@@ -4175,9 +4190,6 @@ RoseProgram makeRoleProgram(const RoseBuildImpl &build, build_context &bc,
     // First, add program instructions that enforce preconditions without
     // effects.
 
-    makeRoleAnchoredDelay(build, prog_build.floatingMinLiteralMatchOffset, v,
-                          program);
-
     if (onlyAtEod(build, v)) {
         DEBUG_PRINTF("only at eod\n");
         const auto *end_inst = program.end_instruction();
@@ -4626,21 +4638,6 @@ u32 findMaxOffset(const RoseBuildImpl &build, u32 lit_id) {
     return max_offset;
 }
 
-static
-void makeRecordAnchoredInstruction(const RoseBuildImpl &build,
-                                   ProgramBuild &prog_build, u32 lit_id,
-                                   RoseProgram &program) {
-    if (build.literals.right.at(lit_id).table != ROSE_ANCHORED) {
-        return;
-    }
-    if (!contains(prog_build.anchored_programs, lit_id)) {
-        return;
-    }
-    auto anch_id = prog_build.anchored_programs.at(lit_id);
-    DEBUG_PRINTF("adding RECORD_ANCHORED for anch_id=%u\n", anch_id);
-    program.add_before_end(make_unique<RoseInstrRecordAnchored>(anch_id));
-}
-
 static
 u32 findMinOffset(const RoseBuildImpl &build, u32 lit_id) {
     const auto &lit_vertices = build.literal_info.at(lit_id).vertices;
@@ -4768,8 +4765,8 @@ bool hasDelayedLiteral(const RoseBuildImpl &build,
 static
 RoseProgram makeLitInitialProgram(const RoseBuildImpl &build,
                                   build_context &bc, ProgramBuild &prog_build,
-                                  u32 lit_id,
-                                  const vector<RoseEdge> &lit_edges) {
+                                  u32 lit_id, const vector<RoseEdge> &lit_edges,
+                                  bool is_anchored_replay_program) {
     RoseProgram program;
 
     // Check long literal info.
@@ -4794,6 +4791,11 @@ RoseProgram makeLitInitialProgram(const RoseBuildImpl &build,
                                  prog_build.floatingMinLiteralMatchOffset,
                                  program);
 
+    /* Check if we are able to deliever matches from the anchored table now */
+    if (!is_anchored_replay_program) {
+        makeAnchoredLiteralDelay(build, prog_build, lit_id, program);
+    }
+
     return program;
 }
 
@@ -4806,7 +4808,13 @@ RoseProgram makeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
 
     DEBUG_PRINTF("lit id=%u, %zu lit edges\n", lit_id, lit_edges.size());
 
-    RoseProgram program;
+    // Construct initial program up front, as its early checks must be able
+    // to jump to end and terminate processing for this literal.
+    auto lit_program = makeLitInitialProgram(build, bc, prog_build, lit_id,
+                                             lit_edges,
+                                             is_anchored_replay_program);
+
+    RoseProgram role_programs;
 
     // Predecessor state id -> program block.
     map<u32, RoseProgram> pred_blocks;
@@ -4829,7 +4837,7 @@ RoseProgram makeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
 
     // Add blocks to deal with non-root edges (triggered by sparse iterator or
     // mmbit_isset checks).
-    addPredBlocks(pred_blocks, bc.roleStateIndices.size(), program);
+    addPredBlocks(pred_blocks, bc.roleStateIndices.size(), role_programs);
 
     // Add blocks to handle root roles.
     for (const auto &e : lit_edges) {
@@ -4839,31 +4847,23 @@ RoseProgram makeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
         }
         DEBUG_PRINTF("root edge (%zu,%zu)\n", g[u].index,
                      g[target(e, g)].index);
-        program.add_block(makeRoleProgram(build, bc, prog_build, e));
+        role_programs.add_block(makeRoleProgram(build, bc, prog_build, e));
     }
 
     if (lit_id == build.eod_event_literal_id) {
+        /* Note: does not require the lit intial program */
         assert(build.eod_event_literal_id != MO_INVALID_IDX);
-        return program;
+        return role_programs;
     }
 
-    RoseProgram root_block;
+    /* Instructions to run even if a role program bails out */
+    RoseProgram unconditional_block;
 
     // Literal may squash groups.
-    makeGroupSquashInstruction(build, lit_id, root_block);
+    makeGroupSquashInstruction(build, lit_id, unconditional_block);
 
-    // Literal may be anchored and need to be recorded.
-    if (!is_anchored_replay_program) {
-        makeRecordAnchoredInstruction(build, prog_build, lit_id, root_block);
-    }
-
-    program.add_block(move(root_block));
-
-    // Construct initial program up front, as its early checks must be able
-    // to jump to end and terminate processing for this literal.
-    auto lit_program = makeLitInitialProgram(build, bc, prog_build, lit_id,
-                                             lit_edges);
-    lit_program.add_before_end(move(program));
+    role_programs.add_block(move(unconditional_block));
+    lit_program.add_before_end(move(role_programs));
 
     return lit_program;
 }
index 73ed830ea0e2c91124894b2415c378101d5628ee..dfbbe1162dfd72d3768c07063a1282637f8e61fa 100644 (file)
@@ -890,6 +890,7 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
             PROGRAM_CASE(ANCHORED_DELAY) {
                 os << "    groups 0x" << std::hex << ri->groups << std::dec
                    << endl;
+                os << "    anch_id " << ri->anch_id << "\n";
                 os << "    done_jump " << offset + ri->done_jump << endl;
             }
             PROGRAM_NEXT_INSTRUCTION
@@ -1097,9 +1098,7 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
             }
             PROGRAM_NEXT_INSTRUCTION
 
-            PROGRAM_CASE(RECORD_ANCHORED) {
-                os << "    id " << ri->id << endl;
-            }
+            PROGRAM_CASE(DUMMY_NOP) {}
             PROGRAM_NEXT_INSTRUCTION
 
             PROGRAM_CASE(CATCH_UP) {}
index a659f22e23c63e90cadea4b4a6a54d36ed92c512..5cf062003be10944618adf0b17fe913c2a12cd4c 100644 (file)
@@ -72,6 +72,7 @@ void RoseInstrAnchoredDelay::write(void *dest, RoseEngineBlob &blob,
     RoseInstrBase::write(dest, blob, offset_map);
     auto *inst = static_cast<impl_type *>(dest);
     inst->groups = groups;
+    inst->anch_id = anch_id;
     inst->done_jump = calc_jump(offset_map, this, target);
 }
 
@@ -248,13 +249,6 @@ void RoseInstrPushDelayed::write(void *dest, RoseEngineBlob &blob,
     inst->index = index;
 }
 
-void RoseInstrRecordAnchored::write(void *dest, RoseEngineBlob &blob,
-                                    const OffsetMap &offset_map) const {
-    RoseInstrBase::write(dest, blob, offset_map);
-    auto *inst = static_cast<impl_type *>(dest);
-    inst->id = id;
-}
-
 void RoseInstrSomAdjust::write(void *dest, RoseEngineBlob &blob,
                                const OffsetMap &offset_map) const {
     RoseInstrBase::write(dest, blob, offset_map);
index 19b9f90ac8836bebe69b61b64458c22952658e79..9c74d488250b4d858c030365e2bff8b926a3cba6 100644 (file)
@@ -216,18 +216,20 @@ class RoseInstrAnchoredDelay
                                     RoseInstrAnchoredDelay> {
 public:
     rose_group groups;
+    u32 anch_id;
     const RoseInstruction *target;
 
-    RoseInstrAnchoredDelay(rose_group groups_in,
+    RoseInstrAnchoredDelay(rose_group groups_in, u32 anch_id_in,
                            const RoseInstruction *target_in)
-        : groups(groups_in), target(target_in) {}
+        : groups(groups_in), anch_id(anch_id_in), target(target_in) {}
 
     bool operator==(const RoseInstrAnchoredDelay &ri) const {
-        return groups == ri.groups && target == ri.target;
+        return groups == ri.groups && anch_id == ri.anch_id
+        && target == ri.target;
     }
 
     size_t hash() const override {
-        return hash_all(static_cast<int>(opcode), groups);
+        return hash_all(static_cast<int>(opcode), groups, anch_id);
     }
 
     void write(void *dest, RoseEngineBlob &blob,
@@ -235,8 +237,8 @@ public:
 
     bool equiv_to(const RoseInstrAnchoredDelay &ri, const OffsetMap &offsets,
                   const OffsetMap &other_offsets) const {
-        return groups == ri.groups &&
-               offsets.at(target) == other_offsets.at(ri.target);
+        return groups == ri.groups && anch_id == ri.anch_id
+               && offsets.at(target) == other_offsets.at(ri.target);
     }
 };
 
@@ -844,32 +846,6 @@ public:
     }
 };
 
-class RoseInstrRecordAnchored
-    : public RoseInstrBaseNoTargets<ROSE_INSTR_RECORD_ANCHORED,
-                                    ROSE_STRUCT_RECORD_ANCHORED,
-                                    RoseInstrRecordAnchored> {
-public:
-    u32 id;
-
-    explicit RoseInstrRecordAnchored(u32 id_in) : id(id_in) {}
-
-    bool operator==(const RoseInstrRecordAnchored &ri) const {
-        return id == ri.id;
-    }
-
-    size_t hash() const override {
-        return hash_all(static_cast<int>(opcode), id);
-    }
-
-    void write(void *dest, RoseEngineBlob &blob,
-               const OffsetMap &offset_map) const override;
-
-    bool equiv_to(const RoseInstrRecordAnchored &ri, const OffsetMap &,
-                  const OffsetMap &) const {
-        return id == ri.id;
-    }
-};
-
 class RoseInstrCatchUp
     : public RoseInstrBaseTrivial<ROSE_INSTR_CATCH_UP, ROSE_STRUCT_CATCH_UP,
                                   RoseInstrCatchUp> {
@@ -2281,6 +2257,8 @@ public:
     /**
      * \brief Adds this block to the program just before the terminating
      * ROSE_INSTR_END.
+     *
+     * Any existing instruction that was jumping to end continues to do so.
      */
     void add_before_end(RoseProgram &&block) {
         assert(!prog.empty());
@@ -2295,6 +2273,9 @@ public:
 
     /**
      * \brief Append this program block, replacing our current ROSE_INSTR_END.
+     *
+     * Any existing instruction that was jumping to end, now leads to the newly
+     * added block.
      */
     void add_block(RoseProgram &&block) {
         assert(!prog.empty());
index ebda679a0febd4ef9220ae3912bd04778b8f411e..cdfe96acee9315c389579870268a649c8d766dba 100644 (file)
@@ -62,7 +62,7 @@ enum RoseInstructionCode {
     ROSE_INSTR_CHECK_INFIX,       //!< Infix engine must be in accept state.
     ROSE_INSTR_CHECK_PREFIX,      //!< Prefix engine must be in accept state.
     ROSE_INSTR_PUSH_DELAYED,      //!< Push delayed literal matches.
-    ROSE_INSTR_RECORD_ANCHORED,   //!< Record an anchored literal match.
+    ROSE_INSTR_DUMMY_NOP,         //!< NOP. Should not exist in build programs.
     ROSE_INSTR_CATCH_UP,          //!< Catch up engines, anchored matches.
     ROSE_INSTR_CATCH_UP_MPV,      //!< Catch up the MPV.
     ROSE_INSTR_SOM_ADJUST,        //!< Set SOM from a distance to EOM.
@@ -188,7 +188,8 @@ struct ROSE_STRUCT_END {
 struct ROSE_STRUCT_ANCHORED_DELAY {
     u8 code; //!< From enum RoseInstructionCode.
     rose_group groups; //!< Bitmask.
-    u32 done_jump; //!< Jump forward this many bytes if successful.
+    u32 anch_id; //!< Program to restart after the delay.
+    u32 done_jump; //!< Jump forward this many bytes if we have to delay.
 };
 
 struct ROSE_STRUCT_CHECK_LIT_EARLY {
@@ -327,9 +328,8 @@ struct ROSE_STRUCT_PUSH_DELAYED {
     u32 index; // Delay literal index (relative to first delay lit).
 };
 
-struct ROSE_STRUCT_RECORD_ANCHORED {
+struct ROSE_STRUCT_DUMMY_NOP {
     u8 code; //!< From enum RoseInstructionCode.
-    u32 id; //!< Literal ID.
 };
 
 struct ROSE_STRUCT_CATCH_UP {