Provide RoseResources to roseQuality.

RoseResources is an alternative to manually digging through the bytecode.
This commit is contained in:
Alex Coyte 2017-07-31 10:38:30 +10:00 committed by Matthew Barr
parent 778addadc5
commit 37033ef9bb
4 changed files with 26 additions and 16 deletions

View File

@ -2333,6 +2333,7 @@ void addSomRevNfas(build_context &bc, RoseEngine &proto,
static static
void recordResources(RoseResources &resources, const RoseBuildImpl &build, void recordResources(RoseResources &resources, const RoseBuildImpl &build,
const vector<raw_dfa> &anchored_dfas,
const vector<LitFragment> &fragments) { const vector<LitFragment> &fragments) {
if (!build.outfixes.empty()) { if (!build.outfixes.empty()) {
resources.has_outfixes = true; resources.has_outfixes = true;
@ -2351,6 +2352,15 @@ void recordResources(RoseResources &resources, const RoseBuildImpl &build,
break; 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 static
@ -3413,6 +3423,7 @@ u32 writeEagerQueueIter(const set<u32> &eager, u32 leftfixBeginQueue,
static static
bytecode_ptr<RoseEngine> addSmallWriteEngine(const RoseBuildImpl &build, bytecode_ptr<RoseEngine> addSmallWriteEngine(const RoseBuildImpl &build,
const RoseResources &res,
bytecode_ptr<RoseEngine> rose) { bytecode_ptr<RoseEngine> rose) {
assert(rose); assert(rose);
@ -3421,7 +3432,7 @@ bytecode_ptr<RoseEngine> addSmallWriteEngine(const RoseBuildImpl &build,
return rose; return rose;
} }
u32 qual = roseQuality(rose.get()); u32 qual = roseQuality(res, rose.get());
auto smwr_engine = build.smwr.build(qual); auto smwr_engine = build.smwr.build(qual);
if (!smwr_engine) { if (!smwr_engine) {
DEBUG_PRINTF("no smwr built\n"); DEBUG_PRINTF("no smwr built\n");
@ -3561,10 +3572,7 @@ bytecode_ptr<RoseEngine> RoseBuildImpl::buildFinalEngine(u32 minWidth) {
build_context bc; build_context bc;
u32 floatingMinLiteralMatchOffset u32 floatingMinLiteralMatchOffset
= findMinFloatingLiteralMatch(*this, anchored_dfas); = findMinFloatingLiteralMatch(*this, anchored_dfas);
recordResources(bc.resources, *this, fragments); recordResources(bc.resources, *this, anchored_dfas, fragments);
if (!anchored_dfas.empty()) {
bc.resources.has_anchored = true;
}
bc.needs_mpv_catchup = needsMpvCatchup(*this); bc.needs_mpv_catchup = needsMpvCatchup(*this);
makeBoundaryPrograms(*this, bc, boundary, dboundary, proto.boundary); makeBoundaryPrograms(*this, bc, boundary, dboundary, proto.boundary);
@ -3803,7 +3811,7 @@ bytecode_ptr<RoseEngine> RoseBuildImpl::buildFinalEngine(u32 minWidth) {
bc.engine_blob.write_bytes(engine.get()); bc.engine_blob.write_bytes(engine.get());
// Add a small write engine if appropriate. // 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()); DEBUG_PRINTF("rose done %p\n", engine.get());

View File

@ -29,6 +29,7 @@
#include "rose_build_misc.h" #include "rose_build_misc.h"
#include "rose_build_impl.h" #include "rose_build_impl.h"
#include "rose_build_resources.h"
#include "hwlm/hwlm_literal.h" #include "hwlm/hwlm_literal.h"
#include "nfa/castlecompile.h" #include "nfa/castlecompile.h"
#include "nfa/goughcompile.h" #include "nfa/goughcompile.h"
@ -788,18 +789,16 @@ LeftEngInfo::operator bool() const {
return graph || castle || dfa || haig; 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 /* Rose is low quality if the atable is a Mcclellan 16 or has multiple DFAs
*/ */
const anchored_matcher_info *atable = getALiteralMatcher(t); if (res.has_anchored) {
if (atable) { if (res.has_anchored_multiple) {
if (atable->next_offset) {
DEBUG_PRINTF("multiple atable engines\n"); DEBUG_PRINTF("multiple atable engines\n");
return 0; 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"); DEBUG_PRINTF("m16 atable engine\n");
return 0; return 0;
} }
@ -808,7 +807,7 @@ u32 roseQuality(const RoseEngine *t) {
/* if we always run multiple engines then we are slow */ /* if we always run multiple engines then we are slow */
u32 always_run = 0; u32 always_run = 0;
if (atable) { if (res.has_anchored) {
always_run++; always_run++;
} }
@ -817,8 +816,7 @@ u32 roseQuality(const RoseEngine *t) {
always_run++; always_run++;
} }
const HWLM *ftable = getFLiteralMatcher(t); if (res.has_floating) {
if (ftable) {
/* TODO: ignore conditional ftables, or ftables beyond smwr region */ /* TODO: ignore conditional ftables, or ftables beyond smwr region */
always_run++; always_run++;
} }

View File

@ -35,9 +35,11 @@ struct RoseEngine;
namespace ue2 { namespace ue2 {
struct RoseResources;
/* used by heuristics to determine the small write engine. High numbers are /* used by heuristics to determine the small write engine. High numbers are
* intended to indicate a lightweight rose. */ * intended to indicate a lightweight rose. */
u32 roseQuality(const RoseEngine *rose); u32 roseQuality(const RoseResources &res, const RoseEngine *rose);
} }

View File

@ -48,6 +48,8 @@ struct RoseResources {
bool has_lit_delay = false; bool has_lit_delay = false;
bool has_lit_check = false; // long literal support bool has_lit_check = false; // long literal support
bool has_anchored = false; 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_floating = false;
bool has_eod = false; bool has_eod = false;
}; };