diff --git a/src/rose/rose_build_bytecode.cpp b/src/rose/rose_build_bytecode.cpp index 4d9c3d7e..e62c9e18 100644 --- a/src/rose/rose_build_bytecode.cpp +++ b/src/rose/rose_build_bytecode.cpp @@ -2333,6 +2333,7 @@ void addSomRevNfas(build_context &bc, RoseEngine &proto, static void recordResources(RoseResources &resources, const RoseBuildImpl &build, + const vector &anchored_dfas, const vector &fragments) { if (!build.outfixes.empty()) { resources.has_outfixes = true; @@ -2351,6 +2352,15 @@ void recordResources(RoseResources &resources, const RoseBuildImpl &build, break; } } + + resources.has_anchored = !anchored_dfas.empty(); + resources.has_anchored_multiple = anchored_dfas.size() > 1; + for (const auto &rdfa : anchored_dfas) { + if (rdfa.states.size() > 256) { + resources.has_anchored_large = true; + } + } + } static @@ -3413,6 +3423,7 @@ u32 writeEagerQueueIter(const set &eager, u32 leftfixBeginQueue, static bytecode_ptr addSmallWriteEngine(const RoseBuildImpl &build, + const RoseResources &res, bytecode_ptr rose) { assert(rose); @@ -3421,7 +3432,7 @@ bytecode_ptr addSmallWriteEngine(const RoseBuildImpl &build, return rose; } - u32 qual = roseQuality(rose.get()); + u32 qual = roseQuality(res, rose.get()); auto smwr_engine = build.smwr.build(qual); if (!smwr_engine) { DEBUG_PRINTF("no smwr built\n"); @@ -3561,10 +3572,7 @@ bytecode_ptr RoseBuildImpl::buildFinalEngine(u32 minWidth) { build_context bc; u32 floatingMinLiteralMatchOffset = findMinFloatingLiteralMatch(*this, anchored_dfas); - recordResources(bc.resources, *this, fragments); - if (!anchored_dfas.empty()) { - bc.resources.has_anchored = true; - } + recordResources(bc.resources, *this, anchored_dfas, fragments); bc.needs_mpv_catchup = needsMpvCatchup(*this); makeBoundaryPrograms(*this, bc, boundary, dboundary, proto.boundary); @@ -3803,7 +3811,7 @@ bytecode_ptr RoseBuildImpl::buildFinalEngine(u32 minWidth) { bc.engine_blob.write_bytes(engine.get()); // Add a small write engine if appropriate. - engine = addSmallWriteEngine(*this, move(engine)); + engine = addSmallWriteEngine(*this, bc.resources, move(engine)); DEBUG_PRINTF("rose done %p\n", engine.get()); diff --git a/src/rose/rose_build_misc.cpp b/src/rose/rose_build_misc.cpp index d8a39994..450b2efb 100644 --- a/src/rose/rose_build_misc.cpp +++ b/src/rose/rose_build_misc.cpp @@ -29,6 +29,7 @@ #include "rose_build_misc.h" #include "rose_build_impl.h" +#include "rose_build_resources.h" #include "hwlm/hwlm_literal.h" #include "nfa/castlecompile.h" #include "nfa/goughcompile.h" @@ -788,18 +789,16 @@ LeftEngInfo::operator bool() const { return graph || castle || dfa || haig; } -u32 roseQuality(const RoseEngine *t) { +u32 roseQuality(const RoseResources &res, const RoseEngine *t) { /* Rose is low quality if the atable is a Mcclellan 16 or has multiple DFAs */ - const anchored_matcher_info *atable = getALiteralMatcher(t); - if (atable) { - if (atable->next_offset) { + if (res.has_anchored) { + if (res.has_anchored_multiple) { DEBUG_PRINTF("multiple atable engines\n"); return 0; } - const NFA *nfa = (const NFA *)((const char *)atable + sizeof(*atable)); - if (!isSmallDfaType(nfa->type)) { + if (res.has_anchored_large) { DEBUG_PRINTF("m16 atable engine\n"); return 0; } @@ -808,7 +807,7 @@ u32 roseQuality(const RoseEngine *t) { /* if we always run multiple engines then we are slow */ u32 always_run = 0; - if (atable) { + if (res.has_anchored) { always_run++; } @@ -817,8 +816,7 @@ u32 roseQuality(const RoseEngine *t) { always_run++; } - const HWLM *ftable = getFLiteralMatcher(t); - if (ftable) { + if (res.has_floating) { /* TODO: ignore conditional ftables, or ftables beyond smwr region */ always_run++; } diff --git a/src/rose/rose_build_misc.h b/src/rose/rose_build_misc.h index b9c6d5ca..f34b8292 100644 --- a/src/rose/rose_build_misc.h +++ b/src/rose/rose_build_misc.h @@ -35,9 +35,11 @@ struct RoseEngine; namespace ue2 { +struct RoseResources; + /* used by heuristics to determine the small write engine. High numbers are * intended to indicate a lightweight rose. */ -u32 roseQuality(const RoseEngine *rose); +u32 roseQuality(const RoseResources &res, const RoseEngine *rose); } diff --git a/src/rose/rose_build_resources.h b/src/rose/rose_build_resources.h index 3edb81b9..4fa102f3 100644 --- a/src/rose/rose_build_resources.h +++ b/src/rose/rose_build_resources.h @@ -48,6 +48,8 @@ struct RoseResources { bool has_lit_delay = false; bool has_lit_check = false; // long literal support bool has_anchored = false; + bool has_anchored_multiple = false; /* multiple anchored dfas */ + bool has_anchored_large = false; /* mcclellan 16 anchored dfa */ bool has_floating = false; bool has_eod = false; };