allow some prefixes that may squash the literal match to run eagerly

This commit is contained in:
Alex Coyte
2016-06-24 09:28:42 +10:00
committed by Matthew Barr
parent f9ded59361
commit f166bc5658
34 changed files with 895 additions and 148 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -324,4 +324,49 @@ flat_set<NFAVertex> execute_graph(const NGHolder &running_g,
initial_states);
}
static
bool can_die_early(const NGHolder &g, const vector<StateInfo> &info,
const dynamic_bitset<> &s,
map<dynamic_bitset<>, u32> &visited, u32 age_limit) {
if (contains(visited, s) && visited[s] >= age_limit) {
/* we have already (or are in the process) of visiting here with a
* looser limit. */
return false;
}
visited[s] = age_limit;
if (s.none()) {
DEBUG_PRINTF("dead\n");
return true;
}
if (age_limit == 0) {
return false;
}
dynamic_bitset<> all_succ(s.size());
step(g, info, s, &all_succ);
all_succ.reset(NODE_START_DOTSTAR);
for (u32 i = 0; i < N_CHARS; i++) {
dynamic_bitset<> next = all_succ;
filter_by_reach(info, &next, CharReach(i));
if (can_die_early(g, info, next, visited, age_limit - 1)) {
return true;
}
}
return false;
}
bool can_die_early(const NGHolder &g, u32 age_limit) {
if (proper_out_degree(g.startDs, g)) {
return false;
}
const vector<StateInfo> &info = makeInfoTable(g);
map<dynamic_bitset<>, u32> visited;
return can_die_early(g, info, makeStateBitset(g, {g.start}), visited,
age_limit);
}
} // namespace ue2

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -64,6 +64,9 @@ flat_set<NFAVertex> execute_graph(const NGHolder &g, const NGHolder &input_dag,
const flat_set<NFAVertex> &input_start_states,
const flat_set<NFAVertex> &initial);
/* returns true if it is possible for the nfa to die within age_limit bytes */
bool can_die_early(const NGHolder &g, u32 age_limit);
} // namespace ue2
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -315,15 +315,26 @@ void remove_edges(const Container &c, NGHolder &h, bool renumber = true) {
remove_edges(c.begin(), c.end(), h, renumber);
}
static UNUSED
inline
bool is_triggered(const NGHolder &g) {
return is_triggered(g.kind);
}
static UNUSED
inline
bool generates_callbacks(const NGHolder &g) {
return generates_callbacks(g.kind);
}
inline
bool has_managed_reports(const NGHolder &g) {
return has_managed_reports(g.kind);
}
inline
bool inspects_states_for_accepts(const NGHolder &g) {
return inspects_states_for_accepts(g.kind);
}
} // namespace ue2
#endif

View File

@@ -373,7 +373,7 @@ constructNFA(const NGHolder &h_in, const ReportManager *rm,
const map<u32, vector<vector<CharReach>>> &triggers,
bool compress_state, bool do_accel, bool impl_test_only, u32 hint,
const CompileContext &cc) {
if (!generates_callbacks(h_in)) {
if (!has_managed_reports(h_in)) {
rm = nullptr;
} else {
assert(rm);
@@ -413,7 +413,7 @@ constructNFA(const NGHolder &h_in, const ReportManager *rm,
set<NFAVertex> zombies = findZombies(*h, br_cyclic, state_ids, cc);
if (generates_callbacks(*h)) {
if (has_managed_reports(*h)) {
assert(rm);
remapReportsToPrograms(*h, *rm);
}
@@ -508,7 +508,7 @@ u32 isImplementableNFA(const NGHolder &g, const ReportManager *rm,
return true;
}
if (!generates_callbacks(g)) {
if (!has_managed_reports(g)) {
rm = nullptr;
} else {
assert(rm);
@@ -547,7 +547,7 @@ void reduceImplementableGraph(NGHolder &g, som_type som, const ReportManager *rm
removeRedundancy(g, som);
if (rm && generates_callbacks(g)) {
if (rm && has_managed_reports(g)) {
pruneHighlanderDominated(g, *rm);
}
@@ -560,7 +560,7 @@ void reduceImplementableGraph(NGHolder &g, som_type som, const ReportManager *rm
u32 countAccelStates(const NGHolder &g, const ReportManager *rm,
const CompileContext &cc) {
if (!generates_callbacks(g)) {
if (!has_managed_reports(g)) {
rm = nullptr;
} else {
assert(rm);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -531,9 +531,9 @@ unique_ptr<raw_dfa> buildMcClellan(const NGHolder &graph,
DEBUG_PRINTF("attempting to build ?%d? mcclellan\n", (int)graph.kind);
assert(allMatchStatesHaveReports(graph));
bool prunable = grey.highlanderPruneDFA && generates_callbacks(graph);
assert(rm || !generates_callbacks(graph));
if (!generates_callbacks(graph)) {
bool prunable = grey.highlanderPruneDFA && has_managed_reports(graph);
assert(rm || !has_managed_reports(graph));
if (!has_managed_reports(graph)) {
rm = nullptr;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -112,6 +112,12 @@ void splitLHS(const NGHolder &base, const vector<NFAVertex> &pivots,
case NFA_SUFFIX:
lhs->kind = NFA_INFIX;
break;
case NFA_EAGER_PREFIX:
/* Current code should not be assigning eager until well after all the
* splitting is done. */
assert(0);
lhs->kind = NFA_EAGER_PREFIX;
break;
case NFA_REV_PREFIX:
case NFA_OUTFIX_RAW:
assert(0);
@@ -154,6 +160,12 @@ void splitRHS(const NGHolder &base, const vector<NFAVertex> &pivots,
case NFA_OUTFIX:
rhs->kind = NFA_SUFFIX;
break;
case NFA_EAGER_PREFIX:
/* Current code should not be assigning eager until well after all the
* splitting is done. */
assert(0);
rhs->kind = NFA_INFIX;
break;
case NFA_REV_PREFIX:
case NFA_OUTFIX_RAW:
assert(0);