]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
rose: add CLEAR_WORK_DONE instruction
authorJustin Viiret <justin.viiret@intel.com>
Wed, 29 Mar 2017 02:06:26 +0000 (13:06 +1100)
committerMatthew Barr <matthew.barr@intel.com>
Wed, 26 Apr 2017 05:18:26 +0000 (15:18 +1000)
Preparatory work for allowing fragments to be shared between literals
that squash groups and those that don't.

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 d67c307ffaf0b0954d6835742ab3fafde1ac0a08..30ff85270d50056f67414e23409e20be53514e61 100644 (file)
@@ -2166,6 +2166,12 @@ hwlmcb_rv_t roseRunProgram_i(const struct RoseEngine *t,
                 }
             }
             PROGRAM_NEXT_INSTRUCTION
+
+            PROGRAM_CASE(CLEAR_WORK_DONE) {
+                DEBUG_PRINTF("clear work_done flag\n");
+                work_done = 0;
+            }
+            PROGRAM_NEXT_INSTRUCTION
         }
     }
 
index 32a1d07508078f1cba2b0ebb16a5be084d7e70a1..f51e0449567ab90373541f0397c2426e4897331e 100644 (file)
@@ -4517,6 +4517,18 @@ u32 writeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
                         bool is_anchored_program) {
     assert(!lit_ids.empty());
 
+    // If we have multiple literals and any of them squash groups, we will have
+    // to add a CLEAR_WORK_DONE instruction to each literal program block to
+    // clear the work_done flags so that it's only set if a state has been
+    // switched on for that literal.
+
+    // Note that we add it to every lit program, as they may be
+    // reordered/uniquified by assembleProgramBlocks() above.
+    const bool needs_clear_work = lit_ids.size() > 1 &&
+        any_of_in(lit_ids, [&](u32 lit_id) {
+            return build.literal_info.at(lit_id).squash_group;
+        });
+
     vector<RoseProgram> blocks;
 
     const vector<RoseEdge> no_edges;
@@ -4531,6 +4543,11 @@ u32 writeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
         }
         auto prog = buildLiteralProgram(build, bc, prog_build, lit_id,
                                         *edges_ptr, is_anchored_program);
+        if (needs_clear_work) {
+            RoseProgram clear_block;
+            clear_block.add_before_end(make_unique<RoseInstrClearWorkDone>());
+            prog.add_block(move(clear_block));
+        }
         blocks.push_back(move(prog));
     }
 
index 0d05e8ac7084293f0169d1c6ee40e24a9f7676bf..0e53d59da097d88eba73bca138686f2e4926582a 100644 (file)
@@ -1100,6 +1100,9 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
             }
             PROGRAM_NEXT_INSTRUCTION
 
+            PROGRAM_CASE(CLEAR_WORK_DONE) {}
+            PROGRAM_NEXT_INSTRUCTION
+
         default:
             os << "  UNKNOWN (code " << int{code} << ")" << endl;
             os << "  <stopping>" << endl;
index 112b93f9274b4e318e2c4cf4c23c573a9a3d67ec..1c0fd2ab8d94875813a55762c482c20fad482e39 100644 (file)
@@ -48,6 +48,7 @@ RoseInstrSomZero::~RoseInstrSomZero() = default;
 RoseInstrSuffixesEod::~RoseInstrSuffixesEod() = default;
 RoseInstrMatcherEod::~RoseInstrMatcherEod() = default;
 RoseInstrEnd::~RoseInstrEnd() = default;
+RoseInstrClearWorkDone::~RoseInstrClearWorkDone() = default;
 
 using OffsetMap = RoseInstruction::OffsetMap;
 
index fd966a8da49225e7ce6bf6ca5bc03fbb43820ad1..a63f03c8f715edaec1e7a3575148ab4d9adf700d 100644 (file)
@@ -1851,6 +1851,14 @@ public:
     }
 };
 
+class RoseInstrClearWorkDone
+    : public RoseInstrBaseTrivial<ROSE_INSTR_CLEAR_WORK_DONE,
+                                  ROSE_STRUCT_CLEAR_WORK_DONE,
+                                  RoseInstrClearWorkDone> {
+public:
+    ~RoseInstrClearWorkDone() override;
+};
+
 class RoseInstrEnd
     : public RoseInstrBaseTrivial<ROSE_INSTR_END, ROSE_STRUCT_END,
                                   RoseInstrEnd> {
index 652b91095f397e8ff92bde17157fb8550b83d206..cf1a9eb6803e7a99f8b8ff7842ccf21436ad2a49 100644 (file)
@@ -141,7 +141,12 @@ enum RoseInstructionCode {
      */
     ROSE_INSTR_CHECK_MED_LIT_NOCASE,
 
-    LAST_ROSE_INSTRUCTION = ROSE_INSTR_CHECK_MED_LIT_NOCASE //!< Sentinel.
+    /**
+     * \brief Clear the "work done" flag used by the SQUASH_GROUPS instruction.
+     */
+    ROSE_INSTR_CLEAR_WORK_DONE,
+
+    LAST_ROSE_INSTRUCTION = ROSE_INSTR_CLEAR_WORK_DONE //!< Sentinel.
 };
 
 struct ROSE_STRUCT_END {
@@ -517,4 +522,8 @@ struct ROSE_STRUCT_CHECK_MED_LIT_NOCASE {
     u32 fail_jump; //!< Jump forward this many bytes on failure.
 };
 
+struct ROSE_STRUCT_CLEAR_WORK_DONE {
+    u8 code; //!< From enum RoseInstructionCode.
+};
+
 #endif // ROSE_ROSE_PROGRAM_H