dstate_id_t sds_proxy = get_sds_or_proxy(rdfa);
DEBUG_PRINTF("sds %hu\n", sds_proxy);
- for (size_t i = 0; i < rdfa.states.size(); i++) {
+ /* Find accel info for a single state. */
+ auto do_state = [&](size_t i) {
if (i == DEAD_STATE) {
- continue;
+ return;
}
/* Note on report acceleration states: While we can't accelerate while
- * we
- * are spamming out callbacks, the QR code paths don't raise reports
+ * we are spamming out callbacks, the QR code paths don't raise reports
* during scanning so they can accelerate report states. */
if (generates_callbacks(rdfa.kind) && !rdfa.states[i].reports.empty()) {
- continue;
+ return;
}
size_t single_limit =
if (ei.cr.count() > single_limit) {
DEBUG_PRINTF("state %zu is not accelerable has %zu\n", i,
ei.cr.count());
- continue;
+ return;
}
DEBUG_PRINTF("state %zu should be accelerable %zu\n", i, ei.cr.count());
rv[i] = ei;
+ };
+
+ if (only_accel_init) {
+ DEBUG_PRINTF("only computing accel for init states\n");
+ do_state(rdfa.start_anchored);
+ if (rdfa.start_floating != rdfa.start_anchored) {
+ do_state(rdfa.start_floating);
+ }
+ } else {
+ DEBUG_PRINTF("computing accel for all states\n");
+ for (size_t i = 0; i < rdfa.states.size(); i++) {
+ do_state(i);
+ }
}
- /* provide accleration states to states in the region of sds */
+ /* provide acceleration states to states in the region of sds */
if (contains(rv, sds_proxy)) {
AccelScheme sds_ei = rv[sds_proxy];
sds_ei.double_byte.clear(); /* region based on single byte scheme
/*
- * Copyright (c) 2015-2016, Intel Corporation
+ * Copyright (c) 2015-2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
class accel_dfa_build_strat : public dfa_build_strat {
public:
- explicit accel_dfa_build_strat(const ReportManager &rm_in)
- : dfa_build_strat(rm_in) {}
+ accel_dfa_build_strat(const ReportManager &rm_in, bool only_accel_init_in)
+ : dfa_build_strat(rm_in), only_accel_init(only_accel_init_in) {}
virtual AccelScheme find_escape_strings(dstate_id_t this_idx) const;
virtual size_t accelSize(void) const = 0;
virtual u32 max_allowed_offset_accel() const = 0;
virtual void buildAccel(dstate_id_t this_idx, const AccelScheme &info,
void *accel_out);
virtual std::map<dstate_id_t, AccelScheme> getAccelInfo(const Grey &grey);
+private:
+ bool only_accel_init;
};
} // namespace ue2
gough_build_strat(
raw_som_dfa &r, const GoughGraph &g, const ReportManager &rm_in,
const map<dstate_id_t, gough_accel_state_info> &accel_info)
- : mcclellan_build_strat(r, rm_in), rdfa(r), gg(g),
+ : mcclellan_build_strat(r, rm_in, false), rdfa(r), gg(g),
accel_gough_info(accel_info) {}
unique_ptr<raw_report_info> gatherReports(vector<u32> &reports /* out */,
vector<u32> &reports_eod /* out */,
bytecode_ptr<NFA> mcclellanCompile(raw_dfa &raw, const CompileContext &cc,
const ReportManager &rm,
+ bool only_accel_init,
set<dstate_id_t> *accel_states) {
- mcclellan_build_strat mbs(raw, rm);
+ mcclellan_build_strat mbs(raw, rm, only_accel_init);
return mcclellanCompile_i(raw, mbs, cc, accel_states);
}
class mcclellan_build_strat : public accel_dfa_build_strat {
public:
- mcclellan_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in)
- : accel_dfa_build_strat(rm_in), rdfa(rdfa_in) {}
+ mcclellan_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in,
+ bool only_accel_init_in)
+ : accel_dfa_build_strat(rm_in, only_accel_init_in), rdfa(rdfa_in) {}
raw_dfa &get_raw() const override { return rdfa; }
std::unique_ptr<raw_report_info> gatherReports(
std::vector<u32> &reports /* out */,
* states */
bytecode_ptr<NFA>
mcclellanCompile(raw_dfa &raw, const CompileContext &cc,
- const ReportManager &rm,
+ const ReportManager &rm, bool only_accel_init,
std::set<dstate_id_t> *accel_states = nullptr);
/* used internally by mcclellan/haig/gough compile process */
return nullptr;
}
- mcclellan_build_strat mbs(raw, rm);
+ mcclellan_build_strat mbs(raw, rm, false);
dfa_info info(mbs);
bool using8bit = cc.grey.allowMcClellan8 && info.size() <= 256;
}
bytecode_ptr<NFA> shengCompile(raw_dfa &raw, const CompileContext &cc,
- const ReportManager &rm,
+ const ReportManager &rm, bool only_accel_init,
set<dstate_id_t> *accel_states) {
if (!cc.grey.allowSheng) {
DEBUG_PRINTF("Sheng is not allowed!\n");
return nullptr;
}
- sheng_build_strat strat(raw, rm);
+ sheng_build_strat strat(raw, rm, only_accel_init);
dfa_info info(strat);
DEBUG_PRINTF("Trying to compile a %zu state Sheng\n", raw.states.size());
class sheng_build_strat : public accel_dfa_build_strat {
public:
- sheng_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in)
- : accel_dfa_build_strat(rm_in), rdfa(rdfa_in) {}
+ sheng_build_strat(raw_dfa &rdfa_in, const ReportManager &rm_in,
+ bool only_accel_init_in)
+ : accel_dfa_build_strat(rm_in, only_accel_init_in), rdfa(rdfa_in) {}
raw_dfa &get_raw() const override { return rdfa; }
std::unique_ptr<raw_report_info> gatherReports(
std::vector<u32> &reports /* out */,
};
bytecode_ptr<NFA> shengCompile(raw_dfa &raw, const CompileContext &cc,
- const ReportManager &rm,
+ const ReportManager &rm, bool only_accel_init,
std::set<dstate_id_t> *accel_states = nullptr);
struct sheng_escape_info {
minimize_hopcroft(rdfa, cc.grey);
- auto nfa = mcclellanCompile(rdfa, cc, rm);
+ auto nfa = mcclellanCompile(rdfa, cc, rm, false);
if (!nfa) {
assert(0);
throw std::bad_alloc();
const CompileContext &cc,
const ReportManager &rm) {
// Unleash the Sheng!!
- auto dfa = shengCompile(rdfa, cc, rm);
+ auto dfa = shengCompile(rdfa, cc, rm, false);
if (!dfa && !is_transient) {
// Sheng wasn't successful, so unleash McClellan!
/* We don't try the hybrid for transient prefixes due to the extra
}
if (!dfa) {
// Sheng wasn't successful, so unleash McClellan!
- dfa = mcclellanCompile(rdfa, cc, rm);
+ dfa = mcclellanCompile(rdfa, cc, rm, false);
}
return dfa;
}
static
bytecode_ptr<NFA> getDfa(raw_dfa &rdfa, const CompileContext &cc,
- const ReportManager &rm,
+ const ReportManager &rm, bool has_literals,
set<dstate_id_t> &accel_states) {
+ // If we determinised literals, then we only need to consider the init
+ // states for acceleration.
+ bool only_accel_init = has_literals;
+
bytecode_ptr<NFA> dfa = nullptr;
if (cc.grey.allowSmallWriteSheng) {
- dfa = shengCompile(rdfa, cc, rm, &accel_states);
+ dfa = shengCompile(rdfa, cc, rm, only_accel_init, &accel_states);
}
if (!dfa) {
- dfa = mcclellanCompile(rdfa, cc, rm, &accel_states);
+ dfa = mcclellanCompile(rdfa, cc, rm, only_accel_init, &accel_states);
}
return dfa;
}
static
bytecode_ptr<NFA> prepEngine(raw_dfa &rdfa, u32 roseQuality,
const CompileContext &cc, const ReportManager &rm,
- u32 *start_offset, u32 *small_region) {
+ bool has_literals, u32 *start_offset,
+ u32 *small_region) {
*start_offset = remove_leading_dots(rdfa);
// Unleash the McClellan!
set<dstate_id_t> accel_states;
- auto nfa = getDfa(rdfa, cc, rm, accel_states);
+ auto nfa = getDfa(rdfa, cc, rm, has_literals, accel_states);
if (!nfa) {
DEBUG_PRINTF("DFA compile failed for smallwrite NFA\n");
return nullptr;
return nullptr;
}
- nfa = getDfa(rdfa, cc, rm, accel_states);
+ nfa = getDfa(rdfa, cc, rm, has_literals, accel_states);
if (!nfa) {
DEBUG_PRINTF("DFA compile failed for smallwrite NFA\n");
assert(0); /* able to build orig dfa but not the trimmed? */
}
bytecode_ptr<SmallWriteEngine> SmallWriteBuildImpl::build(u32 roseQuality) {
- if (!rdfa && is_empty(lit_trie) && is_empty(lit_trie_nocase)) {
+ const bool has_literals = !is_empty(lit_trie) || !is_empty(lit_trie_nocase);
+ if (!rdfa && !has_literals) {
DEBUG_PRINTF("no smallwrite engine\n");
poisoned = true;
return nullptr;
u32 start_offset;
u32 small_region;
- auto nfa =
- prepEngine(*rdfa, roseQuality, cc, rm, &start_offset, &small_region);
+ auto nfa = prepEngine(*rdfa, roseQuality, cc, rm, has_literals,
+ &start_offset, &small_region);
if (!nfa) {
DEBUG_PRINTF("some smallwrite outfix could not be prepped\n");
/* just skip the smallwrite optimization */