ng_region: clean up refineExits

This commit is contained in:
Justin Viiret 2017-03-15 09:29:44 +11:00 committed by Matthew Barr
parent 8823a8fbfd
commit 7396c93990

View File

@ -86,7 +86,7 @@ struct exit_info {
static static
void checkAndAddExitCandidate(const AcyclicGraph &g, void checkAndAddExitCandidate(const AcyclicGraph &g,
const ue2::unordered_set<NFAVertex> &r, const ue2::unordered_set<NFAVertex> &r,
NFAVertex v, vector<exit_info> *exits) { NFAVertex v, vector<exit_info> &exits) {
// set when we find our first candidate. // set when we find our first candidate.
decltype(exit_info::open) *open = nullptr; decltype(exit_info::open) *open = nullptr;
@ -94,8 +94,8 @@ void checkAndAddExitCandidate(const AcyclicGraph &g,
for (auto w : adjacent_vertices_range(v, g)) { for (auto w : adjacent_vertices_range(v, g)) {
if (!contains(r, NFAVertex(w))) { if (!contains(r, NFAVertex(w))) {
if (!open) { if (!open) {
exits->push_back(exit_info(NFAVertex(v))); exits.emplace_back(NFAVertex(v));
open = &exits->back().open; open = &exits.back().open;
} }
open->insert(NFAVertex(w)); open->insert(NFAVertex(w));
} }
@ -107,28 +107,31 @@ void checkAndAddExitCandidate(const AcyclicGraph &g,
} }
static static
void findExits(const AcyclicGraph &g, const ue2::unordered_set<NFAVertex> &r, vector<exit_info> findExits(const AcyclicGraph &g,
vector<exit_info> *exits) { const ue2::unordered_set<NFAVertex> &r) {
exits->clear(); vector<exit_info> exits;
for (auto v : r) { for (auto v : r) {
checkAndAddExitCandidate(g, r, v, exits); checkAndAddExitCandidate(g, r, v, exits);
} }
return exits;
} }
static static
void refineExits(const AcyclicGraph &g, const ue2::unordered_set<NFAVertex> &r, void refineExits(const AcyclicGraph &g, const ue2::unordered_set<NFAVertex> &r,
NFAVertex new_v, vector<exit_info> *exits) { NFAVertex new_v, vector<exit_info> &exits) {
for (u32 i = 0; i < exits->size(); i++) { /* new_v is no long an open edge */
(*exits)[i].open.erase(new_v); /* new_v is no long an open edge */ for (auto &exit : exits) {
if ((*exits)[i].open.empty()) { /* no open edges: no longer an exit */ exit.open.erase(new_v);
/* shuffle to back and kill */
(*exits)[i] = exits->back();
exits->pop_back();
i--;
}
} }
/* no open edges: no longer an exit */
exits.erase(
remove_if(exits.begin(), exits.end(),
[&](const exit_info &exit) { return exit.open.empty(); }),
exits.end());
checkAndAddExitCandidate(g, r, new_v, exits); checkAndAddExitCandidate(g, r, new_v, exits);
} }
@ -193,7 +196,7 @@ void buildInitialCandidate(const AcyclicGraph &g,
DEBUG_PRINTF("adding %zu to initial\n", g[*it].index); DEBUG_PRINTF("adding %zu to initial\n", g[*it].index);
candidate->insert(*it); candidate->insert(*it);
open_jumps->erase(*it); open_jumps->erase(*it);
checkAndAddExitCandidate(g, *candidate, *it, exits); checkAndAddExitCandidate(g, *candidate, *it, *exits);
++it; ++it;
return; return;
} }
@ -218,7 +221,7 @@ void buildInitialCandidate(const AcyclicGraph &g,
open_jumps->clear(); open_jumps->clear();
} }
findExits(g, *candidate, exits); *exits = findExits(g, *candidate);
} }
static static
@ -228,7 +231,6 @@ void findDagLeaders(const NGHolder &h, const AcyclicGraph &g,
assert(!topo.empty()); assert(!topo.empty());
u32 curr_id = 0; u32 curr_id = 0;
vector<NFAVertex>::const_reverse_iterator t_it = topo.rbegin(); vector<NFAVertex>::const_reverse_iterator t_it = topo.rbegin();
vector<exit_info> exits;
ue2::unordered_set<NFAVertex> candidate; ue2::unordered_set<NFAVertex> candidate;
flat_set<NFAVertex> open_jumps; flat_set<NFAVertex> open_jumps;
DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index); DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index);
@ -237,7 +239,8 @@ void findDagLeaders(const NGHolder &h, const AcyclicGraph &g,
DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index); DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index);
assert(t_it != topo.rend()); assert(t_it != topo.rend());
candidate.insert(*t_it++); candidate.insert(*t_it++);
findExits(g, candidate, &exits);
auto exits = findExits(g, candidate);
while (t_it != topo.rend()) { while (t_it != topo.rend()) {
assert(!candidate.empty()); assert(!candidate.empty());
@ -260,7 +263,7 @@ void findDagLeaders(const NGHolder &h, const AcyclicGraph &g,
DEBUG_PRINTF("adding %zu to current\n", g[curr].index); DEBUG_PRINTF("adding %zu to current\n", g[curr].index);
candidate.insert(curr); candidate.insert(curr);
open_jumps.erase(curr); open_jumps.erase(curr);
refineExits(g, candidate, *t_it, &exits); refineExits(g, candidate, *t_it, exits);
DEBUG_PRINTF(" open jumps %zu exits %zu\n", open_jumps.size(), DEBUG_PRINTF(" open jumps %zu exits %zu\n", open_jumps.size(),
exits.size()); exits.size());
++t_it; ++t_it;
@ -416,6 +419,7 @@ vector<NFAVertex> buildTopoOrder(const NGHolder &w,
const AcyclicGraph &acyclic_g, const AcyclicGraph &acyclic_g,
vector<boost::default_color_type> &colours) { vector<boost::default_color_type> &colours) {
vector<NFAVertex> topoOrder; vector<NFAVertex> topoOrder;
topoOrder.reserve(num_vertices(w));
topological_sort(acyclic_g, back_inserter(topoOrder), topological_sort(acyclic_g, back_inserter(topoOrder),
color_map(make_iterator_property_map(colours.begin(), color_map(make_iterator_property_map(colours.begin(),