mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-09-29 19:24:25 +03:00
Introduce custom adjacency-list based graph
This commit is contained in:
@@ -203,6 +203,7 @@ static
|
||||
bool addComponent(NG &ng, NGHolder &g, const NGWrapper &w, const som_type som,
|
||||
const u32 comp_id) {
|
||||
const CompileContext &cc = ng.cc;
|
||||
assert(hasCorrectlyNumberedVertices(g));
|
||||
|
||||
DEBUG_PRINTF("expr=%u, comp=%u: %zu vertices, %zu edges\n",
|
||||
w.expressionIndex, comp_id, num_vertices(g), num_edges(g));
|
||||
|
@@ -202,7 +202,7 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
|
||||
}
|
||||
|
||||
if (!isStartNode(dotV, g.start, g, true)) {
|
||||
DEBUG_PRINTF("fleeing: vertex %u has other preds\n", g[dotV].index);
|
||||
DEBUG_PRINTF("fleeing: vertex %zu has other preds\n", g[dotV].index);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
|
||||
remove_edge(g.start, v, g);
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("removing vertex %u\n", g[dotV].index);
|
||||
DEBUG_PRINTF("removing vertex %zu\n", g[dotV].index);
|
||||
clear_vertex(dotV, g);
|
||||
dead.insert(dotV);
|
||||
compAnchoredStarts.erase(dotV);
|
||||
@@ -313,14 +313,15 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
|
||||
}
|
||||
|
||||
// A self-loop indicates that this is a '.+' or '.*'
|
||||
DEBUG_PRINTF("self-loop detected on %u\n", g[dotV].index);
|
||||
DEBUG_PRINTF("self-loop detected on %zu\n", g[dotV].index);
|
||||
*startEnd = depth::infinity();
|
||||
remove_edge(dotV, dotV, g);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isStartNode(dotV, g.startDs, g, true)) {
|
||||
DEBUG_PRINTF("fleeing: vertex %u has other preds\n", g[dotV].index);
|
||||
DEBUG_PRINTF("fleeing: vertex %zu has other preds\n",
|
||||
g[dotV].index);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,14 +363,14 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
|
||||
compUnanchoredStarts.clear();
|
||||
for (auto t : adjacent_vertices_range(dotV, g)) {
|
||||
if (t != dotV) {
|
||||
DEBUG_PRINTF("connecting sds -> %u\n", g[t].index);
|
||||
DEBUG_PRINTF("connecting sds -> %zu\n", g[t].index);
|
||||
add_edge(g.startDs, t, g);
|
||||
add_edge(g.start, t, g);
|
||||
compUnanchoredStarts.insert(t);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("removing vertex %u\n", g[dotV].index);
|
||||
DEBUG_PRINTF("removing vertex %zu\n", g[dotV].index);
|
||||
dead.insert(dotV);
|
||||
clear_vertex(dotV, g);
|
||||
compUnanchoredStarts.erase(dotV);
|
||||
@@ -416,7 +417,7 @@ bool gatherParticipants(const NGHolder &g,
|
||||
if (isOptionalDot(t, v, g)) {
|
||||
// another dot; bail if we've seen it once already
|
||||
if (dots.find(t) != dots.end()) {
|
||||
DEBUG_PRINTF("cycle detected at vertex %u\n", g[t].index);
|
||||
DEBUG_PRINTF("cycle detected at vertex %zu\n", g[t].index);
|
||||
return false;
|
||||
}
|
||||
dots.insert(t);
|
||||
@@ -432,7 +433,7 @@ bool gatherParticipants(const NGHolder &g,
|
||||
for (auto w : adjacent_vertices_range(v, g)) {
|
||||
succ.insert(w);
|
||||
if (!edge(start, w, g).second) {
|
||||
DEBUG_PRINTF("failing, vertex %u does not have edge from start\n",
|
||||
DEBUG_PRINTF("failing, vertex %zu does not have edge from start\n",
|
||||
g[w].index);
|
||||
return false;
|
||||
}
|
||||
@@ -474,7 +475,7 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
|
||||
return;
|
||||
}
|
||||
initialDot = v;
|
||||
DEBUG_PRINTF("initial dot vertex is %u\n", g[v].index);
|
||||
DEBUG_PRINTF("initial dot vertex is %zu\n", g[v].index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,12 +508,8 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
|
||||
}
|
||||
assert(startEnd->is_reachable());
|
||||
|
||||
// For determinism, copy and sort our successor vertices.
|
||||
deque<NFAVertex> s(succ.begin(), succ.end());
|
||||
sort(s.begin(), s.end(), make_index_ordering(g));
|
||||
|
||||
// Connect our successor vertices to both start and startDs.
|
||||
for (auto v : s) {
|
||||
for (auto v : succ) {
|
||||
add_edge_if_not_present(g.start, v, g);
|
||||
add_edge_if_not_present(g.startDs, v, g);
|
||||
}
|
||||
@@ -637,8 +634,8 @@ void restoreLeadingDots(NGHolder &g, const depth &startBegin,
|
||||
}
|
||||
|
||||
addDotsBetween(g, root, rhs, startBegin, startEnd);
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
}
|
||||
|
||||
// Entry point.
|
||||
|
@@ -101,7 +101,7 @@ vector<NFAEdge> getAsserts(const NGHolder &g) {
|
||||
|
||||
static
|
||||
void addToSplit(const NGHolder &g, NFAVertex v, map<u32, NFAVertex> *to_split) {
|
||||
DEBUG_PRINTF("%u needs splitting\n", g[v].index);
|
||||
DEBUG_PRINTF("%zu needs splitting\n", g[v].index);
|
||||
to_split->emplace(g[v].index, v);
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ void setReportId(ReportManager &rm, NGWrapper &g, NFAVertex v, s32 adj) {
|
||||
Report ir = rm.getBasicInternalReport(g, adj);
|
||||
|
||||
g[v].reports.insert(rm.getInternalId(ir));
|
||||
DEBUG_PRINTF("set report id for vertex %u, adj %d\n", g[v].index, adj);
|
||||
DEBUG_PRINTF("set report id for vertex %zu, adj %d\n", g[v].index, adj);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -224,7 +224,7 @@ void splitVertex(ReportManager &rm, NGWrapper &g, NFAVertex v, bool ucp) {
|
||||
assert(v != g.start);
|
||||
assert(v != g.accept);
|
||||
assert(v != g.acceptEod);
|
||||
DEBUG_PRINTF("partitioning vertex %u ucp:%d\n", g[v].index, (int)ucp);
|
||||
DEBUG_PRINTF("partitioning vertex %zu ucp:%d\n", g[v].index, (int)ucp);
|
||||
|
||||
CharReach cr_word = ucp ? CHARREACH_WORD_UCP_PRE : CHARREACH_WORD;
|
||||
CharReach cr_nonword = ucp ? CHARREACH_NONWORD_UCP_PRE : CHARREACH_NONWORD;
|
||||
@@ -267,8 +267,8 @@ void resolveEdges(ReportManager &rm, NGWrapper &g, set<NFAEdge> *dead) {
|
||||
|
||||
bool impassable = true;
|
||||
bool ucp = flags & UCP_ASSERT_FLAGS;
|
||||
DEBUG_PRINTF("resolving edge %u->%u (flags=0x%x, ucp=%d)\n", g[u].index,
|
||||
g[v].index, flags, (int)ucp);
|
||||
DEBUG_PRINTF("resolving edge %zu->%zu (flags=0x%x, ucp=%d)\n",
|
||||
g[u].index, g[v].index, flags, (int)ucp);
|
||||
while (flags && impassable) {
|
||||
u32 flag = 1U << findAndClearLSB_32(&flags);
|
||||
switch (flag) {
|
||||
@@ -482,12 +482,12 @@ void resolveAsserts(ReportManager &rm, NGWrapper &g) {
|
||||
resolveEdges(rm, g, &dead);
|
||||
|
||||
remove_edges(dead, g);
|
||||
g.renumberVertices();
|
||||
renumber_vertices(g);
|
||||
pruneUseless(g);
|
||||
pruneEmptyVertices(g);
|
||||
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
clearReports(g);
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ void ensureCodePointStart(ReportManager &rm, NGWrapper &g) {
|
||||
add_edge(g.start, v_4, g);
|
||||
add_edge(g.startDs, v_4, g);
|
||||
remove_edge(orig, g);
|
||||
g.renumberEdges();
|
||||
renumber_edges(g);
|
||||
clearReports(g);
|
||||
}
|
||||
}
|
||||
|
@@ -132,7 +132,7 @@ NFAVertex NFABuilderImpl::getVertex(Position pos) const {
|
||||
assert(id2vertex.size() >= pos);
|
||||
const NFAVertex v = id2vertex[pos];
|
||||
assert(v != NGHolder::null_vertex());
|
||||
assert(graph->g[v].index == pos);
|
||||
assert((*graph)[v].index == pos);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ void NFABuilderImpl::addVertex(Position pos) {
|
||||
id2vertex.resize(pos + 1);
|
||||
}
|
||||
id2vertex[pos] = v;
|
||||
graph->g[v].index = pos;
|
||||
(*graph)[v].index = pos;
|
||||
}
|
||||
|
||||
unique_ptr<NGWrapper> NFABuilderImpl::getGraph() {
|
||||
@@ -177,22 +177,22 @@ void NFABuilderImpl::setNodeReportID(Position pos, int offsetAdjust) {
|
||||
|
||||
void NFABuilderImpl::addCharReach(Position pos, const CharReach &cr) {
|
||||
NFAVertex v = getVertex(pos);
|
||||
graph->g[v].char_reach |= cr;
|
||||
(*graph)[v].char_reach |= cr;
|
||||
}
|
||||
|
||||
void NFABuilderImpl::setAssertFlag(Position pos, u32 flag) {
|
||||
NFAVertex v = getVertex(pos);
|
||||
graph->g[v].assert_flags |= flag;
|
||||
(*graph)[v].assert_flags |= flag;
|
||||
}
|
||||
|
||||
u32 NFABuilderImpl::getAssertFlag(Position pos) {
|
||||
NFAVertex v = getVertex(pos);
|
||||
return graph->g[v].assert_flags;
|
||||
return (*graph)[v].assert_flags;
|
||||
}
|
||||
|
||||
pair<NFAEdge, bool> NFABuilderImpl::addEdge(NFAVertex u, NFAVertex v) {
|
||||
// assert that the edge doesn't already exist
|
||||
assert(edge(u, v, graph->g).second == false);
|
||||
assert(edge(u, v, *graph).second == false);
|
||||
|
||||
pair<NFAEdge, bool> e = add_edge(u, v, *graph);
|
||||
assert(e.second);
|
||||
@@ -209,16 +209,16 @@ void NFABuilderImpl::addEdge(Position startPos, Position endPos) {
|
||||
|
||||
if ((u == graph->start || u == graph->startDs) && v == graph->startDs) {
|
||||
/* standard special -> special edges already exist */
|
||||
assert(edge(u, v, graph->g).second == true);
|
||||
assert(edge(u, v, *graph).second == true);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(edge(u, v, graph->g).second == false);
|
||||
assert(edge(u, v, *graph).second == false);
|
||||
addEdge(u, v);
|
||||
}
|
||||
|
||||
bool NFABuilderImpl::hasEdge(Position startPos, Position endPos) const {
|
||||
return edge(getVertex(startPos), getVertex(endPos), graph->g).second;
|
||||
return edge(getVertex(startPos), getVertex(endPos), *graph).second;
|
||||
}
|
||||
|
||||
Position NFABuilderImpl::getStart() const {
|
||||
@@ -252,7 +252,7 @@ Position NFABuilderImpl::makePositions(size_t nPositions) {
|
||||
}
|
||||
|
||||
void NFABuilderImpl::cloneRegion(Position first, Position last, unsigned posOffset) {
|
||||
NFAGraph &g = graph->g;
|
||||
NGHolder &g = *graph;
|
||||
assert(posOffset > 0);
|
||||
|
||||
// walk the nodes between first and last and copy their vertex properties
|
||||
|
@@ -162,7 +162,7 @@ flat_set<NFAVertex> findHeadShell(const NGHolder &g,
|
||||
}
|
||||
|
||||
for (UNUSED auto v : shell) {
|
||||
DEBUG_PRINTF("shell: %u\n", g[v].index);
|
||||
DEBUG_PRINTF("shell: %zu\n", g[v].index);
|
||||
}
|
||||
|
||||
return shell;
|
||||
@@ -184,7 +184,7 @@ flat_set<NFAVertex> findTailShell(const NGHolder &g,
|
||||
}
|
||||
|
||||
for (UNUSED auto v : shell) {
|
||||
DEBUG_PRINTF("shell: %u\n", g[v].index);
|
||||
DEBUG_PRINTF("shell: %zu\n", g[v].index);
|
||||
}
|
||||
|
||||
return shell;
|
||||
@@ -209,7 +209,8 @@ vector<NFAEdge> findShellEdges(const NGHolder &g,
|
||||
|
||||
if ((is_special(u, g) || contains(head_shell, u)) &&
|
||||
(is_special(v, g) || contains(tail_shell, v))) {
|
||||
DEBUG_PRINTF("edge (%u,%u) is a shell edge\n", g[u].index, g[v].index);
|
||||
DEBUG_PRINTF("edge (%zu,%zu) is a shell edge\n", g[u].index,
|
||||
g[v].index);
|
||||
shell_edges.push_back(e);
|
||||
}
|
||||
}
|
||||
@@ -275,9 +276,8 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
|
||||
|
||||
NFAUndirectedGraph ug;
|
||||
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> old2new;
|
||||
ue2::unordered_map<u32, NFAVertex> newIdx2old;
|
||||
|
||||
createUnGraph(g.g, true, true, ug, old2new, newIdx2old);
|
||||
createUnGraph(g, true, true, ug, old2new);
|
||||
|
||||
// Construct reverse mapping.
|
||||
ue2::unordered_map<NFAUndirectedVertex, NFAVertex> new2old;
|
||||
@@ -313,7 +313,7 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
|
||||
assert(contains(new2old, uv));
|
||||
NFAVertex v = new2old.at(uv);
|
||||
verts[c].push_back(v);
|
||||
DEBUG_PRINTF("vertex %u is in comp %u\n", g[v].index, c);
|
||||
DEBUG_PRINTF("vertex %zu is in comp %u\n", g[v].index, c);
|
||||
}
|
||||
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> v_map; // temp map for fillHolder
|
||||
@@ -322,8 +322,9 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
|
||||
vv.insert(vv.end(), begin(head_shell), end(head_shell));
|
||||
vv.insert(vv.end(), begin(tail_shell), end(tail_shell));
|
||||
|
||||
// Sort by vertex index for determinism.
|
||||
sort(begin(vv), end(vv), VertexIndexOrdering<NGHolder>(g));
|
||||
/* Sort for determinism. Still required as NFAUndirectedVertex have
|
||||
* no deterministic ordering (split_components map). */
|
||||
sort(begin(vv), end(vv));
|
||||
|
||||
auto gc = ue2::make_unique<NGHolder>();
|
||||
v_map.clear();
|
||||
@@ -349,9 +350,6 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
|
||||
vv.insert(vv.end(), begin(head_shell), end(head_shell));
|
||||
vv.insert(vv.end(), begin(tail_shell), end(tail_shell));
|
||||
|
||||
// Sort by vertex index for determinism.
|
||||
sort(begin(vv), end(vv), VertexIndexOrdering<NGHolder>(g));
|
||||
|
||||
auto gc = ue2::make_unique<NGHolder>();
|
||||
v_map.clear();
|
||||
fillHolder(gc.get(), g, vv, &v_map);
|
||||
|
@@ -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:
|
||||
@@ -99,7 +99,7 @@ class SearchVisitor : public boost::default_dfs_visitor {
|
||||
|
||||
template<class Vertex, class Graph>
|
||||
void discover_vertex(const Vertex &v, const Graph &g) const {
|
||||
DEBUG_PRINTF("vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu\n", g[v].index);
|
||||
if (is_special(v, g)) {
|
||||
DEBUG_PRINTF("start or accept\n");
|
||||
throw SearchFailed();
|
||||
@@ -141,24 +141,16 @@ bool searchForward(const Graph &g, const CharReach &reach,
|
||||
}
|
||||
|
||||
static
|
||||
NFAEdge to_raw(const NFAEdge &e, const NFAGraph &, const NGHolder &) {
|
||||
NFAEdge to_raw(const NFAEdge &e, const NGHolder &) {
|
||||
return e;
|
||||
}
|
||||
|
||||
static
|
||||
NFAEdge to_raw(const reverse_graph<NFAGraph, NFAGraph&>::edge_descriptor &e,
|
||||
const reverse_graph<NFAGraph, NFAGraph&> &g,
|
||||
const NGHolder &raw) {
|
||||
/* clang doesn't seem to like edge_underlying */
|
||||
NFAVertex t = source(e, g);
|
||||
NFAVertex s = target(e, g);
|
||||
|
||||
assert(edge(s, t, raw).second);
|
||||
|
||||
return edge(s, t, raw).first;
|
||||
NFAEdge to_raw(const reverse_graph<NGHolder, NGHolder &>::edge_descriptor &e,
|
||||
const reverse_graph<NGHolder, NGHolder &> &g) {
|
||||
return get(boost::edge_underlying, g, e);
|
||||
}
|
||||
|
||||
|
||||
/* returns true if we did stuff */
|
||||
template<class Graph>
|
||||
static
|
||||
@@ -185,7 +177,7 @@ bool removeCyclicPathRedundancy(Graph &g, typename Graph::vertex_descriptor v,
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("- checking u %u\n", g[u].index);
|
||||
DEBUG_PRINTF("- checking u %zu\n", g[u].index);
|
||||
|
||||
// let s be intersection(succ(u), succ(v))
|
||||
s.clear();
|
||||
@@ -206,17 +198,18 @@ bool removeCyclicPathRedundancy(Graph &g, typename Graph::vertex_descriptor v,
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF(" - checking w %u\n", g[w].index);
|
||||
DEBUG_PRINTF(" - checking w %zu\n", g[w].index);
|
||||
|
||||
if (searchForward(g, reach, s, w)) {
|
||||
DEBUG_PRINTF("removing edge (%u,%u)\n",
|
||||
g[u].index, g[w].index);
|
||||
/* we are currently iterating over the in-edges of v, so it
|
||||
would be unwise to remove edges to v. However, */
|
||||
assert(w != v); /* as v is in s */
|
||||
remove_edge(to_raw(e_u, g, raw), raw);
|
||||
did_stuff = true;
|
||||
if (!searchForward(g, reach, s, w)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("removing edge (%zu,%zu)\n", g[u].index, g[w].index);
|
||||
/* we are currently iterating over the in-edges of v, so it
|
||||
would be unwise to remove edges to v. However, */
|
||||
assert(w != v); /* as v is in s */
|
||||
remove_edge(to_raw(e_u, g), raw);
|
||||
did_stuff = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +226,7 @@ bool cyclicPathRedundancyPass(Graph &g, NGHolder &raw) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("examining cyclic vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("examining cyclic vertex %zu\n", g[v].index);
|
||||
did_stuff |= removeCyclicPathRedundancy(g, v, raw);
|
||||
}
|
||||
|
||||
@@ -242,7 +235,7 @@ bool cyclicPathRedundancyPass(Graph &g, NGHolder &raw) {
|
||||
|
||||
bool removeCyclicPathRedundancy(NGHolder &g) {
|
||||
// Forward pass.
|
||||
bool f_changed = cyclicPathRedundancyPass(g.g, g);
|
||||
bool f_changed = cyclicPathRedundancyPass(g, g);
|
||||
if (f_changed) {
|
||||
DEBUG_PRINTF("edges removed by forward pass\n");
|
||||
pruneUseless(g);
|
||||
@@ -250,8 +243,8 @@ bool removeCyclicPathRedundancy(NGHolder &g) {
|
||||
|
||||
// Reverse pass.
|
||||
DEBUG_PRINTF("REVERSE PASS\n");
|
||||
typedef reverse_graph<NFAGraph, NFAGraph&> RevGraph;
|
||||
RevGraph revg(g.g);
|
||||
typedef reverse_graph<NGHolder, NGHolder &> RevGraph;
|
||||
RevGraph revg(g);
|
||||
bool r_changed = cyclicPathRedundancyPass(revg, g);
|
||||
if (r_changed) {
|
||||
DEBUG_PRINTF("edges removed by reverse pass\n");
|
||||
|
@@ -44,11 +44,14 @@
|
||||
#include <boost/graph/reverse_graph.hpp>
|
||||
#include <boost/graph/topological_sort.hpp>
|
||||
#include <boost/graph/property_maps/constant_property_map.hpp>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
using namespace std;
|
||||
using boost::filtered_graph;
|
||||
using boost::make_filtered_graph;
|
||||
using boost::make_constant_property;
|
||||
using boost::reverse_graph;
|
||||
using boost::adaptors::reverse;
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
@@ -122,25 +125,23 @@ private:
|
||||
|
||||
template<class GraphT>
|
||||
static
|
||||
void findLoopReachable(const GraphT &g, const NFAVertex srcVertex,
|
||||
void findLoopReachable(const GraphT &g,
|
||||
const typename GraphT::vertex_descriptor srcVertex,
|
||||
vector<bool> &deadNodes) {
|
||||
typedef typename GraphT::edge_descriptor EdgeT;
|
||||
typedef typename GraphT::vertex_descriptor VertexT;
|
||||
typedef set<EdgeT> EdgeSet;
|
||||
|
||||
EdgeSet deadEdges;
|
||||
BackEdges<EdgeSet> be(deadEdges);
|
||||
|
||||
auto index_map = get(&NFAGraphVertexProps::index, g);
|
||||
|
||||
depth_first_search(g, visitor(be).root_vertex(srcVertex).vertex_index_map(
|
||||
index_map));
|
||||
depth_first_search(g, visitor(be).root_vertex(srcVertex));
|
||||
auto af = make_bad_edge_filter(&deadEdges);
|
||||
auto acyclic_g = make_filtered_graph(g, af);
|
||||
|
||||
vector<NFAVertex> topoOrder; /* actually reverse topological order */
|
||||
vector<VertexT> topoOrder; /* actually reverse topological order */
|
||||
topoOrder.reserve(deadNodes.size());
|
||||
topological_sort(acyclic_g, back_inserter(topoOrder),
|
||||
vertex_index_map(index_map));
|
||||
topological_sort(acyclic_g, back_inserter(topoOrder));
|
||||
|
||||
for (const auto &e : deadEdges) {
|
||||
u32 srcIdx = g[source(e, g)].index;
|
||||
@@ -149,8 +150,7 @@ void findLoopReachable(const GraphT &g, const NFAVertex srcVertex,
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = topoOrder.rbegin(); it != topoOrder.rend(); ++it) {
|
||||
NFAVertex v = *it;
|
||||
for (VertexT v : reverse(topoOrder)) {
|
||||
for (const auto &e : in_edges_range(v, g)) {
|
||||
if (deadNodes[g[source(e, g)].index]) {
|
||||
deadNodes[g[v].index] = true;
|
||||
@@ -194,22 +194,20 @@ void calcDepthFromSource(const NGHolder &graph, const GraphT &g,
|
||||
|
||||
using boost::make_iterator_property_map;
|
||||
|
||||
auto min_index_map = get(&NFAGraphVertexProps::index, mindist_g);
|
||||
auto min_index_map = get(vertex_index, mindist_g);
|
||||
|
||||
breadth_first_search(mindist_g, srcVertex,
|
||||
boost::vertex_index_map(min_index_map).
|
||||
visitor(make_bfs_visitor(record_distances(
|
||||
make_iterator_property_map(
|
||||
dMin.begin(), min_index_map),
|
||||
make_iterator_property_map(dMin.begin(),
|
||||
min_index_map),
|
||||
boost::on_tree_edge()))));
|
||||
|
||||
auto max_index_map = get(&NFAGraphVertexProps::index, maxdist_g);
|
||||
auto max_index_map = get(vertex_index, maxdist_g);
|
||||
|
||||
dag_shortest_paths(maxdist_g, srcVertex,
|
||||
boost::vertex_index_map(max_index_map).
|
||||
distance_map(make_iterator_property_map(dMax.begin(),
|
||||
max_index_map)).
|
||||
weight_map(make_constant_property<EdgeT>(-1)));
|
||||
distance_map(make_iterator_property_map(dMax.begin(),
|
||||
max_index_map))
|
||||
.weight_map(make_constant_property<EdgeT>(-1)));
|
||||
|
||||
for (size_t i = 0; i < numVerts; i++) {
|
||||
if (dMin[i] > DIST_UNREACHABLE) {
|
||||
@@ -285,14 +283,14 @@ void calcDepths(const NGHolder &g, std::vector<NFAVertexDepth> &depths) {
|
||||
* reachable from a loop need to be removed
|
||||
*/
|
||||
vector<bool> deadNodes(numVertices);
|
||||
findLoopReachable(g.g, g.start, deadNodes);
|
||||
findLoopReachable(g, g.start, deadNodes);
|
||||
|
||||
DEBUG_PRINTF("doing start\n");
|
||||
calcAndStoreDepth(g, g.g, g.start, deadNodes, dMin, dMax,
|
||||
depths, &NFAVertexDepth::fromStart);
|
||||
calcAndStoreDepth(g, g, g.start, deadNodes, dMin, dMax, depths,
|
||||
&NFAVertexDepth::fromStart);
|
||||
DEBUG_PRINTF("doing startds\n");
|
||||
calcAndStoreDepth(g, g.g, g.startDs, deadNodes, dMin, dMax,
|
||||
depths, &NFAVertexDepth::fromStartDotStar);
|
||||
calcAndStoreDepth(g, g, g.startDs, deadNodes, dMin, dMax, depths,
|
||||
&NFAVertexDepth::fromStartDotStar);
|
||||
}
|
||||
|
||||
void calcDepths(const NGHolder &g, std::vector<NFAVertexRevDepth> &depths) {
|
||||
@@ -305,8 +303,8 @@ void calcDepths(const NGHolder &g, std::vector<NFAVertexRevDepth> &depths) {
|
||||
vector<int> dMax;
|
||||
|
||||
/* reverse the graph before walking it */
|
||||
typedef reverse_graph<NFAGraph, const NFAGraph&> RevNFAGraph;
|
||||
const RevNFAGraph rg(g.g);
|
||||
typedef reverse_graph<NGHolder, const NGHolder &> RevNFAGraph;
|
||||
const RevNFAGraph rg(g);
|
||||
|
||||
/*
|
||||
* create a filtered graph for max depth calculations: all nodes/edges
|
||||
@@ -340,20 +338,20 @@ void calcDepths(const NGHolder &g, vector<NFAVertexBidiDepth> &depths) {
|
||||
* reachable from a loop need to be removed
|
||||
*/
|
||||
vector<bool> deadNodes(numVertices);
|
||||
findLoopReachable(g.g, g.start, deadNodes);
|
||||
findLoopReachable(g, g.start, deadNodes);
|
||||
|
||||
DEBUG_PRINTF("doing start\n");
|
||||
calcAndStoreDepth<NFAGraph, NFAVertexBidiDepth>(
|
||||
g, g.g, g.start, deadNodes, dMin, dMax, depths,
|
||||
calcAndStoreDepth<NGHolder, NFAVertexBidiDepth>(
|
||||
g, g, g.start, deadNodes, dMin, dMax, depths,
|
||||
&NFAVertexBidiDepth::fromStart);
|
||||
DEBUG_PRINTF("doing startds\n");
|
||||
calcAndStoreDepth<NFAGraph, NFAVertexBidiDepth>(
|
||||
g, g.g, g.startDs, deadNodes, dMin, dMax, depths,
|
||||
calcAndStoreDepth<NGHolder, NFAVertexBidiDepth>(
|
||||
g, g, g.startDs, deadNodes, dMin, dMax, depths,
|
||||
&NFAVertexBidiDepth::fromStartDotStar);
|
||||
|
||||
/* Now go backwards */
|
||||
typedef reverse_graph<NFAGraph, const NFAGraph&> RevNFAGraph;
|
||||
const RevNFAGraph rg(g.g);
|
||||
typedef reverse_graph<NGHolder, const NGHolder &> RevNFAGraph;
|
||||
const RevNFAGraph rg(g);
|
||||
deadNodes.assign(numVertices, false);
|
||||
findLoopReachable(rg, g.acceptEod, deadNodes);
|
||||
|
||||
@@ -374,10 +372,10 @@ void calcDepthsFrom(const NGHolder &g, const NFAVertex src,
|
||||
const size_t numVertices = num_vertices(g);
|
||||
|
||||
vector<bool> deadNodes(numVertices);
|
||||
findLoopReachable(g.g, g.start, deadNodes);
|
||||
findLoopReachable(g, g.start, deadNodes);
|
||||
|
||||
vector<int> dMin, dMax;
|
||||
calcDepthFromSource(g, g.g, src, deadNodes, dMin, dMax);
|
||||
calcDepthFromSource(g, g, src, deadNodes, dMin, dMax);
|
||||
|
||||
depths.clear();
|
||||
depths.resize(numVertices);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-16, 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:
|
||||
@@ -48,37 +48,45 @@ using boost::make_iterator_property_map;
|
||||
namespace ue2 {
|
||||
|
||||
template <class Graph>
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> calcDominators(const Graph &g,
|
||||
NFAVertex source) {
|
||||
unordered_map<NFAVertex, NFAVertex> calcDominators(const Graph &g,
|
||||
typename Graph::vertex_descriptor source) {
|
||||
using Vertex = typename Graph::vertex_descriptor;
|
||||
const size_t num_verts = num_vertices(g);
|
||||
auto index_map = get(&NFAGraphVertexProps::index, g);
|
||||
|
||||
vector<size_t> dfnum(num_verts, 0);
|
||||
vector<NFAVertex> parents(num_verts, Graph::null_vertex());
|
||||
vector<Vertex> parents(num_verts, Graph::null_vertex());
|
||||
|
||||
auto dfnum_map = make_iterator_property_map(dfnum.begin(), index_map);
|
||||
auto parent_map = make_iterator_property_map(parents.begin(), index_map);
|
||||
vector<NFAVertex> vertices_by_dfnum(num_verts, Graph::null_vertex());
|
||||
vector<Vertex> vertices_by_dfnum(num_verts, Graph::null_vertex());
|
||||
|
||||
// Output map.
|
||||
unordered_map<NFAVertex, NFAVertex> doms;
|
||||
unordered_map<Vertex, Vertex> doms;
|
||||
auto dom_map = make_assoc_property_map(doms);
|
||||
|
||||
boost_ue2::lengauer_tarjan_dominator_tree(g, source, index_map, dfnum_map,
|
||||
parent_map, vertices_by_dfnum,
|
||||
dom_map);
|
||||
|
||||
return doms;
|
||||
/* Translate back to an NFAVertex map */
|
||||
unordered_map<NFAVertex, NFAVertex> doms2;
|
||||
for (const auto &e : doms) {
|
||||
NFAVertex f(e.first);
|
||||
NFAVertex s(e.second);
|
||||
doms2[f] = s;
|
||||
}
|
||||
return doms2;
|
||||
}
|
||||
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> findDominators(const NGHolder &g) {
|
||||
unordered_map<NFAVertex, NFAVertex> findDominators(const NGHolder &g) {
|
||||
assert(hasCorrectlyNumberedVertices(g));
|
||||
return calcDominators(g.g, g.start);
|
||||
return calcDominators(g, g.start);
|
||||
}
|
||||
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> findPostDominators(const NGHolder &g) {
|
||||
unordered_map<NFAVertex, NFAVertex> findPostDominators(const NGHolder &g) {
|
||||
assert(hasCorrectlyNumberedVertices(g));
|
||||
return calcDominators(boost::reverse_graph<NFAGraph, const NFAGraph &>(g.g),
|
||||
return calcDominators(boost::reverse_graph<NGHolder, const NGHolder &>(g),
|
||||
g.acceptEod);
|
||||
}
|
||||
|
||||
|
@@ -285,7 +285,7 @@ void dumpGraphImpl(const char *name, const GraphT &g,
|
||||
}
|
||||
|
||||
// manual instantiation of templated dumpGraph above.
|
||||
template void dumpGraphImpl(const char *, const NFAGraph &);
|
||||
template void dumpGraphImpl(const char *, const NGHolder &);
|
||||
|
||||
void dumpDotWrapperImpl(const NGWrapper &nw, const char *name,
|
||||
const Grey &grey) {
|
||||
@@ -293,7 +293,7 @@ void dumpDotWrapperImpl(const NGWrapper &nw, const char *name,
|
||||
stringstream ss;
|
||||
ss << grey.dumpPath << "Expr_" << nw.expressionIndex << "_" << name << ".dot";
|
||||
DEBUG_PRINTF("dumping dot graph to '%s'\n", ss.str().c_str());
|
||||
dumpGraphImpl(ss.str().c_str(), nw.g);
|
||||
dumpGraphImpl(ss.str().c_str(), nw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ void dumpComponentImpl(const NGHolder &g, const char *name, u32 expr,
|
||||
ss << grey.dumpPath << "Comp_" << expr << "-" << comp << "_"
|
||||
<< name << ".dot";
|
||||
DEBUG_PRINTF("dumping dot graph to '%s'\n", ss.str().c_str());
|
||||
dumpGraphImpl(ss.str().c_str(), g.g);
|
||||
dumpGraphImpl(ss.str().c_str(), g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ void dumpSomSubComponentImpl(const NGHolder &g, const char *name, u32 expr,
|
||||
ss << grey.dumpPath << "Comp_" << expr << "-" << comp << "_"
|
||||
<< name << "_" << plan << ".dot";
|
||||
DEBUG_PRINTF("dumping dot graph to '%s'\n", ss.str().c_str());
|
||||
dumpGraphImpl(ss.str().c_str(), g.g);
|
||||
dumpGraphImpl(ss.str().c_str(), g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ void dumpHolderImpl(const NGHolder &h, unsigned int stageNumber,
|
||||
stringstream ss;
|
||||
ss << grey.dumpPath << "Holder_X_" << stageNumber
|
||||
<< "-" << stageName << ".dot";
|
||||
dumpGraphImpl(ss.str().c_str(), h.g);
|
||||
dumpGraphImpl(ss.str().c_str(), h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ void dumpHolderImpl(const NGHolder &h,
|
||||
stringstream ss;
|
||||
ss << grey.dumpPath << "Holder_X_" << stageNumber
|
||||
<< "-" << stageName << ".dot";
|
||||
dumpGraphImpl(ss.str().c_str(), h.g, region_map);
|
||||
dumpGraphImpl(ss.str().c_str(), h, region_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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:
|
||||
@@ -297,9 +297,8 @@ bool checkFwdCandidate(const NGHolder &g, NFAVertex fixed_src,
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("edge (%u, %u) killed by edge (%u, %u)\n",
|
||||
g[w].index, g[v].index,
|
||||
g[fixed_src].index, g[v].index);
|
||||
DEBUG_PRINTF("edge (%zu, %zu) killed by edge (%zu, %zu)\n",
|
||||
g[w].index, g[v].index, g[fixed_src].index, g[v].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -415,7 +414,7 @@ bool removeEdgeRedundancyFwd(NGHolder &g, bool ignore_starts) {
|
||||
pred(g, u, &parents_u);
|
||||
|
||||
done.clear();
|
||||
if (hasGreaterOutDegree(1, u, g)) {
|
||||
if (out_degree(u, g) > 1) {
|
||||
checkLargeOutU(g, u, parents_u, possible_w, done, &dead);
|
||||
} else {
|
||||
checkSmallOutU(g, u, parents_u, done, &dead);
|
||||
@@ -460,7 +459,7 @@ bool removeSiblingsOfStartDotStar(NGHolder &g) {
|
||||
vector<NFAEdge> dead;
|
||||
|
||||
for (auto v : adjacent_vertices_range(g.startDs, g)) {
|
||||
DEBUG_PRINTF("checking %u\n", g[v].index);
|
||||
DEBUG_PRINTF("checking %zu\n", g[v].index);
|
||||
if (is_special(v, g)) {
|
||||
continue;
|
||||
}
|
||||
@@ -470,8 +469,7 @@ bool removeSiblingsOfStartDotStar(NGHolder &g) {
|
||||
if (is_special(u, g)) {
|
||||
continue;
|
||||
}
|
||||
DEBUG_PRINTF("removing %u->%u\n", g[u].index,
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("removing %zu->%zu\n", g[u].index, g[v].index);
|
||||
dead.push_back(e);
|
||||
}
|
||||
}
|
||||
|
@@ -77,7 +77,7 @@ public:
|
||||
flat_set<VertexInfo *, VertexInfoPtrCmp> pred; //!< predecessors of this vertex
|
||||
flat_set<VertexInfo *, VertexInfoPtrCmp> succ; //!< successors of this vertex
|
||||
NFAVertex v;
|
||||
u32 vert_index;
|
||||
size_t vert_index;
|
||||
CharReach cr;
|
||||
CharReach pred_cr;
|
||||
CharReach succ_cr;
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
vertex_flags(vi.vertex_flags), edge_tops(vi.edge_tops), cr(vi.cr),
|
||||
adjacent_cr(eq == LEFT_EQUIVALENCE ? vi.pred_cr : vi.succ_cr),
|
||||
/* treat non-special vertices the same */
|
||||
node_type(min(g[vi.v].index, u32{N_SPECIALS})), depth(d_in) {}
|
||||
node_type(min(g[vi.v].index, size_t{N_SPECIALS})), depth(d_in) {}
|
||||
|
||||
bool operator==(const ClassInfo &b) const {
|
||||
return node_type == b.node_type && depth.d1 == b.depth.d1 &&
|
||||
@@ -678,7 +678,7 @@ bool reduceGraphEquivalences(NGHolder &g, const CompileContext &cc) {
|
||||
DEBUG_PRINTF("equivalence processing disabled in grey box\n");
|
||||
return false;
|
||||
}
|
||||
g.renumberVertices();
|
||||
renumber_vertices(g);
|
||||
|
||||
// Cheap check: if all the non-special vertices have in-degree one and
|
||||
// out-degree one, there's no redundancy in this here graph and we can
|
||||
|
@@ -183,8 +183,6 @@ flat_set<NFAVertex> execute_graph(const NGHolder &g,
|
||||
return getVertices(work_states, info);
|
||||
}
|
||||
|
||||
typedef boost::reverse_graph<const NFAGraph, const NFAGraph &> RevNFAGraph;
|
||||
|
||||
namespace {
|
||||
class eg_visitor : public boost::default_dfs_visitor {
|
||||
public:
|
||||
@@ -195,13 +193,14 @@ public:
|
||||
info(info_in), input_g(input_g_in), states(states_in),
|
||||
succs(vertex_count) {}
|
||||
|
||||
void finish_vertex(NFAVertex input_v, const RevNFAGraph &) {
|
||||
void finish_vertex(NFAVertex input_v,
|
||||
const boost::reverse_graph<NGHolder, const NGHolder &> &) {
|
||||
if (input_v == input_g.accept) {
|
||||
return;
|
||||
}
|
||||
assert(input_v != input_g.acceptEod);
|
||||
|
||||
DEBUG_PRINTF("finished p%u\n", input_g[input_v].index);
|
||||
DEBUG_PRINTF("finished p%zu\n", input_g[input_v].index);
|
||||
|
||||
/* finish vertex is called on vertex --> implies that all its parents
|
||||
* (in the forward graph) are also finished. Our parents will have
|
||||
@@ -236,7 +235,7 @@ public:
|
||||
/* we need to push into all our (forward) children their successors
|
||||
* from us. */
|
||||
for (auto v : adjacent_vertices_range(input_v, input_g)) {
|
||||
DEBUG_PRINTF("pushing our states to pstate %u\n",
|
||||
DEBUG_PRINTF("pushing our states to pstate %zu\n",
|
||||
input_g[v].index);
|
||||
if (v == input_g.startDs) {
|
||||
/* no need for intra start edges */
|
||||
@@ -289,7 +288,7 @@ flat_set<NFAVertex> execute_graph(const NGHolder &running_g,
|
||||
map<NFAVertex, boost::default_color_type> colours;
|
||||
/* could just a topo order, but really it is time to pull a slightly bigger
|
||||
* gun: DFS */
|
||||
RevNFAGraph revg(input_dag.g);
|
||||
boost::reverse_graph<NGHolder, const NGHolder &> revg(input_dag);
|
||||
map<NFAVertex, dynamic_bitset<> > dfs_states;
|
||||
|
||||
auto info = makeInfoTable(running_g);
|
||||
@@ -308,7 +307,7 @@ flat_set<NFAVertex> execute_graph(const NGHolder &running_g,
|
||||
#ifdef DEBUG
|
||||
DEBUG_PRINTF(" output rstates:");
|
||||
for (const auto &v : states) {
|
||||
printf(" %u", running_g[v].index);
|
||||
printf(" %zu", running_g[v].index);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
@@ -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:
|
||||
@@ -118,7 +118,7 @@ void checkVertex(const ReportManager &rm, const NGWrapper &w, NFAVertex v,
|
||||
rd.max = min(rd.max, max_offset);
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("vertex %u report %u: %s\n", w[v].index, report_id,
|
||||
DEBUG_PRINTF("vertex %zu report %u: %s\n", w[v].index, report_id,
|
||||
rd.str().c_str());
|
||||
|
||||
info = unionDepthMinMax(info, rd);
|
||||
|
@@ -172,8 +172,7 @@ void updateReportBounds(ReportManager &rm, NGWrapper &g, NFAVertex accept,
|
||||
new_reports.insert(rm.getInternalId(ir));
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("swapping reports on vertex %u\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("swapping reports on vertex %zu\n", g[v].index);
|
||||
reports.swap(new_reports);
|
||||
}
|
||||
}
|
||||
@@ -286,8 +285,8 @@ bool anchorPatternWithBoundedRepeat(NGWrapper &g, const depth &minWidth,
|
||||
add_edge(u, v, g);
|
||||
}
|
||||
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -309,7 +308,7 @@ NFAVertex findSingleCyclic(const NGHolder &g) {
|
||||
}
|
||||
|
||||
if (v != NGHolder::null_vertex()) {
|
||||
DEBUG_PRINTF("cyclic is %u\n", g[v].index);
|
||||
DEBUG_PRINTF("cyclic is %zu\n", g[v].index);
|
||||
assert(!is_special(v, g));
|
||||
}
|
||||
return v;
|
||||
@@ -380,7 +379,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
|
||||
// Walk from the start vertex to the cyclic state and ensure we have a
|
||||
// chain of vertices.
|
||||
while (v != cyclic) {
|
||||
DEBUG_PRINTF("vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu\n", g[v].index);
|
||||
width++;
|
||||
auto succ = succs(v, g);
|
||||
if (contains(succ, cyclic)) {
|
||||
@@ -418,7 +417,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
|
||||
// Walk from the cyclic state to an accept and ensure we have a chain of
|
||||
// vertices.
|
||||
while (!is_any_accept(v, g)) {
|
||||
DEBUG_PRINTF("vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu\n", g[v].index);
|
||||
width++;
|
||||
auto succ = succs(v, g);
|
||||
if (succ.size() != 1) {
|
||||
@@ -435,7 +434,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
|
||||
DEBUG_PRINTF("adjusting width by %d\n", offsetAdjust);
|
||||
width += offsetAdjust;
|
||||
|
||||
DEBUG_PRINTF("width=%u, vertex %u is cyclic\n", width,
|
||||
DEBUG_PRINTF("width=%u, vertex %zu is cyclic\n", width,
|
||||
g[cyclic].index);
|
||||
|
||||
if (width >= g.min_length) {
|
||||
@@ -448,7 +447,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
|
||||
vector<NFAVertex> preds;
|
||||
vector<NFAEdge> dead;
|
||||
for (auto u : inv_adjacent_vertices_range(cyclic, g)) {
|
||||
DEBUG_PRINTF("pred %u\n", g[u].index);
|
||||
DEBUG_PRINTF("pred %zu\n", g[u].index);
|
||||
if (u == cyclic) {
|
||||
continue;
|
||||
}
|
||||
@@ -484,8 +483,8 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
|
||||
add_edge(u, cyclic, g);
|
||||
}
|
||||
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
clearReports(g);
|
||||
|
||||
g.min_length = 0;
|
||||
@@ -542,8 +541,7 @@ bool isEdgePrunable(const NGWrapper &g,
|
||||
const NFAVertex u = source(e, g);
|
||||
const NFAVertex v = target(e, g);
|
||||
|
||||
DEBUG_PRINTF("edge (%u,%u)\n", g[u].index,
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("edge (%zu,%zu)\n", g[u].index, g[v].index);
|
||||
|
||||
// Leave our special-to-special edges alone.
|
||||
if (is_special(u, g) && is_special(v, g)) {
|
||||
@@ -716,8 +714,7 @@ static
|
||||
bool isUnanchored(const NGHolder &g) {
|
||||
for (auto v : adjacent_vertices_range(g.start, g)) {
|
||||
if (!edge(g.startDs, v, g).second) {
|
||||
DEBUG_PRINTF("fail, %u is anchored vertex\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("fail, %zu is anchored vertex\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -862,7 +859,7 @@ void handleExtendedParams(ReportManager &rm, NGWrapper &g,
|
||||
}
|
||||
}
|
||||
}
|
||||
//dumpGraph("final.dot", g.g);
|
||||
//dumpGraph("final.dot", g);
|
||||
|
||||
if (!hasExtParams(g)) {
|
||||
return;
|
||||
|
@@ -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:
|
||||
@@ -77,7 +77,7 @@ bool findMask(const NGHolder &g, vector<CharReach> *mask, bool *anchored,
|
||||
NFAVertex v = *succs.begin();
|
||||
|
||||
while (true) {
|
||||
DEBUG_PRINTF("validating vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("validating vertex %zu\n", g[v].index);
|
||||
|
||||
assert(v != g.acceptEod);
|
||||
|
||||
|
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Definition of the NFAGraph type used for all NFA graph
|
||||
* representations.
|
||||
*
|
||||
* Note that most of the time we don't work on a bare NFAGraph: instead
|
||||
* we use an NGHolder, which wraps the graph and defines our special vertices,
|
||||
* etc.
|
||||
*/
|
||||
|
||||
#ifndef NG_GRAPH_H
|
||||
#define NG_GRAPH_H
|
||||
|
||||
#include "util/charreach.h"
|
||||
#include "util/ue2_containers.h"
|
||||
#include "ue2common.h"
|
||||
|
||||
#include <boost/graph/adjacency_iterator.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
/** \brief Properties associated with each vertex in an NFAGraph. */
|
||||
struct NFAGraphVertexProps {
|
||||
/** \brief Set of characters on which this vertex is reachable. */
|
||||
CharReach char_reach;
|
||||
|
||||
/** \brief Set of reports raised by this vertex. */
|
||||
ue2::flat_set<ReportID> reports;
|
||||
|
||||
/** \brief Unique index for this vertex, used for BGL algorithms. */
|
||||
u32 index = 0;
|
||||
|
||||
/** \brief Flags associated with assertions. */
|
||||
u32 assert_flags = 0;
|
||||
};
|
||||
|
||||
/** \brief Properties associated with each edge in an NFAGraph. */
|
||||
struct NFAGraphEdgeProps {
|
||||
/** \brief Unique index for this edge, used for BGL algorithms. */
|
||||
u32 index = 0;
|
||||
|
||||
/** \brief For graphs that will be implemented as multi-top engines, this
|
||||
* specifies the top events. Only used on edges from the start vertex. */
|
||||
ue2::flat_set<u32> tops;
|
||||
|
||||
/** \brief Flags associated with assertions. */
|
||||
u32 assert_flags = 0;
|
||||
};
|
||||
|
||||
// For flexibility: boost::listS, boost::listS for out-edge and vertex lists.
|
||||
// boost::bidirectionalS for directed graph so that we can get at in-edges.
|
||||
typedef boost::adjacency_list<boost::listS,
|
||||
boost::listS,
|
||||
boost::bidirectionalS,
|
||||
NFAGraphVertexProps,
|
||||
NFAGraphEdgeProps> NFAGraph;
|
||||
|
||||
typedef NFAGraph::vertex_descriptor NFAVertex;
|
||||
typedef NFAGraph::edge_descriptor NFAEdge;
|
||||
|
||||
/** \brief vertex_index values for special nodes in the NFAGraph. */
|
||||
enum SpecialNodes {
|
||||
/** \brief Anchored start vertex. WARNING: this may be triggered at various
|
||||
* locations (not just zero) for triggered graphs. */
|
||||
NODE_START,
|
||||
|
||||
/** \brief Unanchored start-dotstar vertex. WARNING: this may not have a
|
||||
* proper self-loop. */
|
||||
NODE_START_DOTSTAR,
|
||||
|
||||
/** \brief Accept vertex. All vertices that can match at arbitrary offsets
|
||||
* must have an edge to this vertex. */
|
||||
NODE_ACCEPT,
|
||||
|
||||
/** \brief Accept-EOD vertex. Vertices that must raise a match at EOD only
|
||||
* must have an edge to this vertex. */
|
||||
NODE_ACCEPT_EOD,
|
||||
|
||||
/** \brief Sentinel, number of special vertices. */
|
||||
N_SPECIALS
|
||||
};
|
||||
|
||||
} // namespace ue2
|
||||
|
||||
#endif
|
@@ -37,10 +37,10 @@
|
||||
#include "ng_mcclellan_internal.h"
|
||||
#include "ng_som_util.h"
|
||||
#include "ng_squash.h"
|
||||
#include "ng_util.h"
|
||||
#include "util/bitfield.h"
|
||||
#include "util/container.h"
|
||||
#include "util/determinise.h"
|
||||
#include "util/graph.h"
|
||||
#include "util/graph_range.h"
|
||||
#include "util/make_unique.h"
|
||||
#include "util/ue2_containers.h"
|
||||
@@ -449,7 +449,7 @@ void haig_do_preds(const NGHolder &g, const stateset &nfa_states,
|
||||
NFAVertex v = state_mapping[i];
|
||||
s32 slot_id = g[v].index;
|
||||
|
||||
DEBUG_PRINTF("d vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("d vertex %zu\n", g[v].index);
|
||||
vector<u32> &out_map = preds[slot_id];
|
||||
for (auto u : inv_adjacent_vertices_range(v, g)) {
|
||||
out_map.push_back(g[u].index);
|
||||
@@ -490,7 +490,7 @@ void haig_note_starts(const NGHolder &g, map<u32, u32> *out) {
|
||||
|
||||
for (auto v : vertices_range(g)) {
|
||||
if (is_any_start_inc_virtual(v, g)) {
|
||||
DEBUG_PRINTF("%u creates new som value\n", g[v].index);
|
||||
DEBUG_PRINTF("%zu creates new som value\n", g[v].index);
|
||||
out->emplace(g[v].index, 0U);
|
||||
continue;
|
||||
}
|
||||
@@ -501,7 +501,7 @@ void haig_note_starts(const NGHolder &g, map<u32, u32> *out) {
|
||||
|
||||
const DepthMinMax &d = depths[g[v].index];
|
||||
if (d.min == d.max && d.min.is_finite()) {
|
||||
DEBUG_PRINTF("%u is fixed at %u\n", g[v].index, (u32)d.min);
|
||||
DEBUG_PRINTF("%zu is fixed at %u\n", g[v].index, (u32)d.min);
|
||||
out->emplace(g[v].index, d.min);
|
||||
}
|
||||
}
|
||||
|
@@ -36,123 +36,33 @@ using namespace std;
|
||||
namespace ue2 {
|
||||
|
||||
// internal use only
|
||||
static NFAVertex addSpecialVertex(NFAGraph &g, SpecialNodes id) {
|
||||
NFAVertex v = add_vertex(g);
|
||||
static NFAVertex addSpecialVertex(NGHolder &g, SpecialNodes id) {
|
||||
NFAVertex v(add_vertex(g));
|
||||
g[v].index = id;
|
||||
return v;
|
||||
}
|
||||
|
||||
NGHolder::NGHolder(void)
|
||||
: g(),
|
||||
// add initial special nodes
|
||||
start(addSpecialVertex(g, NODE_START)),
|
||||
startDs(addSpecialVertex(g, NODE_START_DOTSTAR)),
|
||||
accept(addSpecialVertex(g, NODE_ACCEPT)),
|
||||
acceptEod(addSpecialVertex(g, NODE_ACCEPT_EOD)),
|
||||
// misc data
|
||||
numVertices(N_SPECIALS),
|
||||
numEdges(0),
|
||||
isValidNumEdges(true),
|
||||
isValidNumVertices(true) {
|
||||
|
||||
// wire up some fake edges for the stylized bits of the NFA
|
||||
add_edge(start, startDs, *this);
|
||||
add_edge(startDs, startDs, *this);
|
||||
add_edge(accept, acceptEod, *this);
|
||||
|
||||
g[start].char_reach.setall();
|
||||
g[startDs].char_reach.setall();
|
||||
}
|
||||
|
||||
NGHolder::NGHolder(nfa_kind k)
|
||||
: kind (k), g(),
|
||||
: kind (k),
|
||||
// add initial special nodes
|
||||
start(addSpecialVertex(g, NODE_START)),
|
||||
startDs(addSpecialVertex(g, NODE_START_DOTSTAR)),
|
||||
accept(addSpecialVertex(g, NODE_ACCEPT)),
|
||||
acceptEod(addSpecialVertex(g, NODE_ACCEPT_EOD)),
|
||||
// misc data
|
||||
numVertices(N_SPECIALS),
|
||||
numEdges(0),
|
||||
isValidNumEdges(true),
|
||||
isValidNumVertices(true) {
|
||||
start(addSpecialVertex(*this, NODE_START)),
|
||||
startDs(addSpecialVertex(*this, NODE_START_DOTSTAR)),
|
||||
accept(addSpecialVertex(*this, NODE_ACCEPT)),
|
||||
acceptEod(addSpecialVertex(*this, NODE_ACCEPT_EOD)) {
|
||||
|
||||
// wire up some fake edges for the stylized bits of the NFA
|
||||
add_edge(start, startDs, *this);
|
||||
add_edge(startDs, startDs, *this);
|
||||
add_edge(accept, acceptEod, *this);
|
||||
|
||||
g[start].char_reach.setall();
|
||||
g[startDs].char_reach.setall();
|
||||
(*this)[start].char_reach.setall();
|
||||
(*this)[startDs].char_reach.setall();
|
||||
}
|
||||
|
||||
NGHolder::~NGHolder(void) {
|
||||
DEBUG_PRINTF("destroying holder @ %p\n", this);
|
||||
}
|
||||
|
||||
size_t num_edges(NGHolder &h) {
|
||||
if (!h.isValidNumEdges) {
|
||||
h.numEdges = num_edges(h.g);
|
||||
h.isValidNumEdges = true;
|
||||
}
|
||||
return h.numEdges;
|
||||
}
|
||||
|
||||
size_t num_edges(const NGHolder &h) {
|
||||
if (!h.isValidNumEdges) {
|
||||
return num_edges(h.g);
|
||||
}
|
||||
return h.numEdges;
|
||||
}
|
||||
|
||||
size_t num_vertices(NGHolder &h) {
|
||||
if (!h.isValidNumVertices) {
|
||||
h.numVertices = num_vertices(h.g);
|
||||
h.isValidNumVertices = true;
|
||||
}
|
||||
return h.numVertices;
|
||||
}
|
||||
|
||||
size_t num_vertices(const NGHolder &h) {
|
||||
if (!h.isValidNumVertices) {
|
||||
return num_vertices(h.g);
|
||||
}
|
||||
return h.numVertices;
|
||||
}
|
||||
|
||||
void remove_edge(const NFAEdge &e, NGHolder &h) {
|
||||
remove_edge(e, h.g);
|
||||
assert(!h.isValidNumEdges || h.numEdges > 0);
|
||||
h.numEdges--;
|
||||
}
|
||||
|
||||
void remove_edge(NFAVertex u, NFAVertex v, NGHolder &h) {
|
||||
remove_edge(u, v, h.g);
|
||||
assert(!h.isValidNumEdges || h.numEdges > 0);
|
||||
h.numEdges--;
|
||||
}
|
||||
|
||||
void remove_vertex(NFAVertex v, NGHolder &h) {
|
||||
remove_vertex(v, h.g);
|
||||
assert(!h.isValidNumVertices || h.numVertices > 0);
|
||||
h.numVertices--;
|
||||
}
|
||||
|
||||
void clear_vertex(NFAVertex v, NGHolder &h) {
|
||||
h.isValidNumEdges = false;
|
||||
clear_vertex_faster(v, h.g);
|
||||
}
|
||||
|
||||
void clear_in_edges(NFAVertex v, NGHolder &h) {
|
||||
h.isValidNumEdges = false;
|
||||
clear_in_edges(v, h.g);
|
||||
}
|
||||
|
||||
void clear_out_edges(NFAVertex v, NGHolder &h) {
|
||||
h.isValidNumEdges = false;
|
||||
clear_out_edges(v, h.g);
|
||||
}
|
||||
|
||||
void clear_graph(NGHolder &h) {
|
||||
NGHolder::vertex_iterator vi, ve;
|
||||
for (tie(vi, ve) = vertices(h); vi != ve;) {
|
||||
@@ -166,6 +76,8 @@ void clear_graph(NGHolder &h) {
|
||||
}
|
||||
|
||||
assert(num_vertices(h) == N_SPECIALS);
|
||||
renumber_vertices(h); /* ensure that we reset our next allocated index */
|
||||
renumber_edges(h);
|
||||
|
||||
// Recreate special stylised edges.
|
||||
add_edge(h.start, h.startDs, h);
|
||||
@@ -173,56 +85,13 @@ void clear_graph(NGHolder &h) {
|
||||
add_edge(h.accept, h.acceptEod, h);
|
||||
}
|
||||
|
||||
std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v, NGHolder &h) {
|
||||
assert(edge(u, v, h.g).second == false);
|
||||
pair<NFAEdge, bool> e = add_edge(u, v, h.g);
|
||||
h.g[e.first].index = h.numEdges++;
|
||||
assert(!h.isValidNumEdges || h.numEdges > 0); // no wrapping
|
||||
return e;
|
||||
}
|
||||
|
||||
std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v,
|
||||
const NFAGraph::edge_property_type &ep,
|
||||
NGHolder &h) {
|
||||
assert(edge(u, v, h.g).second == false);
|
||||
pair<NFAEdge, bool> e = add_edge(u, v, ep, h.g);
|
||||
h.g[e.first].index = h.numEdges++;
|
||||
assert(!h.isValidNumEdges || h.numEdges > 0); // no wrapping
|
||||
return e;
|
||||
}
|
||||
|
||||
NFAVertex add_vertex(NGHolder &h) {
|
||||
NFAVertex v = add_vertex(h.g);
|
||||
h[v].index = h.numVertices++;
|
||||
assert(h.numVertices > 0); // no wrapping
|
||||
return v;
|
||||
}
|
||||
|
||||
NFAVertex add_vertex(const NFAGraph::vertex_property_type &vp, NGHolder &h) {
|
||||
NFAVertex v = add_vertex(h);
|
||||
u32 i = h.g[v].index; /* preserve index */
|
||||
h.g[v] = vp;
|
||||
h.g[v].index = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
void NGHolder::renumberEdges() {
|
||||
numEdges = renumberGraphEdges(g);
|
||||
isValidNumEdges = true;
|
||||
}
|
||||
|
||||
void NGHolder::renumberVertices() {
|
||||
numVertices = renumberGraphVertices(g);
|
||||
isValidNumVertices = true;
|
||||
}
|
||||
|
||||
NFAVertex NGHolder::getSpecialVertex(u32 id) const {
|
||||
switch (id) {
|
||||
case NODE_START: return start;
|
||||
case NODE_START_DOTSTAR: return startDs;
|
||||
case NODE_ACCEPT: return accept;
|
||||
case NODE_ACCEPT_EOD: return acceptEod;
|
||||
default: return nullptr;
|
||||
case NODE_START: return start;
|
||||
case NODE_START_DOTSTAR: return startDs;
|
||||
case NODE_ACCEPT: return accept;
|
||||
case NODE_ACCEPT_EOD: return acceptEod;
|
||||
default: return null_vertex();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -26,19 +26,75 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Definition of the NGHolder type used for to represent general nfa
|
||||
* graphs as well as all associated types (vertex and edge properties, etc).
|
||||
*
|
||||
* The NGHolder also contains the special vertices used to represents starts and
|
||||
* accepts.
|
||||
*/
|
||||
|
||||
#ifndef NG_HOLDER_H
|
||||
#define NG_HOLDER_H
|
||||
|
||||
#include "ng_graph.h"
|
||||
#include "ue2common.h"
|
||||
#include "nfa/nfa_kind.h"
|
||||
|
||||
#include <boost/graph/adjacency_iterator.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include "util/charreach.h"
|
||||
#include "util/ue2_containers.h"
|
||||
#include "util/ue2_graph.h"
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
/** \brief Properties associated with each vertex in an NFAGraph. */
|
||||
struct NFAGraphVertexProps {
|
||||
/** \brief Set of characters on which this vertex is reachable. */
|
||||
CharReach char_reach;
|
||||
|
||||
/** \brief Set of reports raised by this vertex. */
|
||||
flat_set<ReportID> reports;
|
||||
|
||||
/** \brief Unique index for this vertex, used for BGL algorithms. */
|
||||
size_t index = 0;
|
||||
|
||||
/** \brief Flags associated with assertions. */
|
||||
u32 assert_flags = 0;
|
||||
};
|
||||
|
||||
/** \brief Properties associated with each edge in an NFAGraph. */
|
||||
struct NFAGraphEdgeProps {
|
||||
/** \brief Unique index for this edge, used for BGL algorithms. */
|
||||
size_t index = 0;
|
||||
|
||||
/** \brief For graphs that will be implemented as multi-top engines, this
|
||||
* specifies the top events. Only used on edges from the start vertex. */
|
||||
ue2::flat_set<u32> tops;
|
||||
|
||||
/** \brief Flags associated with assertions. */
|
||||
u32 assert_flags = 0;
|
||||
};
|
||||
|
||||
/** \brief vertex_index values for special nodes in the NFAGraph. */
|
||||
enum SpecialNodes {
|
||||
/** \brief Anchored start vertex. WARNING: this may be triggered at various
|
||||
* locations (not just zero) for triggered graphs. */
|
||||
NODE_START,
|
||||
|
||||
/** \brief Unanchored start-dotstar vertex. WARNING: this may not have a
|
||||
* proper self-loop. */
|
||||
NODE_START_DOTSTAR,
|
||||
|
||||
/** \brief Accept vertex. All vertices that can match at arbitrary offsets
|
||||
* must have an edge to this vertex. */
|
||||
NODE_ACCEPT,
|
||||
|
||||
/** \brief Accept-EOD vertex. Vertices that must raise a match at EOD only
|
||||
* must have an edge to this vertex. */
|
||||
NODE_ACCEPT_EOD,
|
||||
|
||||
/** \brief Sentinel, number of special vertices. */
|
||||
N_SPECIALS
|
||||
};
|
||||
|
||||
/** \brief Encapsulates an NFAGraph, stores special vertices and other
|
||||
* metadata.
|
||||
*
|
||||
@@ -49,188 +105,34 @@ namespace ue2 {
|
||||
* - (startDs, startDs) (self-loop)
|
||||
* - (accept, acceptEod)
|
||||
*/
|
||||
class NGHolder : boost::noncopyable {
|
||||
class NGHolder : public ue2_graph<NGHolder, NFAGraphVertexProps,
|
||||
NFAGraphEdgeProps> {
|
||||
public:
|
||||
NGHolder(void);
|
||||
explicit NGHolder(nfa_kind kind);
|
||||
NGHolder(void) : NGHolder(NFA_OUTFIX) {};
|
||||
virtual ~NGHolder(void);
|
||||
|
||||
// Pack edge and vertex indices.
|
||||
// Note: maintaining edge index order can be expensive due to the frequency
|
||||
// of edge removal/addition, so only renumberEdges() when required by
|
||||
// operations on edge lists.
|
||||
void renumberEdges();
|
||||
void renumberVertices();
|
||||
nfa_kind kind; /* Role that this plays in Rose */
|
||||
|
||||
NFAVertex getSpecialVertex(u32 id) const;
|
||||
static const size_t N_SPECIAL_VERTICES = N_SPECIALS;
|
||||
public:
|
||||
const vertex_descriptor start; //!< Anchored start vertex.
|
||||
const vertex_descriptor startDs; //!< Unanchored start-dotstar vertex.
|
||||
const vertex_descriptor accept; //!< Accept vertex.
|
||||
const vertex_descriptor acceptEod; //!< Accept at EOD vertex.
|
||||
|
||||
nfa_kind kind = NFA_OUTFIX; /* Role that this plays in Rose */
|
||||
|
||||
/** \brief Underlying graph object */
|
||||
NFAGraph g;
|
||||
|
||||
const NFAVertex start; //!< Anchored start vertex.
|
||||
const NFAVertex startDs; //!< Unanchored start-dotstar vertex.
|
||||
const NFAVertex accept; //!< Accept vertex.
|
||||
const NFAVertex acceptEod; //!< Accept at EOD vertex.
|
||||
|
||||
using directed_category = NFAGraph::directed_category;
|
||||
using edge_parallel_category = NFAGraph::edge_parallel_category;
|
||||
using traversal_category = NFAGraph::traversal_category;
|
||||
|
||||
using vertex_descriptor = NFAGraph::vertex_descriptor;
|
||||
using edge_descriptor = NFAGraph::edge_descriptor;
|
||||
using adjacency_iterator = NFAGraph::adjacency_iterator;
|
||||
using edge_iterator = NFAGraph::edge_iterator;
|
||||
using in_edge_iterator = NFAGraph::in_edge_iterator;
|
||||
using inv_adjacency_iterator = NFAGraph::inv_adjacency_iterator;
|
||||
using out_edge_iterator = NFAGraph::out_edge_iterator;
|
||||
using vertex_iterator = NFAGraph::vertex_iterator;
|
||||
using edge_property_type = NFAGraph::edge_property_type;
|
||||
using vertex_property_type = NFAGraph::vertex_property_type;
|
||||
|
||||
// These free functions, which follow the BGL model, are the interface to
|
||||
// the graph held by this class.
|
||||
friend size_t num_vertices(NGHolder &h);
|
||||
friend size_t num_vertices(const NGHolder &h);
|
||||
friend size_t num_edges(NGHolder &h);
|
||||
friend size_t num_edges(const NGHolder &h);
|
||||
friend void remove_vertex(NFAVertex v, NGHolder &h);
|
||||
friend void clear_vertex(NFAVertex v, NGHolder &h);
|
||||
friend void clear_in_edges(NFAVertex v, NGHolder &h);
|
||||
friend void clear_out_edges(NFAVertex v, NGHolder &h);
|
||||
friend void remove_edge(const NFAEdge &e, NGHolder &h);
|
||||
friend void remove_edge(NFAVertex u, NFAVertex v, NGHolder &h);
|
||||
|
||||
template<class Predicate>
|
||||
friend void remove_out_edge_if(NFAVertex v, Predicate pred, NGHolder &h) {
|
||||
boost::remove_out_edge_if(v, pred, h.g);
|
||||
h.isValidNumEdges = false;
|
||||
}
|
||||
|
||||
template<class Predicate>
|
||||
friend void remove_in_edge_if(NFAVertex v, Predicate pred, NGHolder &h) {
|
||||
boost::remove_in_edge_if(v, pred, h.g);
|
||||
h.isValidNumEdges = false;
|
||||
}
|
||||
|
||||
template<class Predicate>
|
||||
friend void remove_edge_if(Predicate pred, NGHolder &h) {
|
||||
boost::remove_edge_if(pred, h.g);
|
||||
h.isValidNumEdges = false;
|
||||
}
|
||||
|
||||
friend std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v,
|
||||
NGHolder &h);
|
||||
friend std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v,
|
||||
const edge_property_type &ep,
|
||||
NGHolder &h);
|
||||
friend NFAVertex add_vertex(NGHolder &h);
|
||||
friend NFAVertex add_vertex(const vertex_property_type &vp, NGHolder &h);
|
||||
|
||||
static NFAVertex null_vertex(void) { return NFAGraph::null_vertex(); }
|
||||
|
||||
// Subscript operators for BGL bundled properties.
|
||||
using graph_bundled = NFAGraph::graph_bundled;
|
||||
using vertex_bundled = NFAGraph::vertex_bundled;
|
||||
using edge_bundled = NFAGraph::edge_bundled;
|
||||
|
||||
vertex_bundled &operator[](NFAVertex v) {
|
||||
return get(boost::vertex_bundle, g)[v];
|
||||
}
|
||||
const vertex_bundled &operator[](NFAVertex v) const {
|
||||
return get(boost::vertex_bundle, g)[v];
|
||||
}
|
||||
edge_bundled &operator[](const NFAEdge &e) {
|
||||
return get(boost::edge_bundle, g)[e];
|
||||
}
|
||||
const edge_bundled &operator[](const NFAEdge &e) const {
|
||||
return get(boost::edge_bundle, g)[e];
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/* Since the NFAGraph vertex/edge list selectors are std::lists, computing
|
||||
* num_vertices and num_edges is O(N). We use these members to store a
|
||||
* cached copy of the size.
|
||||
*
|
||||
* In the future, with C++11's constant-time std::list::size, these may
|
||||
* become obsolete. */
|
||||
|
||||
u32 numVertices;
|
||||
u32 numEdges;
|
||||
bool isValidNumEdges;
|
||||
bool isValidNumVertices;
|
||||
vertex_descriptor getSpecialVertex(u32 id) const;
|
||||
};
|
||||
|
||||
typedef NGHolder::vertex_descriptor NFAVertex;
|
||||
typedef NGHolder::edge_descriptor NFAEdge;
|
||||
|
||||
/** \brief True if the vertex \p v is one of our special vertices. */
|
||||
template <typename GraphT>
|
||||
static really_inline
|
||||
bool is_special(const NFAVertex v, const GraphT &g) {
|
||||
bool is_special(const typename GraphT::vertex_descriptor v, const GraphT &g) {
|
||||
return g[v].index < N_SPECIALS;
|
||||
}
|
||||
|
||||
static really_inline
|
||||
std::pair<NGHolder::adjacency_iterator, NGHolder::adjacency_iterator>
|
||||
adjacent_vertices(NFAVertex v, const NGHolder &h) {
|
||||
return adjacent_vertices(v, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
std::pair<NFAEdge, bool> edge(NFAVertex u, NFAVertex v, const NGHolder &h) {
|
||||
return boost::edge(u, v, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
std::pair<NGHolder::edge_iterator, NGHolder::edge_iterator>
|
||||
edges(const NGHolder &h) {
|
||||
return edges(h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
size_t in_degree(NFAVertex v, const NGHolder &h) {
|
||||
return in_degree(v, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
std::pair<NGHolder::in_edge_iterator, NGHolder::in_edge_iterator>
|
||||
in_edges(NFAVertex v, const NGHolder &h) {
|
||||
return in_edges(v, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
std::pair<NGHolder::inv_adjacency_iterator, NGHolder::inv_adjacency_iterator>
|
||||
inv_adjacent_vertices(NFAVertex v, const NGHolder &h) {
|
||||
return inv_adjacent_vertices(v, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
size_t out_degree(NFAVertex v, const NGHolder &h) {
|
||||
return out_degree(v, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
std::pair<NGHolder::out_edge_iterator, NGHolder::out_edge_iterator>
|
||||
out_edges(NFAVertex v, const NGHolder &h) {
|
||||
return out_edges(v, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
NFAVertex source(const NFAEdge &e, const NGHolder &h) {
|
||||
return source(e, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
NFAVertex target(const NFAEdge &e, const NGHolder &h) {
|
||||
return target(e, h.g);
|
||||
}
|
||||
|
||||
static really_inline
|
||||
std::pair<NGHolder::vertex_iterator, NGHolder::vertex_iterator>
|
||||
vertices(const NGHolder &h) {
|
||||
return vertices(h.g);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clears all non-special vertices and edges from the graph.
|
||||
*
|
||||
@@ -239,16 +141,6 @@ vertices(const NGHolder &h) {
|
||||
*/
|
||||
void clear_graph(NGHolder &h);
|
||||
|
||||
inline
|
||||
void renumber_edges(NGHolder &h) {
|
||||
h.renumberEdges();
|
||||
}
|
||||
|
||||
inline
|
||||
void renumber_vertices(NGHolder &h) {
|
||||
h.renumberVertices();
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Clear and remove all of the vertices pointed to by the given iterator
|
||||
* range.
|
||||
@@ -275,8 +167,8 @@ void remove_vertices(Iter begin, Iter end, NGHolder &h, bool renumber = true) {
|
||||
}
|
||||
|
||||
if (renumber) {
|
||||
h.renumberEdges();
|
||||
h.renumberVertices();
|
||||
renumber_edges(h);
|
||||
renumber_vertices(h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +203,7 @@ void remove_edges(Iter begin, Iter end, NGHolder &h, bool renumber = true) {
|
||||
}
|
||||
|
||||
if (renumber) {
|
||||
h.renumberEdges();
|
||||
renumber_edges(h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -77,6 +77,26 @@ private:
|
||||
ReportID a_rep;
|
||||
ReportID b_rep;
|
||||
};
|
||||
|
||||
/** Comparison functor used to sort by vertex_index. */
|
||||
template<typename Graph>
|
||||
struct VertexIndexOrdering {
|
||||
explicit VertexIndexOrdering(const Graph &g_in) : g(g_in) {}
|
||||
bool operator()(typename Graph::vertex_descriptor a,
|
||||
typename Graph::vertex_descriptor b) const {
|
||||
assert(a == b || g[a].index != g[b].index);
|
||||
return g[a].index < g[b].index;
|
||||
}
|
||||
private:
|
||||
const Graph &g;
|
||||
};
|
||||
|
||||
template<typename Graph>
|
||||
static
|
||||
VertexIndexOrdering<Graph> make_index_ordering(const Graph &g) {
|
||||
return VertexIndexOrdering<Graph>(g);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
@@ -109,7 +129,7 @@ bool is_equal_i(const NGHolder &a, const NGHolder &b,
|
||||
for (size_t i = 0; i < vert_a.size(); i++) {
|
||||
NFAVertex va = vert_a[i];
|
||||
NFAVertex vb = vert_b[i];
|
||||
DEBUG_PRINTF("vertex %u\n", a[va].index);
|
||||
DEBUG_PRINTF("vertex %zu\n", a[va].index);
|
||||
|
||||
// Vertex index must be the same.
|
||||
if (a[va].index != b[vb].index) {
|
||||
|
@@ -78,8 +78,7 @@ bool sanityCheckGraph(const NGHolder &g,
|
||||
// Non-specials should have non-empty reachability.
|
||||
if (!is_special(v, g)) {
|
||||
if (g[v].char_reach.none()) {
|
||||
DEBUG_PRINTF("vertex %u has empty reach\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu has empty reach\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -88,25 +87,23 @@ bool sanityCheckGraph(const NGHolder &g,
|
||||
// other vertices must not have them.
|
||||
if (is_match_vertex(v, g) && v != g.accept) {
|
||||
if (g[v].reports.empty()) {
|
||||
DEBUG_PRINTF("vertex %u has no reports\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu has no reports\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
} else if (!g[v].reports.empty()) {
|
||||
DEBUG_PRINTF("vertex %u has reports but no accept edge\n",
|
||||
DEBUG_PRINTF("vertex %zu has reports but no accept edge\n",
|
||||
g[v].index);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Participant vertices should have distinct state indices.
|
||||
if (!contains(state_ids, v)) {
|
||||
DEBUG_PRINTF("vertex %u has no state index!\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu has no state index!\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
u32 s = state_ids.at(v);
|
||||
if (s != NO_STATE && !seen_states.insert(s).second) {
|
||||
DEBUG_PRINTF("vertex %u has dupe state %u\n",
|
||||
g[v].index, s);
|
||||
DEBUG_PRINTF("vertex %zu has dupe state %u\n", g[v].index, s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -178,11 +175,7 @@ NFAVertex makeTopStartVertex(NGHolder &g, const flat_set<u32> &tops,
|
||||
CharReach top_cr = calcTopVertexReach(tops, top_reach);
|
||||
g[u].char_reach = top_cr;
|
||||
|
||||
// Add edges in vertex index order, for determinism.
|
||||
vector<NFAVertex> ordered_succs(begin(succs), end(succs));
|
||||
sort(begin(ordered_succs), end(ordered_succs), make_index_ordering(g));
|
||||
|
||||
for (auto v : ordered_succs) {
|
||||
for (auto v : succs) {
|
||||
if (v == g.accept || v == g.acceptEod) {
|
||||
reporter = true;
|
||||
}
|
||||
@@ -374,7 +367,7 @@ void attemptToUseAsStart(const NGHolder &g, NFAVertex u,
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("reusing %u is a start vertex\n", g[u].index);
|
||||
DEBUG_PRINTF("reusing %zu is a start vertex\n", g[u].index);
|
||||
markTopSuccAsHandled(u, top_inter, succs, tops_out, unhandled_top_succs,
|
||||
unhandled_succ_tops);
|
||||
}
|
||||
@@ -388,8 +381,7 @@ void reusePredsAsStarts(const NGHolder &g, const map<u32, CharReach> &top_reach,
|
||||
map<u32, flat_set<NFAVertex>> &unhandled_top_succs,
|
||||
map<NFAVertex, flat_set<u32>> &unhandled_succ_tops,
|
||||
map<u32, set<NFAVertex>> &tops_out) {
|
||||
/* create list of candidates first, to avoid issues of iter invalidation
|
||||
* and determinism */
|
||||
/* create list of candidates first, to avoid issues of iter invalidation */
|
||||
DEBUG_PRINTF("attempting to reuse vertices for top starts\n");
|
||||
vector<NFAVertex> cand_starts;
|
||||
for (NFAVertex u : unhandled_succ_tops | map_keys) {
|
||||
@@ -397,7 +389,6 @@ void reusePredsAsStarts(const NGHolder &g, const map<u32, CharReach> &top_reach,
|
||||
cand_starts.push_back(u);
|
||||
}
|
||||
}
|
||||
sort(cand_starts.begin(), cand_starts.end(), make_index_ordering(g));
|
||||
|
||||
for (NFAVertex u : cand_starts) {
|
||||
if (!contains(unhandled_succ_tops, u)) {
|
||||
@@ -625,7 +616,7 @@ void remapReportsToPrograms(NGHolder &h, const ReportManager &rm) {
|
||||
u32 program = rm.getProgramOffset(id);
|
||||
reports.insert(program);
|
||||
}
|
||||
DEBUG_PRINTF("vertex %u: remapped reports {%s} to programs {%s}\n",
|
||||
DEBUG_PRINTF("vertex %zu: remapped reports {%s} to programs {%s}\n",
|
||||
h[v].index, as_string_list(old_reports).c_str(),
|
||||
as_string_list(reports).c_str());
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ void findAccelFriendGeneration(const NGHolder &g, const CharReach &cr,
|
||||
}
|
||||
|
||||
const CharReach &acr = g[v].char_reach;
|
||||
DEBUG_PRINTF("checking %u\n", g[v].index);
|
||||
DEBUG_PRINTF("checking %zu\n", g[v].index);
|
||||
|
||||
if (acr.count() < WIDE_FRIEND_MIN || !acr.isSubsetOf(cr)) {
|
||||
DEBUG_PRINTF("bad reach %zu\n", acr.count());
|
||||
@@ -86,7 +86,7 @@ void findAccelFriendGeneration(const NGHolder &g, const CharReach &cr,
|
||||
next_preds->insert(v);
|
||||
insert(next_cands, adjacent_vertices(v, g));
|
||||
|
||||
DEBUG_PRINTF("%u is a friend indeed\n", g[v].index);
|
||||
DEBUG_PRINTF("%zu is a friend indeed\n", g[v].index);
|
||||
friends->insert(v);
|
||||
next_cand:;
|
||||
}
|
||||
@@ -675,7 +675,7 @@ NFAVertex get_sds_or_proxy(const NGHolder &g) {
|
||||
|
||||
while (true) {
|
||||
if (hasSelfLoop(v, g)) {
|
||||
DEBUG_PRINTF("woot %u\n", g[v].index);
|
||||
DEBUG_PRINTF("woot %zu\n", g[v].index);
|
||||
return v;
|
||||
}
|
||||
if (out_degree(v, g) != 1) {
|
||||
@@ -837,7 +837,7 @@ bool nfaCheckAccel(const NGHolder &g, NFAVertex v,
|
||||
CharReach terminating = g[v].char_reach;
|
||||
terminating.flip();
|
||||
|
||||
DEBUG_PRINTF("vertex %u is cyclic and has %zu stop chars%s\n",
|
||||
DEBUG_PRINTF("vertex %zu is cyclic and has %zu stop chars%s\n",
|
||||
g[v].index, terminating.count(),
|
||||
allow_wide ? " (w)" : "");
|
||||
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
|
||||
|
||||
using namespace std;
|
||||
@@ -335,7 +336,7 @@ void processWorkQueue(const NGHolder &g, const NFAEdge &e,
|
||||
// Our literal set should contain no literal that is a suffix of another.
|
||||
assert(!hasSuffixLiterals(s));
|
||||
|
||||
DEBUG_PRINTF("edge %u (%u->%u) produced %zu literals\n", g[e].index,
|
||||
DEBUG_PRINTF("edge %zu (%zu->%zu) produced %zu literals\n", g[e].index,
|
||||
g[source(e, g)].index, g[target(e, g)].index, s.size());
|
||||
}
|
||||
|
||||
@@ -791,7 +792,7 @@ bool splitOffLeadingLiteral_i(const NGHolder &g, bool anch,
|
||||
}
|
||||
|
||||
while (true) {
|
||||
DEBUG_PRINTF("validating vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("validating vertex %zu\n", g[v].index);
|
||||
|
||||
assert(v != g.acceptEod && v != g.accept);
|
||||
|
||||
|
@@ -95,7 +95,7 @@ void addToString(string &s, const NGHolder &g, NFAVertex v) {
|
||||
static
|
||||
bool splitOffLiteral(NG &ng, NGWrapper &g, NFAVertex v, const bool anchored,
|
||||
set<NFAVertex> &dead) {
|
||||
DEBUG_PRINTF("examine vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("examine vertex %zu\n", g[v].index);
|
||||
bool nocase = false, casefixed = false;
|
||||
|
||||
assert(!is_special(v, g));
|
||||
@@ -109,7 +109,7 @@ bool splitOffLiteral(NG &ng, NGWrapper &g, NFAVertex v, const bool anchored,
|
||||
assert(edge(g.start, v, g).second);
|
||||
assert(edge(g.startDs, v, g).second);
|
||||
}
|
||||
if (hasGreaterInDegree(reqInDegree, v, g)) {
|
||||
if (in_degree(v, g) > reqInDegree) {
|
||||
DEBUG_PRINTF("extra in-edges\n");
|
||||
return false;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ bool splitOffLiteral(NG &ng, NGWrapper &g, NFAVertex v, const bool anchored,
|
||||
u = v; // previous vertex
|
||||
v = *(adjacent_vertices(v, g).first);
|
||||
|
||||
DEBUG_PRINTF("loop, v=%u\n", g[v].index);
|
||||
DEBUG_PRINTF("loop, v=%zu\n", g[v].index);
|
||||
|
||||
if (is_special(v, g)) {
|
||||
if (v == g.accept || v == g.acceptEod) {
|
||||
|
@@ -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:
|
||||
@@ -77,7 +77,7 @@ bool findPaths(const NGHolder &g, vector<Path> &paths) {
|
||||
|
||||
read_count[g[v].index] = out_degree(v, g);
|
||||
|
||||
DEBUG_PRINTF("setting read_count to %zu for %u\n",
|
||||
DEBUG_PRINTF("setting read_count to %zu for %zu\n",
|
||||
read_count[g[v].index], g[v].index);
|
||||
|
||||
if (v == g.start || v == g.startDs) {
|
||||
@@ -117,7 +117,7 @@ bool findPaths(const NGHolder &g, vector<Path> &paths) {
|
||||
|
||||
read_count[g[u].index]--;
|
||||
if (!read_count[g[u].index]) {
|
||||
DEBUG_PRINTF("clearing %u as finished reading\n", g[u].index);
|
||||
DEBUG_PRINTF("clearing %zu as finished reading\n", g[u].index);
|
||||
built[g[u].index].clear();
|
||||
built[g[u].index].shrink_to_fit();
|
||||
}
|
||||
@@ -138,9 +138,9 @@ bool hasLargeDegreeVertex(const NGHolder &g) {
|
||||
if (is_special(v, g)) { // specials can have large degree
|
||||
continue;
|
||||
}
|
||||
if (has_greater_degree(MAX_VERTEX_DEGREE, v, g)) {
|
||||
DEBUG_PRINTF("vertex %u has degree %zu\n", g[v].index,
|
||||
boost::degree(v, g.g));
|
||||
if (degree(v, g) > MAX_VERTEX_DEGREE) {
|
||||
DEBUG_PRINTF("vertex %zu has degree %zu\n", g[v].index,
|
||||
degree(v, g));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -188,7 +188,8 @@ struct PathMask {
|
||||
}
|
||||
|
||||
// Reports are attached to the second-to-last vertex.
|
||||
reports = g[*next(path.rbegin())].reports;
|
||||
NFAVertex u = *std::next(path.rbegin());
|
||||
reports = g[u].reports;
|
||||
assert(!reports.empty());
|
||||
}
|
||||
|
||||
|
@@ -328,7 +328,7 @@ void markToppableStarts(const NGHolder &g, const flat_set<NFAVertex> &unused,
|
||||
}
|
||||
for (const auto &trigger : triggers) {
|
||||
if (triggerAllowed(g, v, triggers, trigger)) {
|
||||
DEBUG_PRINTF("idx %u is valid location for top\n", g[v].index);
|
||||
DEBUG_PRINTF("idx %zu is valid location for top\n", g[v].index);
|
||||
out->set(g[v].index);
|
||||
break;
|
||||
}
|
||||
|
@@ -80,6 +80,7 @@
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using boost::make_filtered_graph;
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
@@ -108,7 +109,7 @@ void findCandidates(NGHolder &g, const vector<NFAVertex> &ordering,
|
||||
goto next_cand;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF("vertex %u is a candidate\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu is a candidate\n", g[v].index);
|
||||
cand->push_back(v);
|
||||
next_cand:;
|
||||
}
|
||||
@@ -139,7 +140,7 @@ void findCandidates_rev(NGHolder &g, const vector<NFAVertex> &ordering,
|
||||
goto next_cand;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF("vertex %u is a candidate\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu is a candidate\n", g[v].index);
|
||||
cand->push_back(v);
|
||||
next_cand:;
|
||||
}
|
||||
@@ -242,7 +243,7 @@ set<NFAVertex> findSustainSet_rev(const NGHolder &g, NFAVertex p,
|
||||
|
||||
static
|
||||
bool enlargeCyclicVertex(NGHolder &g, som_type som, NFAVertex v) {
|
||||
DEBUG_PRINTF("considering vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("considering vertex %zu\n", g[v].index);
|
||||
const CharReach &v_cr = g[v].char_reach;
|
||||
|
||||
CharReach add;
|
||||
@@ -261,7 +262,7 @@ bool enlargeCyclicVertex(NGHolder &g, som_type som, NFAVertex v) {
|
||||
if (p == v) {
|
||||
continue;
|
||||
}
|
||||
DEBUG_PRINTF("looking at pred %u\n", g[p].index);
|
||||
DEBUG_PRINTF("looking at pred %zu\n", g[p].index);
|
||||
|
||||
bool ignore_sds = som; /* if we are tracking som, entries into a state
|
||||
from sds are significant. */
|
||||
@@ -291,13 +292,13 @@ bool enlargeCyclicVertex(NGHolder &g, som_type som, NFAVertex v) {
|
||||
|
||||
/* the cr can be increased */
|
||||
g[v].char_reach = add;
|
||||
DEBUG_PRINTF("vertex %u was widened\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu was widened\n", g[v].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool enlargeCyclicVertex_rev(NGHolder &g, NFAVertex v) {
|
||||
DEBUG_PRINTF("considering vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("considering vertex %zu\n", g[v].index);
|
||||
const CharReach &v_cr = g[v].char_reach;
|
||||
|
||||
CharReach add;
|
||||
@@ -316,7 +317,7 @@ bool enlargeCyclicVertex_rev(NGHolder &g, NFAVertex v) {
|
||||
if (p == v) {
|
||||
continue;
|
||||
}
|
||||
DEBUG_PRINTF("looking at succ %u\n", g[p].index);
|
||||
DEBUG_PRINTF("looking at succ %zu\n", g[p].index);
|
||||
|
||||
set<NFAVertex> sustain = findSustainSet_rev(g, p, add);
|
||||
DEBUG_PRINTF("sustain set is %zu\n", sustain.size());
|
||||
@@ -341,7 +342,7 @@ bool enlargeCyclicVertex_rev(NGHolder &g, NFAVertex v) {
|
||||
|
||||
/* the cr can be increased */
|
||||
g[v].char_reach = add;
|
||||
DEBUG_PRINTF("vertex %u was widened\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu was widened\n", g[v].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -390,7 +391,7 @@ bool improveGraph(NGHolder &g, som_type som) {
|
||||
* enlargeCyclicCR. */
|
||||
CharReach reduced_cr(NFAVertex v, const NGHolder &g,
|
||||
const map<NFAVertex, BoundedRepeatSummary> &br_cyclic) {
|
||||
DEBUG_PRINTF("find minimal cr for %u\n", g[v].index);
|
||||
DEBUG_PRINTF("find minimal cr for %zu\n", g[v].index);
|
||||
CharReach v_cr = g[v].char_reach;
|
||||
if (proper_in_degree(v, g) != 1) {
|
||||
return v_cr;
|
||||
@@ -579,12 +580,11 @@ flat_set<NFAVertex> findDependentVertices(const NGHolder &g, NFAVertex v) {
|
||||
}
|
||||
}
|
||||
|
||||
auto filtered_g = make_filtered_graph(g.g,
|
||||
make_bad_edge_filter(&no_explore));
|
||||
auto filtered_g = make_filtered_graph(g, make_bad_edge_filter(&no_explore));
|
||||
|
||||
vector<boost::default_color_type> color_raw(num_vertices(g));
|
||||
auto color = make_iterator_property_map(color_raw.begin(),
|
||||
get(&NFAGraphVertexProps::index, g.g));
|
||||
get(vertex_index, g));
|
||||
flat_set<NFAVertex> bad;
|
||||
for (NFAVertex b : vertices_range(g)) {
|
||||
if (b != g.start && g[b].char_reach.isSubsetOf(g[v].char_reach)) {
|
||||
@@ -597,7 +597,7 @@ flat_set<NFAVertex> findDependentVertices(const NGHolder &g, NFAVertex v) {
|
||||
flat_set<NFAVertex> rv;
|
||||
for (NFAVertex u : vertices_range(g)) {
|
||||
if (!contains(bad, u)) {
|
||||
DEBUG_PRINTF("%u is good\n", g[u].index);
|
||||
DEBUG_PRINTF("%zu is good\n", g[u].index);
|
||||
rv.insert(u);
|
||||
}
|
||||
}
|
||||
@@ -623,7 +623,7 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
DEBUG_PRINTF("using cyclic %u as base\n", g[u].index);
|
||||
DEBUG_PRINTF("using cyclic %zu as base\n", g[u].index);
|
||||
auto children = findDependentVertices(g, u);
|
||||
vector<NFAVertex> u_succs;
|
||||
for (NFAVertex v : adjacent_vertices_range(u, g)) {
|
||||
@@ -639,23 +639,23 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
|
||||
return g[a].char_reach.count() > g[b].char_reach.count();
|
||||
});
|
||||
for (NFAVertex v : u_succs) {
|
||||
DEBUG_PRINTF(" using %u as killer\n", g[v].index);
|
||||
DEBUG_PRINTF(" using %zu as killer\n", g[v].index);
|
||||
/* Need to distinguish between vertices that are switched on after the
|
||||
* cyclic vs vertices that are switched on concurrently with the cyclic
|
||||
* if (subject to a suitable reach) */
|
||||
bool v_peer_of_cyclic = willBeEnabledConcurrently(u, v, g);
|
||||
set<NFAEdge> dead;
|
||||
for (NFAVertex s : adjacent_vertices_range(v, g)) {
|
||||
DEBUG_PRINTF(" looking at preds of %u\n", g[s].index);
|
||||
DEBUG_PRINTF(" looking at preds of %zu\n", g[s].index);
|
||||
for (NFAEdge e : in_edges_range(s, g)) {
|
||||
NFAVertex p = source(e, g);
|
||||
if (!contains(children, p) || p == v || p == u
|
||||
|| p == g.accept) {
|
||||
DEBUG_PRINTF("%u not a cand\n", g[p].index);
|
||||
DEBUG_PRINTF("%zu not a cand\n", g[p].index);
|
||||
continue;
|
||||
}
|
||||
if (is_any_accept(s, g) && g[p].reports != g[v].reports) {
|
||||
DEBUG_PRINTF("%u bad reports\n", g[p].index);
|
||||
DEBUG_PRINTF("%zu bad reports\n", g[p].index);
|
||||
continue;
|
||||
}
|
||||
/* the out-edges of a vertex that may be enabled on the same
|
||||
@@ -664,7 +664,7 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
|
||||
* may not be switched on until another byte is processed). */
|
||||
if (!v_peer_of_cyclic
|
||||
&& sometimesEnabledConcurrently(u, p, g)) {
|
||||
DEBUG_PRINTF("%u can only be squashed by a proper peer\n",
|
||||
DEBUG_PRINTF("%zu can only be squashed by a proper peer\n",
|
||||
g[p].index);
|
||||
continue;
|
||||
}
|
||||
@@ -672,14 +672,14 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
|
||||
if (g[p].char_reach.isSubsetOf(g[v].char_reach)) {
|
||||
dead.insert(e);
|
||||
changed = true;
|
||||
DEBUG_PRINTF("removing edge %u->%u\n", g[p].index,
|
||||
DEBUG_PRINTF("removing edge %zu->%zu\n", g[p].index,
|
||||
g[s].index);
|
||||
} else if (is_subset_of(succs(p, g), succs(u, g))) {
|
||||
if (is_match_vertex(p, g)
|
||||
&& !is_subset_of(g[p].reports, g[v].reports)) {
|
||||
continue;
|
||||
}
|
||||
DEBUG_PRINTF("updating reach on %u\n", g[p].index);
|
||||
DEBUG_PRINTF("updating reach on %zu\n", g[p].index);
|
||||
changed |= (g[p].char_reach & g[v].char_reach).any();
|
||||
g[p].char_reach &= ~g[v].char_reach;
|
||||
}
|
||||
|
@@ -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:
|
||||
@@ -111,6 +111,7 @@ static
|
||||
void removeEdgesFromIndex(NGHolder &g, vector<u64a> &capacityMap, u32 idx) {
|
||||
remove_edge_if([&](const NFAEdge &e) { return g[e].index >= idx; }, g);
|
||||
capacityMap.resize(idx);
|
||||
renumber_edges(g);
|
||||
}
|
||||
|
||||
/** A wrapper around boykov_kolmogorov_max_flow, returns the max flow and
|
||||
@@ -142,11 +143,10 @@ u64a getMaxFlow(NGHolder &h, const vector<u64a> &capacityMap_in,
|
||||
vector<s32> distances(numVertices);
|
||||
assert(colorMap.size() == numVertices);
|
||||
|
||||
const NFAGraph &g = h.g;
|
||||
auto v_index_map = get(&NFAGraphVertexProps::index, g);
|
||||
auto e_index_map = get(&NFAGraphEdgeProps::index, g);
|
||||
auto v_index_map = get(vertex_index, h);
|
||||
auto e_index_map = get(edge_index, h);
|
||||
|
||||
u64a flow = boykov_kolmogorov_max_flow(g,
|
||||
u64a flow = boykov_kolmogorov_max_flow(h,
|
||||
make_iterator_property_map(capacityMap.begin(), e_index_map),
|
||||
make_iterator_property_map(edgeResiduals.begin(), e_index_map),
|
||||
make_iterator_property_map(reverseEdges.begin(), e_index_map),
|
||||
@@ -158,7 +158,7 @@ u64a getMaxFlow(NGHolder &h, const vector<u64a> &capacityMap_in,
|
||||
|
||||
// Remove reverse edges from graph.
|
||||
removeEdgesFromIndex(h, capacityMap, numRealEdges);
|
||||
assert(num_edges(h.g) == numRealEdges);
|
||||
assert(num_edges(h) == numRealEdges);
|
||||
|
||||
DEBUG_PRINTF("flow = %llu\n", flow);
|
||||
return flow;
|
||||
@@ -190,14 +190,14 @@ vector<NFAEdge> findMinCut(NGHolder &h, const vector<u64a> &scores) {
|
||||
|
||||
if (fromColor != boost::white_color && toColor == boost::white_color) {
|
||||
assert(ec <= INVALID_EDGE_CAP);
|
||||
DEBUG_PRINTF("found white cut edge %u->%u cap %llu\n",
|
||||
DEBUG_PRINTF("found white cut edge %zu->%zu cap %llu\n",
|
||||
h[from].index, h[to].index, ec);
|
||||
observed_white_flow += ec;
|
||||
picked_white.push_back(e);
|
||||
}
|
||||
if (fromColor == boost::black_color && toColor != boost::black_color) {
|
||||
assert(ec <= INVALID_EDGE_CAP);
|
||||
DEBUG_PRINTF("found black cut edge %u->%u cap %llu\n",
|
||||
DEBUG_PRINTF("found black cut edge %zu->%zu cap %llu\n",
|
||||
h[from].index, h[to].index, ec);
|
||||
observed_black_flow += ec;
|
||||
picked_black.push_back(e);
|
||||
|
@@ -220,13 +220,7 @@ void copyInEdges(NGHolder &g, NFAVertex from, NFAVertex to,
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check with edge_by_target to cope with predecessors with large
|
||||
// fan-out.
|
||||
if (edge_by_target(u, to, g).second) {
|
||||
continue;
|
||||
}
|
||||
|
||||
add_edge(u, to, g[e], g);
|
||||
add_edge_if_not_present(u, to, g[e], g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +355,7 @@ void reduceRegions(NGHolder &h) {
|
||||
// We may have vertices that have edges to both accept and acceptEod: in
|
||||
// this case, we can optimize for performance by removing the acceptEod
|
||||
// edges.
|
||||
remove_in_edge_if(h.acceptEod, SourceHasEdgeToAccept(h), h.g);
|
||||
remove_in_edge_if(h.acceptEod, SourceHasEdgeToAccept(h), h);
|
||||
}
|
||||
|
||||
void prefilterReductions(NGHolder &h, const CompileContext &cc) {
|
||||
@@ -378,13 +372,13 @@ void prefilterReductions(NGHolder &h, const CompileContext &cc) {
|
||||
DEBUG_PRINTF("before: graph with %zu vertices, %zu edges\n",
|
||||
num_vertices(h), num_edges(h));
|
||||
|
||||
h.renumberVertices();
|
||||
h.renumberEdges();
|
||||
renumber_vertices(h);
|
||||
renumber_edges(h);
|
||||
|
||||
reduceRegions(h);
|
||||
|
||||
h.renumberVertices();
|
||||
h.renumberEdges();
|
||||
renumber_vertices(h);
|
||||
renumber_edges(h);
|
||||
|
||||
DEBUG_PRINTF("after: graph with %zu vertices, %zu edges\n",
|
||||
num_vertices(h), num_edges(h));
|
||||
|
@@ -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:
|
||||
@@ -57,9 +57,8 @@ namespace ue2 {
|
||||
void pruneUnreachable(NGHolder &g) {
|
||||
deque<NFAVertex> dead;
|
||||
|
||||
if (!hasGreaterInDegree(1, g.acceptEod, g) &&
|
||||
!hasGreaterInDegree(0, g.accept, g) &&
|
||||
edge(g.accept, g.acceptEod, g).second) {
|
||||
if (in_degree(g.acceptEod, g) == 1 && !in_degree(g.accept, g)
|
||||
&& edge(g.accept, g.acceptEod, g).second) {
|
||||
// Trivial case: there are no in-edges to our accepts (other than
|
||||
// accept->acceptEod), so all non-specials are unreachable.
|
||||
for (auto v : vertices_range(g)) {
|
||||
@@ -70,10 +69,10 @@ void pruneUnreachable(NGHolder &g) {
|
||||
} else {
|
||||
// Walk a reverse graph from acceptEod with Boost's depth_first_visit
|
||||
// call.
|
||||
typedef reverse_graph<NFAGraph, NFAGraph&> RevNFAGraph;
|
||||
RevNFAGraph revg(g.g);
|
||||
typedef reverse_graph<NGHolder, NGHolder &> RevNFAGraph;
|
||||
RevNFAGraph revg(g);
|
||||
|
||||
map<NFAVertex, default_color_type> colours;
|
||||
map<RevNFAGraph::vertex_descriptor, default_color_type> colours;
|
||||
|
||||
depth_first_visit(revg, g.acceptEod,
|
||||
make_dfs_visitor(boost::null_visitor()),
|
||||
@@ -104,7 +103,8 @@ void pruneUnreachable(NGHolder &g) {
|
||||
|
||||
template<class nfag_t>
|
||||
static
|
||||
bool pruneForwardUseless(NGHolder &h, const nfag_t &g, NFAVertex s,
|
||||
bool pruneForwardUseless(NGHolder &h, const nfag_t &g,
|
||||
typename nfag_t::vertex_descriptor s,
|
||||
vector<default_color_type> &vertexColor) {
|
||||
// Begin with all vertices set to white, as DFV only marks visited
|
||||
// vertices.
|
||||
@@ -122,9 +122,9 @@ bool pruneForwardUseless(NGHolder &h, const nfag_t &g, NFAVertex s,
|
||||
for (auto v : vertices_range(g)) {
|
||||
u32 idx = g[v].index;
|
||||
if (!is_special(v, g) && vertexColor[idx] == boost::white_color) {
|
||||
DEBUG_PRINTF("vertex %u is unreachable from %u\n",
|
||||
DEBUG_PRINTF("vertex %zu is unreachable from %zu\n",
|
||||
g[v].index, g[s].index);
|
||||
dead.push_back(v);
|
||||
dead.push_back(NFAVertex(v));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,17 +145,17 @@ void pruneUseless(NGHolder &g, bool renumber) {
|
||||
assert(hasCorrectlyNumberedVertices(g));
|
||||
vector<default_color_type> vertexColor(num_vertices(g));
|
||||
|
||||
bool work_done = pruneForwardUseless(g, g.g, g.start, vertexColor);
|
||||
work_done |= pruneForwardUseless(
|
||||
g, reverse_graph<NFAGraph, NFAGraph &>(g.g), g.acceptEod, vertexColor);
|
||||
bool work_done = pruneForwardUseless(g, g, g.start, vertexColor);
|
||||
work_done |= pruneForwardUseless(g, reverse_graph<NGHolder, NGHolder &>(g),
|
||||
g.acceptEod, vertexColor);
|
||||
|
||||
if (!work_done) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (renumber) {
|
||||
g.renumberEdges();
|
||||
g.renumberVertices();
|
||||
renumber_edges(g);
|
||||
renumber_vertices(g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ void pruneEmptyVertices(NGHolder &g) {
|
||||
|
||||
const CharReach &cr = g[v].char_reach;
|
||||
if (cr.none()) {
|
||||
DEBUG_PRINTF("empty: %u\n", g[v].index);
|
||||
DEBUG_PRINTF("empty: %zu\n", g[v].index);
|
||||
dead.push_back(v);
|
||||
}
|
||||
}
|
||||
@@ -234,7 +234,7 @@ bool isDominatedByReporter(const NGHolder &g,
|
||||
// Note: reporters with edges only to acceptEod are not considered to
|
||||
// dominate.
|
||||
if (edge(u, g.accept, g).second && contains(g[u].reports, report_id)) {
|
||||
DEBUG_PRINTF("%u is dominated by %u, and both report %u\n",
|
||||
DEBUG_PRINTF("%zu is dominated by %zu, and both report %u\n",
|
||||
g[v].index, g[u].index, report_id);
|
||||
return true;
|
||||
}
|
||||
@@ -296,7 +296,7 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
|
||||
}
|
||||
|
||||
|
||||
sort(begin(reporters), end(reporters), make_index_ordering(g));
|
||||
sort(begin(reporters), end(reporters));
|
||||
reporters.erase(unique(begin(reporters), end(reporters)), end(reporters));
|
||||
|
||||
DEBUG_PRINTF("%zu vertices have simple exhaustible reports\n",
|
||||
@@ -315,14 +315,14 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
|
||||
continue;
|
||||
}
|
||||
if (isDominatedByReporter(g, dom, v, report_id)) {
|
||||
DEBUG_PRINTF("removed dominated report %u from vertex %u\n",
|
||||
DEBUG_PRINTF("removed dominated report %u from vertex %zu\n",
|
||||
report_id, g[v].index);
|
||||
g[v].reports.erase(report_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (g[v].reports.empty()) {
|
||||
DEBUG_PRINTF("removed edges to accepts from %u, no reports left\n",
|
||||
DEBUG_PRINTF("removed edges to accepts from %zu, no reports left\n",
|
||||
g[v].index);
|
||||
remove_edge(v, g.accept, g);
|
||||
remove_edge(v, g.acceptEod, g);
|
||||
@@ -337,7 +337,7 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
|
||||
if (hasOnlySelfLoopAndExhaustibleAccepts(g, rm, v)) {
|
||||
remove_edge(v, v, g);
|
||||
modified = true;
|
||||
DEBUG_PRINTF("removed self-loop on %u\n", g[v].index);
|
||||
DEBUG_PRINTF("removed self-loop on %zu\n", g[v].index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
|
||||
|
||||
// We may have only removed self-loops, in which case pruneUseless wouldn't
|
||||
// renumber, so we do edge renumbering explicitly here.
|
||||
g.renumberEdges();
|
||||
renumber_edges(g);
|
||||
}
|
||||
|
||||
/** Removes the given Report ID from vertices connected to accept, and then
|
||||
@@ -388,8 +388,8 @@ void pruneReport(NGHolder &g, ReportID report) {
|
||||
|
||||
remove_edges(dead, g);
|
||||
pruneUnreachable(g);
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
}
|
||||
|
||||
/** Removes all Report IDs bar the given one from vertices connected to accept,
|
||||
@@ -431,8 +431,8 @@ void pruneAllOtherReports(NGHolder &g, ReportID report) {
|
||||
|
||||
remove_edges(dead, g);
|
||||
pruneUnreachable(g);
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
}
|
||||
|
||||
} // namespace ue2
|
||||
|
@@ -59,7 +59,7 @@ static
|
||||
size_t countChain(const NGHolder &g, NFAVertex v) {
|
||||
size_t count = 0;
|
||||
while (v) {
|
||||
DEBUG_PRINTF("counting vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("counting vertex %zu\n", g[v].index);
|
||||
if (is_special(v, g)) {
|
||||
break;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ void wireNewAccepts(NGHolder &g, NFAVertex head,
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("adding edge: %u -> accept\n", g[u].index);
|
||||
DEBUG_PRINTF("adding edge: %zu -> accept\n", g[u].index);
|
||||
assert(!edge(u, g.accept, g).second);
|
||||
assert(!edge(u, g.acceptEod, g).second);
|
||||
add_edge(u, g.accept, g);
|
||||
@@ -136,13 +136,13 @@ bool singleStart(const NGHolder &g) {
|
||||
|
||||
for (auto v : adjacent_vertices_range(g.start, g)) {
|
||||
if (!is_special(v, g)) {
|
||||
DEBUG_PRINTF("saw %u\n", g[v].index);
|
||||
DEBUG_PRINTF("saw %zu\n", g[v].index);
|
||||
seen.insert(v);
|
||||
}
|
||||
}
|
||||
for (auto v : adjacent_vertices_range(g.startDs, g)) {
|
||||
if (!is_special(v, g)) {
|
||||
DEBUG_PRINTF("saw %u\n", g[v].index);
|
||||
DEBUG_PRINTF("saw %zu\n", g[v].index);
|
||||
seen.insert(v);
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ bool triggerResetsPuff(const NGHolder &g, NFAVertex head) {
|
||||
|
||||
for (auto u : inv_adjacent_vertices_range(head, g)) {
|
||||
if (!g[u].char_reach.isSubsetOf(puff_escapes)) {
|
||||
DEBUG_PRINTF("no reset on trigger %u %u\n", g[u].index,
|
||||
DEBUG_PRINTF("no reset on trigger %zu %zu\n", g[u].index,
|
||||
g[head].index);
|
||||
return false;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ bool triggerResetsPuff(const NGHolder &g, NFAVertex head) {
|
||||
* */
|
||||
static
|
||||
bool triggerFloodsPuff(const NGHolder &g, NFAVertex head) {
|
||||
DEBUG_PRINTF("head = %u\n", g[head].index);
|
||||
DEBUG_PRINTF("head = %zu\n", g[head].index);
|
||||
|
||||
const CharReach &puff_cr = g[head].char_reach;
|
||||
|
||||
@@ -186,14 +186,14 @@ bool triggerFloodsPuff(const NGHolder &g, NFAVertex head) {
|
||||
if (proper_in_degree(head, g) == 1
|
||||
&& puff_cr == g[getSoleSourceVertex(g, head)].char_reach) {
|
||||
head = getSoleSourceVertex(g, head);
|
||||
DEBUG_PRINTF("temp new head = %u\n", g[head].index);
|
||||
DEBUG_PRINTF("temp new head = %zu\n", g[head].index);
|
||||
}
|
||||
|
||||
for (auto s : inv_adjacent_vertices_range(head, g)) {
|
||||
DEBUG_PRINTF("s = %u\n", g[s].index);
|
||||
DEBUG_PRINTF("s = %zu\n", g[s].index);
|
||||
if (!puff_cr.isSubsetOf(g[s].char_reach)) {
|
||||
DEBUG_PRINTF("no flood on trigger %u %u\n",
|
||||
g[s].index, g[head].index);
|
||||
DEBUG_PRINTF("no flood on trigger %zu %zu\n", g[s].index,
|
||||
g[head].index);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ void constructPuff(NGHolder &g, const NFAVertex a, const NFAVertex puffv,
|
||||
RoseBuild &rose, ReportManager &rm,
|
||||
flat_set<ReportID> &chain_reports, bool prefilter) {
|
||||
DEBUG_PRINTF("constructing Puff for report %u\n", report);
|
||||
DEBUG_PRINTF("a = %u\n", g[a].index);
|
||||
DEBUG_PRINTF("a = %zu\n", g[a].index);
|
||||
|
||||
const Report &puff_report = rm.getReport(report);
|
||||
const bool simple_exhaust = isSimpleExhaustible(puff_report);
|
||||
@@ -349,7 +349,7 @@ bool doComponent(RoseBuild &rose, ReportManager &rm, NGHolder &g, NFAVertex a,
|
||||
}
|
||||
|
||||
nodes.push_back(a);
|
||||
DEBUG_PRINTF("vertex %u has in_degree %zu\n", g[a].index,
|
||||
DEBUG_PRINTF("vertex %zu has in_degree %zu\n", g[a].index,
|
||||
in_degree(a, g));
|
||||
|
||||
a = getSoleSourceVertex(g, a);
|
||||
@@ -387,10 +387,10 @@ bool doComponent(RoseBuild &rose, ReportManager &rm, NGHolder &g, NFAVertex a,
|
||||
|
||||
bool auto_restart = false;
|
||||
|
||||
DEBUG_PRINTF("a = %u\n", g[a].index);
|
||||
DEBUG_PRINTF("a = %zu\n", g[a].index);
|
||||
|
||||
if (nodes.size() < MIN_PUFF_LENGTH || a == g.startDs) {
|
||||
DEBUG_PRINTF("bad %zu %u\n", nodes.size(), g[a].index);
|
||||
DEBUG_PRINTF("bad %zu %zu\n", nodes.size(), g[a].index);
|
||||
if (nodes.size() < MIN_PUFF_LENGTH) {
|
||||
return false;
|
||||
} else {
|
||||
|
@@ -309,14 +309,10 @@ static
|
||||
bool hasInEdgeTops(const NGHolder &g, NFAVertex v) {
|
||||
bool exists;
|
||||
NFAEdge e;
|
||||
tie(e, exists) = edge_by_target(g.start, v, g);
|
||||
if (exists && !g[e].tops.empty()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
tie(e, exists) = edge(g.start, v, g);
|
||||
return exists && !g[e].tops.empty();
|
||||
}
|
||||
|
||||
|
||||
/** Transform (1), removal of redundant vertices. */
|
||||
static
|
||||
bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
|
||||
@@ -348,8 +344,7 @@ bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
|
||||
}
|
||||
|
||||
if (info.pred.empty() || info.succ.empty()) {
|
||||
DEBUG_PRINTF("vertex %u has empty pred/succ list\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu has empty pred/succ list\n", g[v].index);
|
||||
assert(0); // non-special states should always have succ/pred lists
|
||||
continue;
|
||||
}
|
||||
@@ -448,7 +443,7 @@ bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
|
||||
|
||||
CharReach &otherReach = g[t].char_reach;
|
||||
if (currReach.isSubsetOf(otherReach)) {
|
||||
DEBUG_PRINTF("removing redundant vertex %u (keeping %u)\n",
|
||||
DEBUG_PRINTF("removing redundant vertex %zu (keeping %zu)\n",
|
||||
g[v].index, g[t].index);
|
||||
markForRemoval(v, infoMap, removable);
|
||||
changed = true;
|
||||
@@ -539,9 +534,6 @@ bool doDiamondMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ensure that we look for candidates in the same order */
|
||||
sort(intersection.begin(), intersection.end(), make_index_ordering(g));
|
||||
|
||||
const CharReach &currReach = g[v].char_reach;
|
||||
const auto &currReports = g[v].reports;
|
||||
for (auto t : intersection) {
|
||||
@@ -578,8 +570,8 @@ bool doDiamondMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
|
||||
CharReach &otherReach = g[t].char_reach;
|
||||
otherReach |= currReach;
|
||||
// v can be removed
|
||||
DEBUG_PRINTF("removing redundant vertex %u and merging "
|
||||
"reachability with vertex %u\n",
|
||||
DEBUG_PRINTF("removing redundant vertex %zu and merging "
|
||||
"reachability with vertex %zu\n",
|
||||
g[v].index, g[t].index);
|
||||
markForRemoval(v, infoMap, removable);
|
||||
changed = true;
|
||||
@@ -645,14 +637,14 @@ bool reversePathReachSubset(const NFAEdge &e, const NFAVertex &dom,
|
||||
}
|
||||
|
||||
NFAVertex start = source(e, g);
|
||||
using RevGraph = boost::reverse_graph<NFAGraph, const NFAGraph &>;
|
||||
using RevGraph = boost::reverse_graph<NGHolder, const NGHolder &>;
|
||||
map<RevGraph::vertex_descriptor, boost::default_color_type> vertexColor;
|
||||
|
||||
// Walk the graph backwards from v, examining each node. We fail (return
|
||||
// false) if we encounter a node with reach NOT a subset of domReach, and
|
||||
// we stop searching at dom.
|
||||
try {
|
||||
depth_first_visit(RevGraph(g.g), start,
|
||||
depth_first_visit(RevGraph(g), start,
|
||||
ReachSubsetVisitor(domReach),
|
||||
make_assoc_property_map(vertexColor),
|
||||
VertexIs<RevGraph, RevGraph::vertex_descriptor>(dom));
|
||||
@@ -674,16 +666,15 @@ bool forwardPathReachSubset(const NFAEdge &e, const NFAVertex &dom,
|
||||
}
|
||||
|
||||
NFAVertex start = target(e, g);
|
||||
map<NFAGraph::vertex_descriptor, boost::default_color_type> vertexColor;
|
||||
map<NFAVertex, boost::default_color_type> vertexColor;
|
||||
|
||||
// Walk the graph forward from v, examining each node. We fail (return
|
||||
// false) if we encounter a node with reach NOT a subset of domReach, and
|
||||
// we stop searching at dom.
|
||||
try {
|
||||
depth_first_visit(g.g, start,
|
||||
ReachSubsetVisitor(domReach),
|
||||
depth_first_visit(g, start, ReachSubsetVisitor(domReach),
|
||||
make_assoc_property_map(vertexColor),
|
||||
VertexIs<NFAGraph, NFAVertex>(dom));
|
||||
VertexIs<NGHolder, NFAVertex>(dom));
|
||||
} catch(ReachMismatch&) {
|
||||
return false;
|
||||
}
|
||||
@@ -775,9 +766,8 @@ void findCyclicDom(NGHolder &g, vector<bool> &cyclic,
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("vertex %u is dominated by directly-connected cyclic "
|
||||
"vertex %u\n", g[v].index,
|
||||
g[dom].index);
|
||||
DEBUG_PRINTF("vertex %zu is dominated by directly-connected cyclic "
|
||||
"vertex %zu\n", g[v].index, g[dom].index);
|
||||
|
||||
// iff all paths through in-edge e of v involve vertices whose
|
||||
// reachability is a subset of reach(dom), we can delete edge e.
|
||||
@@ -787,8 +777,8 @@ void findCyclicDom(NGHolder &g, vector<bool> &cyclic,
|
||||
}
|
||||
|
||||
if (reversePathReachSubset(e, dom, g)) {
|
||||
DEBUG_PRINTF("edge (%u, %u) can be removed: leading paths "
|
||||
"share dom reach\n",
|
||||
DEBUG_PRINTF("edge (%zu, %zu) can be removed: leading "
|
||||
"paths share dom reach\n",
|
||||
g[source(e, g)].index, g[target(e, g)].index);
|
||||
dead.insert(e);
|
||||
if (source(e, g) == v) {
|
||||
@@ -814,11 +804,9 @@ void findCyclicPostDom(NGHolder &g, vector<bool> &cyclic,
|
||||
|
||||
// Path out through a post-dominator (e.g. a?.+foobar')
|
||||
NFAVertex postdom = postdominators[v];
|
||||
if (postdom && cyclic[g[postdom].index]
|
||||
&& edge(v, postdom, g).second) {
|
||||
DEBUG_PRINTF("vertex %u is postdominated by directly-connected "
|
||||
"cyclic vertex %u\n", g[v].index,
|
||||
g[postdom].index);
|
||||
if (postdom && cyclic[g[postdom].index] && edge(v, postdom, g).second) {
|
||||
DEBUG_PRINTF("vertex %zu is postdominated by directly-connected "
|
||||
"cyclic vertex %zu\n", g[v].index, g[postdom].index);
|
||||
|
||||
// iff all paths through in-edge e of v involve vertices whose
|
||||
// reachability is a subset of reach(dom), we can delete edge e.
|
||||
@@ -828,8 +816,8 @@ void findCyclicPostDom(NGHolder &g, vector<bool> &cyclic,
|
||||
}
|
||||
|
||||
if (forwardPathReachSubset(e, postdom, g)) {
|
||||
DEBUG_PRINTF("edge (%u, %u) can be removed: trailing paths "
|
||||
"share postdom reach\n",
|
||||
DEBUG_PRINTF("edge (%zu, %zu) can be removed: trailing "
|
||||
"paths share postdom reach\n",
|
||||
g[source(e, g)].index, g[target(e, g)].index);
|
||||
if (target(e, g) == v) {
|
||||
cyclic[g[v].index] = false;
|
||||
@@ -844,7 +832,7 @@ void findCyclicPostDom(NGHolder &g, vector<bool> &cyclic,
|
||||
|
||||
bool removeRedundancy(NGHolder &g, som_type som) {
|
||||
DEBUG_PRINTF("rr som = %d\n", (int)som);
|
||||
g.renumberVertices();
|
||||
renumber_vertices(g);
|
||||
|
||||
// Cheap check: if all the non-special vertices have in-degree one and
|
||||
// out-degree one, there's no redundancy in this here graph and we can
|
||||
|
@@ -71,7 +71,7 @@ using namespace std;
|
||||
namespace ue2 {
|
||||
|
||||
typedef ue2::unordered_set<NFAEdge> BackEdgeSet;
|
||||
typedef boost::filtered_graph<NFAGraph, bad_edge_filter<BackEdgeSet>>
|
||||
typedef boost::filtered_graph<NGHolder, bad_edge_filter<BackEdgeSet>>
|
||||
AcyclicGraph;
|
||||
|
||||
namespace {
|
||||
@@ -92,17 +92,17 @@ void checkAndAddExitCandidate(const AcyclicGraph &g,
|
||||
|
||||
/* find the set of vertices reachable from v which are not in r */
|
||||
for (auto w : adjacent_vertices_range(v, g)) {
|
||||
if (!contains(r, w)) {
|
||||
if (!contains(r, NFAVertex(w))) {
|
||||
if (!open) {
|
||||
exits->push_back(exit_info(v));
|
||||
exits->push_back(exit_info(NFAVertex(v)));
|
||||
open = &exits->back().open;
|
||||
}
|
||||
open->insert(w);
|
||||
open->insert(NFAVertex(w));
|
||||
}
|
||||
}
|
||||
|
||||
if (open) {
|
||||
DEBUG_PRINTF("exit %u\n", g[v].index);
|
||||
DEBUG_PRINTF("exit %zu\n", g[v].index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ bool exitValid(UNUSED const AcyclicGraph &g, const vector<exit_info> &exits,
|
||||
return true;
|
||||
}
|
||||
if (exits.size() == 1 && open_jumps.size() == 1) {
|
||||
DEBUG_PRINTF("oj %u, e %u\n", g[*open_jumps.begin()].index,
|
||||
DEBUG_PRINTF("oj %zu, e %zu\n", g[*open_jumps.begin()].index,
|
||||
g[exits[0].exit].index);
|
||||
if (*open_jumps.begin() == exits[0].exit) {
|
||||
return true;
|
||||
@@ -190,7 +190,7 @@ void buildInitialCandidate(const AcyclicGraph &g,
|
||||
if (exits->empty()) {
|
||||
DEBUG_PRINTF("odd\n");
|
||||
candidate->clear();
|
||||
DEBUG_PRINTF("adding %u to initial\n", g[*it].index);
|
||||
DEBUG_PRINTF("adding %zu to initial\n", g[*it].index);
|
||||
candidate->insert(*it);
|
||||
open_jumps->erase(*it);
|
||||
checkAndAddExitCandidate(g, *candidate, *it, exits);
|
||||
@@ -202,7 +202,7 @@ void buildInitialCandidate(const AcyclicGraph &g,
|
||||
candidate->clear();
|
||||
|
||||
for (; it != ite; ++it) {
|
||||
DEBUG_PRINTF("adding %u to initial\n", g[*it].index);
|
||||
DEBUG_PRINTF("adding %zu to initial\n", g[*it].index);
|
||||
candidate->insert(*it);
|
||||
if (contains(enters, *it)) {
|
||||
break;
|
||||
@@ -231,10 +231,10 @@ void findDagLeaders(const NGHolder &h, const AcyclicGraph &g,
|
||||
vector<exit_info> exits;
|
||||
ue2::unordered_set<NFAVertex> candidate;
|
||||
ue2::unordered_set<NFAVertex> open_jumps;
|
||||
DEBUG_PRINTF("adding %u to current\n", g[*t_it].index);
|
||||
DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index);
|
||||
assert(t_it != topo.rend());
|
||||
candidate.insert(*t_it++);
|
||||
DEBUG_PRINTF("adding %u to current\n", g[*t_it].index);
|
||||
DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index);
|
||||
assert(t_it != topo.rend());
|
||||
candidate.insert(*t_it++);
|
||||
findExits(g, candidate, &exits);
|
||||
@@ -257,7 +257,7 @@ void findDagLeaders(const NGHolder &h, const AcyclicGraph &g,
|
||||
&open_jumps);
|
||||
} else {
|
||||
NFAVertex curr = *t_it;
|
||||
DEBUG_PRINTF("adding %u to current\n", g[curr].index);
|
||||
DEBUG_PRINTF("adding %zu to current\n", g[curr].index);
|
||||
candidate.insert(curr);
|
||||
open_jumps.erase(curr);
|
||||
refineExits(g, candidate, *t_it, &exits);
|
||||
@@ -284,7 +284,7 @@ void mergeUnderBackEdges(const NGHolder &g, const vector<NFAVertex> &topo,
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("merging v = %u(%u), u = %u(%u)\n", g[v].index, rv,
|
||||
DEBUG_PRINTF("merging v = %zu(%u), u = %zu(%u)\n", g[v].index, rv,
|
||||
g[u].index, ru);
|
||||
assert(rv < ru);
|
||||
|
||||
@@ -350,8 +350,8 @@ void liftSinks(const AcyclicGraph &acyclic_g, vector<NFAVertex> &topoOrder) {
|
||||
}
|
||||
|
||||
if (isLeafNode(v, acyclic_g)) {
|
||||
DEBUG_PRINTF("sink found %u\n", acyclic_g[v].index);
|
||||
sinks.insert(v);
|
||||
DEBUG_PRINTF("sink found %zu\n", acyclic_g[v].index);
|
||||
sinks.insert(NFAVertex(v));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,18 +365,18 @@ void liftSinks(const AcyclicGraph &acyclic_g, vector<NFAVertex> &topoOrder) {
|
||||
DEBUG_PRINTF("look\n");
|
||||
changed = false;
|
||||
for (auto v : vertices_range(acyclic_g)) {
|
||||
if (is_special(v, acyclic_g) || contains(sinks, v)) {
|
||||
if (is_special(v, acyclic_g) || contains(sinks, NFAVertex(v))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto w : adjacent_vertices_range(v, acyclic_g)) {
|
||||
if (!contains(sinks, w)) {
|
||||
if (!contains(sinks, NFAVertex(w))) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("sink found %u\n", acyclic_g[v].index);
|
||||
sinks.insert(v);
|
||||
DEBUG_PRINTF("sink found %zu\n", acyclic_g[v].index);
|
||||
sinks.insert(NFAVertex(v));
|
||||
changed = true;
|
||||
next:;
|
||||
}
|
||||
@@ -387,10 +387,10 @@ void liftSinks(const AcyclicGraph &acyclic_g, vector<NFAVertex> &topoOrder) {
|
||||
continue;
|
||||
}
|
||||
NFAVertex s = *ri;
|
||||
DEBUG_PRINTF("handling sink %u\n", acyclic_g[s].index);
|
||||
DEBUG_PRINTF("handling sink %zu\n", acyclic_g[s].index);
|
||||
ue2::unordered_set<NFAVertex> parents;
|
||||
for (const auto &e : in_edges_range(s, acyclic_g)) {
|
||||
parents.insert(source(e, acyclic_g));
|
||||
parents.insert(NFAVertex(source(e, acyclic_g)));
|
||||
}
|
||||
|
||||
/* vertex has no children not reachable on a back edge, bubble the
|
||||
@@ -417,10 +417,9 @@ vector<NFAVertex> buildTopoOrder(const NGHolder &w,
|
||||
vector<boost::default_color_type> &colours) {
|
||||
vector<NFAVertex> topoOrder;
|
||||
|
||||
topological_sort(
|
||||
acyclic_g, back_inserter(topoOrder),
|
||||
color_map(make_iterator_property_map(
|
||||
colours.begin(), get(&NFAGraphVertexProps::index, acyclic_g))));
|
||||
topological_sort(acyclic_g, back_inserter(topoOrder),
|
||||
color_map(make_iterator_property_map(colours.begin(),
|
||||
get(vertex_index, acyclic_g))));
|
||||
|
||||
reorderSpecials(w, acyclic_g, topoOrder);
|
||||
|
||||
@@ -432,7 +431,7 @@ vector<NFAVertex> buildTopoOrder(const NGHolder &w,
|
||||
|
||||
DEBUG_PRINTF("TOPO ORDER\n");
|
||||
for (auto ri = topoOrder.rbegin(); ri != topoOrder.rend(); ++ri) {
|
||||
DEBUG_PRINTF("[%u]\n", acyclic_g[*ri].index);
|
||||
DEBUG_PRINTF("[%zu]\n", acyclic_g[*ri].index);
|
||||
}
|
||||
DEBUG_PRINTF("----------\n");
|
||||
|
||||
@@ -448,14 +447,14 @@ ue2::unordered_map<NFAVertex, u32> assignRegions(const NGHolder &g) {
|
||||
|
||||
// Build an acyclic graph for this NGHolder.
|
||||
BackEdgeSet deadEdges;
|
||||
depth_first_search(
|
||||
g.g, visitor(BackEdges<BackEdgeSet>(deadEdges))
|
||||
.root_vertex(g.start)
|
||||
.color_map(make_iterator_property_map(
|
||||
colours.begin(), get(&NFAGraphVertexProps::index, g.g))));
|
||||
depth_first_search(g,
|
||||
visitor(BackEdges<BackEdgeSet>(deadEdges))
|
||||
.root_vertex(g.start)
|
||||
.color_map(make_iterator_property_map(colours.begin(),
|
||||
get(vertex_index, g))));
|
||||
|
||||
auto af = make_bad_edge_filter(&deadEdges);
|
||||
AcyclicGraph acyclic_g(g.g, af);
|
||||
AcyclicGraph acyclic_g(g, af);
|
||||
|
||||
// Build a (reverse) topological ordering.
|
||||
vector<NFAVertex> topoOrder = buildTopoOrder(g, acyclic_g, colours);
|
||||
|
@@ -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:
|
||||
@@ -181,7 +181,7 @@ bool isOptionalRegion(const Graph &g, NFAVertex v,
|
||||
const ue2::unordered_map<NFAVertex, u32> ®ion_map) {
|
||||
assert(isRegionEntry(g, v, region_map));
|
||||
|
||||
DEBUG_PRINTF("check if r%u is optional (inspecting v%u)\n",
|
||||
DEBUG_PRINTF("check if r%u is optional (inspecting v%zu)\n",
|
||||
region_map.at(v), g[v].index);
|
||||
|
||||
// Region zero is never optional.
|
||||
@@ -198,12 +198,12 @@ bool isOptionalRegion(const Graph &g, NFAVertex v,
|
||||
if (inSameRegion(g, v, u, region_map)) {
|
||||
continue;
|
||||
}
|
||||
DEBUG_PRINTF(" searching from u=%u\n", g[u].index);
|
||||
DEBUG_PRINTF(" searching from u=%zu\n", g[u].index);
|
||||
|
||||
assert(inEarlierRegion(g, v, u, region_map));
|
||||
|
||||
for (auto w : adjacent_vertices_range(u, g)) {
|
||||
DEBUG_PRINTF(" searching to w=%u\n", g[w].index);
|
||||
DEBUG_PRINTF(" searching to w=%zu\n", g[w].index);
|
||||
if (inLaterRegion(g, v, w, region_map)) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -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:
|
||||
@@ -90,7 +90,7 @@ void processCyclicStateForward(NGHolder &h, NFAVertex cyc,
|
||||
CharReach cr = h[cyc].char_reach;
|
||||
auto reports = h[cyc].reports;
|
||||
|
||||
DEBUG_PRINTF("going forward from %u/%u\n", h[cyc].index,
|
||||
DEBUG_PRINTF("going forward from %zu/%u\n", h[cyc].index,
|
||||
region);
|
||||
|
||||
map<u32, RegionInfo>::const_iterator it;
|
||||
@@ -98,7 +98,7 @@ void processCyclicStateForward(NGHolder &h, NFAVertex cyc,
|
||||
NFAVertex v = it->second.entry;
|
||||
const CharReach ®ion_cr = it->second.cr;
|
||||
assert(isRegionEntry(h, v, region_map) && !is_special(v, h));
|
||||
DEBUG_PRINTF("checking %u\n", h[v].index);
|
||||
DEBUG_PRINTF("checking %zu\n", h[v].index);
|
||||
|
||||
if (!region_cr.isSubsetOf(cr)) {
|
||||
DEBUG_PRINTF("doesn't cover the reach of region %u\n", region);
|
||||
@@ -107,8 +107,8 @@ void processCyclicStateForward(NGHolder &h, NFAVertex cyc,
|
||||
|
||||
if (isOptionalRegion(h, v, region_map)
|
||||
&& !regionHasUnexpectedAccept(h, region, reports, region_map)) {
|
||||
DEBUG_PRINTF("cyclic state %u leads to optional region leader %u\n",
|
||||
h[cyc].index, h[v].index);
|
||||
DEBUG_PRINTF("cyclic state %zu leads to optional region leader"
|
||||
" %zu\n", h[cyc].index, h[v].index);
|
||||
deadRegions.insert(region);
|
||||
} else if (isSingletonRegion(h, v, region_map)) {
|
||||
/* we can use this region as straw and suck in optional regions on
|
||||
@@ -136,14 +136,14 @@ void processCyclicStateReverse(NGHolder &h, NFAVertex cyc,
|
||||
CharReach cr = h[cyc].char_reach;
|
||||
auto reports = h[cyc].reports;
|
||||
|
||||
DEBUG_PRINTF("going back from %u/%u\n", h[cyc].index, region);
|
||||
DEBUG_PRINTF("going back from %zu/%u\n", h[cyc].index, region);
|
||||
|
||||
map<u32, RegionInfo>::const_iterator it;
|
||||
while ((it = info.find(--region)) != info.end()) {
|
||||
NFAVertex v = it->second.entry;
|
||||
const CharReach ®ion_cr = it->second.cr;
|
||||
assert(isRegionEntry(h, v, region_map) && !is_special(v, h));
|
||||
DEBUG_PRINTF("checking %u\n", h[v].index);
|
||||
DEBUG_PRINTF("checking %zu\n", h[v].index);
|
||||
|
||||
if (!region_cr.isSubsetOf(cr)) {
|
||||
DEBUG_PRINTF("doesn't cover the reach of region %u\n", region);
|
||||
@@ -152,7 +152,7 @@ void processCyclicStateReverse(NGHolder &h, NFAVertex cyc,
|
||||
|
||||
if (isOptionalRegion(h, v, region_map)
|
||||
&& !regionHasUnexpectedAccept(h, region, reports, region_map)) {
|
||||
DEBUG_PRINTF("cyclic state %u trails optional region leader %u\n",
|
||||
DEBUG_PRINTF("cyclic state %zu trails optional region leader %zu\n",
|
||||
h[cyc].index, h[v].index);
|
||||
deadRegions.insert(region);
|
||||
} else if (isSingletonRegion(h, v, region_map)) {
|
||||
|
@@ -61,6 +61,8 @@
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
|
||||
using namespace std;
|
||||
using boost::depth_first_search;
|
||||
using boost::depth_first_visit;
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
@@ -99,7 +101,7 @@ struct ReachFilter {
|
||||
const Graph *g = nullptr;
|
||||
};
|
||||
|
||||
typedef boost::filtered_graph<NFAGraph, ReachFilter<NFAGraph> > RepeatGraph;
|
||||
typedef boost::filtered_graph<NGHolder, ReachFilter<NGHolder>> RepeatGraph;
|
||||
|
||||
struct ReachSubgraph {
|
||||
vector<NFAVertex> vertices;
|
||||
@@ -126,9 +128,11 @@ void findInitDepths(const NGHolder &g,
|
||||
}
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
static
|
||||
void buildTopoOrder(const Graph &g, vector<NFAVertex> &topoOrder) {
|
||||
vector<NFAVertex> buildTopoOrder(const RepeatGraph &g) {
|
||||
/* Note: RepeatGraph is a filtered version of NGHolder and still has
|
||||
* NFAVertex as its vertex descriptor */
|
||||
|
||||
typedef ue2::unordered_set<NFAEdge> EdgeSet;
|
||||
EdgeSet deadEdges;
|
||||
|
||||
@@ -140,10 +144,13 @@ void buildTopoOrder(const Graph &g, vector<NFAVertex> &topoOrder) {
|
||||
color_map(make_assoc_property_map(colours)));
|
||||
auto acyclic_g = make_filtered_graph(g, make_bad_edge_filter(&deadEdges));
|
||||
|
||||
vector<NFAVertex> topoOrder;
|
||||
topological_sort(acyclic_g, back_inserter(topoOrder),
|
||||
color_map(make_assoc_property_map(colours)));
|
||||
|
||||
reverse(topoOrder.begin(), topoOrder.end());
|
||||
|
||||
return topoOrder;
|
||||
}
|
||||
|
||||
static
|
||||
@@ -171,7 +178,7 @@ bool roguePredecessor(const NGHolder &g, NFAVertex v,
|
||||
continue;
|
||||
}
|
||||
if (!contains(pred, u)) {
|
||||
DEBUG_PRINTF("%u is a rogue pred\n", g[u].index);
|
||||
DEBUG_PRINTF("%zu is a rogue pred\n", g[u].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -197,7 +204,7 @@ bool rogueSuccessor(const NGHolder &g, NFAVertex v,
|
||||
}
|
||||
|
||||
if (!contains(succ, w)) {
|
||||
DEBUG_PRINTF("%u is a rogue succ\n", g[w].index);
|
||||
DEBUG_PRINTF("%zu is a rogue succ\n", g[w].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -223,8 +230,8 @@ bool hasDifferentTops(const NGHolder &g, const vector<NFAVertex> &verts) {
|
||||
if (u != g.start && u != g.startDs) {
|
||||
continue; // Only edges from starts have valid top properties.
|
||||
}
|
||||
DEBUG_PRINTF("edge (%u,%u) with %zu tops\n", g[u].index, g[v].index,
|
||||
g[e].tops.size());
|
||||
DEBUG_PRINTF("edge (%zu,%zu) with %zu tops\n", g[u].index,
|
||||
g[v].index, g[e].tops.size());
|
||||
if (!tops) {
|
||||
tops = &g[e].tops;
|
||||
} else if (g[e].tops != *tops) {
|
||||
@@ -243,14 +250,14 @@ bool vertexIsBad(const NGHolder &g, NFAVertex v,
|
||||
const ue2::unordered_set<NFAVertex> &pred,
|
||||
const ue2::unordered_set<NFAVertex> &succ,
|
||||
const flat_set<ReportID> &reports) {
|
||||
DEBUG_PRINTF("check vertex %u\n", g[v].index);
|
||||
DEBUG_PRINTF("check vertex %zu\n", g[v].index);
|
||||
|
||||
// We must drop any vertex that is the target of a back-edge within
|
||||
// our subgraph. The tail set contains all vertices that are after v in a
|
||||
// topo ordering.
|
||||
for (auto u : inv_adjacent_vertices_range(v, g)) {
|
||||
if (contains(tail, u)) {
|
||||
DEBUG_PRINTF("back-edge (%u,%u) in subgraph found\n",
|
||||
DEBUG_PRINTF("back-edge (%zu,%zu) in subgraph found\n",
|
||||
g[u].index, g[v].index);
|
||||
return true;
|
||||
}
|
||||
@@ -260,18 +267,18 @@ bool vertexIsBad(const NGHolder &g, NFAVertex v,
|
||||
// edges from *all* the vertices in pred and no other external entries.
|
||||
// Similarly for exits.
|
||||
if (roguePredecessor(g, v, involved, pred)) {
|
||||
DEBUG_PRINTF("preds for %u not well-formed\n", g[v].index);
|
||||
DEBUG_PRINTF("preds for %zu not well-formed\n", g[v].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rogueSuccessor(g, v, involved, succ)) {
|
||||
DEBUG_PRINTF("succs for %u not well-formed\n", g[v].index);
|
||||
DEBUG_PRINTF("succs for %zu not well-formed\n", g[v].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
// All reporting vertices should have the same reports.
|
||||
if (is_match_vertex(v, g) && reports != g[v].reports) {
|
||||
DEBUG_PRINTF("report mismatch to %u\n", g[v].index);
|
||||
DEBUG_PRINTF("report mismatch to %zu\n", g[v].index);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -291,8 +298,7 @@ void splitSubgraph(const NGHolder &g, const deque<NFAVertex> &verts,
|
||||
|
||||
NFAUndirectedGraph ug;
|
||||
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> old2new;
|
||||
ue2::unordered_map<u32, NFAVertex> newIdx2old;
|
||||
createUnGraph(verts_g.g, true, true, ug, old2new, newIdx2old);
|
||||
createUnGraph(verts_g, true, true, ug, old2new);
|
||||
|
||||
ue2::unordered_map<NFAUndirectedVertex, u32> repeatMap;
|
||||
|
||||
@@ -517,7 +523,7 @@ bool processSubgraph(const NGHolder &g, ReachSubgraph &rsi,
|
||||
if (u == first) {
|
||||
continue; // no self-loops
|
||||
}
|
||||
DEBUG_PRINTF("pred vertex %u\n", g[u].index);
|
||||
DEBUG_PRINTF("pred vertex %zu\n", g[u].index);
|
||||
dist[u].insert(0);
|
||||
}
|
||||
|
||||
@@ -619,7 +625,7 @@ void buildTugTrigger(NGHolder &g, NFAVertex cyclic, NFAVertex v,
|
||||
vector<NFAVertex> &tugs) {
|
||||
if (allPredsInSubgraph(v, g, involved)) {
|
||||
// We can transform this vertex into a tug trigger in-place.
|
||||
DEBUG_PRINTF("all preds in subgraph, vertex %u becomes tug\n",
|
||||
DEBUG_PRINTF("all preds in subgraph, vertex %zu becomes tug\n",
|
||||
g[v].index);
|
||||
add_edge(cyclic, v, g);
|
||||
tugs.push_back(v);
|
||||
@@ -631,7 +637,7 @@ void buildTugTrigger(NGHolder &g, NFAVertex cyclic, NFAVertex v,
|
||||
NFAVertex t = clone_vertex(g, v);
|
||||
depths[t] = depths[v];
|
||||
|
||||
DEBUG_PRINTF("there are other paths, cloned tug %u from vertex %u\n",
|
||||
DEBUG_PRINTF("there are other paths, cloned tug %zu from vertex %zu\n",
|
||||
g[t].index, g[v].index);
|
||||
|
||||
tugs.push_back(t);
|
||||
@@ -648,7 +654,7 @@ NFAVertex createCyclic(NGHolder &g, ReachSubgraph &rsi) {
|
||||
NFAVertex cyclic = clone_vertex(g, last);
|
||||
add_edge(cyclic, cyclic, g);
|
||||
|
||||
DEBUG_PRINTF("created cyclic vertex %u\n", g[cyclic].index);
|
||||
DEBUG_PRINTF("created cyclic vertex %zu\n", g[cyclic].index);
|
||||
return cyclic;
|
||||
}
|
||||
|
||||
@@ -659,7 +665,7 @@ NFAVertex createPos(NGHolder &g, ReachSubgraph &rsi) {
|
||||
|
||||
g[pos].char_reach = g[first].char_reach;
|
||||
|
||||
DEBUG_PRINTF("created pos vertex %u\n", g[pos].index);
|
||||
DEBUG_PRINTF("created pos vertex %zu\n", g[pos].index);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -705,7 +711,7 @@ void unpeelNearEnd(NGHolder &g, ReachSubgraph &rsi,
|
||||
|
||||
NFAVertex d = clone_vertex(g, last);
|
||||
depths[d] = depths[last];
|
||||
DEBUG_PRINTF("created vertex %u\n", g[d].index);
|
||||
DEBUG_PRINTF("created vertex %zu\n", g[d].index);
|
||||
|
||||
for (auto v : *succs) {
|
||||
add_edge(d, v, g);
|
||||
@@ -946,7 +952,7 @@ bool peelSubgraph(const NGHolder &g, const Grey &grey, ReachSubgraph &rsi,
|
||||
zap = it;
|
||||
break;
|
||||
} else {
|
||||
DEBUG_PRINTF("%u is involved in another repeat\n", g[*it].index);
|
||||
DEBUG_PRINTF("%zu is involved in another repeat\n", g[*it].index);
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF("peeling %zu vertices from front\n",
|
||||
@@ -963,7 +969,7 @@ bool peelSubgraph(const NGHolder &g, const Grey &grey, ReachSubgraph &rsi,
|
||||
zap = it.base(); // Note: erases everything after it.
|
||||
break;
|
||||
} else {
|
||||
DEBUG_PRINTF("%u is involved in another repeat\n", g[*it].index);
|
||||
DEBUG_PRINTF("%zu is involved in another repeat\n", g[*it].index);
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF("peeling %zu vertices from back\n",
|
||||
@@ -974,7 +980,7 @@ bool peelSubgraph(const NGHolder &g, const Grey &grey, ReachSubgraph &rsi,
|
||||
// no-no.
|
||||
for (auto v : rsi.vertices) {
|
||||
if (contains(created, v)) {
|
||||
DEBUG_PRINTF("vertex %u is in another repeat\n", g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu is in another repeat\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -997,7 +1003,7 @@ void peelStartDotStar(const NGHolder &g,
|
||||
|
||||
NFAVertex first = rsi.vertices.front();
|
||||
if (depths.at(first).fromStartDotStar.min == depth(1)) {
|
||||
DEBUG_PRINTF("peeling start front vertex %u\n", g[first].index);
|
||||
DEBUG_PRINTF("peeling start front vertex %zu\n", g[first].index);
|
||||
rsi.vertices.erase(rsi.vertices.begin());
|
||||
reprocessSubgraph(g, grey, rsi);
|
||||
}
|
||||
@@ -1006,8 +1012,8 @@ void peelStartDotStar(const NGHolder &g,
|
||||
static
|
||||
void buildReachSubgraphs(const NGHolder &g, vector<ReachSubgraph> &rs,
|
||||
const u32 minNumVertices) {
|
||||
const ReachFilter<NFAGraph> fil(&g.g);
|
||||
const RepeatGraph rg(g.g, fil);
|
||||
const ReachFilter<NGHolder> fil(&g);
|
||||
const RepeatGraph rg(g, fil);
|
||||
|
||||
if (!isCompBigEnough(rg, minNumVertices)) {
|
||||
DEBUG_PRINTF("component not big enough, bailing\n");
|
||||
@@ -1015,19 +1021,17 @@ void buildReachSubgraphs(const NGHolder &g, vector<ReachSubgraph> &rs,
|
||||
}
|
||||
|
||||
NFAUndirectedGraph ug;
|
||||
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> old2new;
|
||||
ue2::unordered_map<u32, NFAVertex> newIdx2old;
|
||||
createUnGraph(rg, true, true, ug, old2new, newIdx2old);
|
||||
unordered_map<RepeatGraph::vertex_descriptor, NFAUndirectedVertex> old2new;
|
||||
createUnGraph(rg, true, true, ug, old2new);
|
||||
|
||||
ue2::unordered_map<NFAUndirectedVertex, u32> repeatMap;
|
||||
unordered_map<NFAUndirectedVertex, u32> repeatMap;
|
||||
|
||||
unsigned int num;
|
||||
num = connected_components(ug, make_assoc_property_map(repeatMap));
|
||||
DEBUG_PRINTF("found %u connected repeat components\n", num);
|
||||
|
||||
// Now, we build a set of topo-ordered ReachSubgraphs.
|
||||
vector<NFAVertex> topoOrder;
|
||||
buildTopoOrder(rg, topoOrder);
|
||||
vector<NFAVertex> topoOrder = buildTopoOrder(rg);
|
||||
|
||||
rs.resize(num);
|
||||
|
||||
@@ -1078,7 +1082,7 @@ bool entered_at_fixed_offset(NFAVertex v, const NGHolder &g,
|
||||
if (is_triggered(g) && !contains(reached_by_fixed_tops, v)) {
|
||||
/* can't do this for infix/suffixes unless we know trigger literals
|
||||
* can only occur at one offset */
|
||||
DEBUG_PRINTF("bad top(s) for %u\n", g[v].index);
|
||||
DEBUG_PRINTF("bad top(s) for %zu\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1098,8 +1102,8 @@ bool entered_at_fixed_offset(NFAVertex v, const NGHolder &g,
|
||||
|
||||
for (auto u : inv_adjacent_vertices_range(v, g)) {
|
||||
const depth &u_max_depth = depths.at(u).fromStart.max;
|
||||
DEBUG_PRINTF("pred %u max depth %s from start\n",
|
||||
g[u].index, u_max_depth.str().c_str());
|
||||
DEBUG_PRINTF("pred %zu max depth %s from start\n", g[u].index,
|
||||
u_max_depth.str().c_str());
|
||||
if (u_max_depth != first - depth(1)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1122,7 +1126,7 @@ NFAVertex buildTriggerStates(NGHolder &g, const vector<CharReach> &trigger,
|
||||
u = v;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("trigger len=%zu has sink %u\n", trigger.size(), g[u].index);
|
||||
DEBUG_PRINTF("trigger len=%zu has sink %zu\n", trigger.size(), g[u].index);
|
||||
return u;
|
||||
}
|
||||
|
||||
@@ -1252,7 +1256,7 @@ void buildRepeatGraph(NGHolder &rg,
|
||||
if (is_triggered(rg)) {
|
||||
// Add vertices for all our triggers
|
||||
addTriggers(rg, triggers);
|
||||
rg.renumberVertices();
|
||||
renumber_vertices(rg);
|
||||
|
||||
// We don't know anything about how often this graph is triggered, so we
|
||||
// make the start vertex cyclic for the purposes of this analysis ONLY.
|
||||
@@ -1274,30 +1278,26 @@ void buildInputGraph(NGHolder &lhs,
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> &lhs_map,
|
||||
const NGHolder &g, const NFAVertex first,
|
||||
const map<u32, vector<vector<CharReach>>> &triggers) {
|
||||
DEBUG_PRINTF("building lhs with first=%u\n", g[first].index);
|
||||
DEBUG_PRINTF("building lhs with first=%zu\n", g[first].index);
|
||||
cloneHolder(lhs, g, &lhs_map);
|
||||
assert(g.kind == lhs.kind);
|
||||
addTriggers(lhs, triggers);
|
||||
lhs.renumberVertices();
|
||||
renumber_vertices(lhs);
|
||||
|
||||
// Replace each back-edge (u,v) with an edge (startDs,v), which will
|
||||
// generate entries at at least the rate of the loop created by that
|
||||
// back-edge.
|
||||
set<NFAEdge> dead;
|
||||
BackEdges<set<NFAEdge> > backEdgeVisitor(dead);
|
||||
depth_first_search(
|
||||
lhs.g, visitor(backEdgeVisitor)
|
||||
.root_vertex(lhs.start)
|
||||
.vertex_index_map(get(&NFAGraphVertexProps::index, lhs.g)));
|
||||
depth_first_search(lhs, visitor(backEdgeVisitor).root_vertex(lhs.start));
|
||||
for (const auto &e : dead) {
|
||||
const NFAVertex u = source(e, lhs), v = target(e, lhs);
|
||||
if (u == v) {
|
||||
continue; // Self-loops are OK.
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("replacing back-edge (%u,%u) with edge (startDs,%u)\n",
|
||||
lhs[u].index, lhs[v].index,
|
||||
lhs[v].index);
|
||||
DEBUG_PRINTF("replacing back-edge (%zu,%zu) with edge (startDs,%zu)\n",
|
||||
lhs[u].index, lhs[v].index, lhs[v].index);
|
||||
|
||||
add_edge_if_not_present(lhs.startDs, v, lhs);
|
||||
remove_edge(e, lhs);
|
||||
@@ -1384,13 +1384,13 @@ bool hasSoleEntry(const NGHolder &g, const ReachSubgraph &rsi,
|
||||
for (const auto &v : rsi.vertices) {
|
||||
assert(!is_special(v, g)); // no specials in repeats
|
||||
assert(contains(rg_map, v));
|
||||
DEBUG_PRINTF("rg vertex %u in repeat\n", rg[rg_map.at(v)].index);
|
||||
DEBUG_PRINTF("rg vertex %zu in repeat\n", rg[rg_map.at(v)].index);
|
||||
region_map.emplace(rg_map.at(v), repeat_region);
|
||||
}
|
||||
|
||||
for (const auto &v : vertices_range(rg)) {
|
||||
if (!contains(region_map, v)) {
|
||||
DEBUG_PRINTF("rg vertex %u in lhs (trigger)\n", rg[v].index);
|
||||
DEBUG_PRINTF("rg vertex %zu in lhs (trigger)\n", rg[v].index);
|
||||
region_map.emplace(v, lhs_region);
|
||||
}
|
||||
}
|
||||
@@ -1432,7 +1432,7 @@ struct StrawWalker {
|
||||
if (next == v) { // Ignore self loop.
|
||||
++ai;
|
||||
if (ai == ae) {
|
||||
return NFAGraph::null_vertex();
|
||||
return NGHolder::null_vertex();
|
||||
}
|
||||
next = *ai;
|
||||
}
|
||||
@@ -1447,7 +1447,7 @@ struct StrawWalker {
|
||||
succs.erase(v);
|
||||
for (tie(ai, ae) = adjacent_vertices(v, g); ai != ae; ++ai) {
|
||||
next = *ai;
|
||||
DEBUG_PRINTF("checking %u\n", g[next].index);
|
||||
DEBUG_PRINTF("checking %zu\n", g[next].index);
|
||||
if (next == v) {
|
||||
continue;
|
||||
}
|
||||
@@ -1468,32 +1468,31 @@ struct StrawWalker {
|
||||
return next;
|
||||
}
|
||||
DEBUG_PRINTF("bailing\n");
|
||||
return NFAGraph::null_vertex();
|
||||
return NGHolder::null_vertex();
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
NFAVertex walk(NFAVertex v, vector<NFAVertex> &straw) const {
|
||||
DEBUG_PRINTF("walk from %u\n", g[v].index);
|
||||
DEBUG_PRINTF("walk from %zu\n", g[v].index);
|
||||
ue2::unordered_set<NFAVertex> visited;
|
||||
straw.clear();
|
||||
|
||||
while (!is_special(v, g)) {
|
||||
DEBUG_PRINTF("checking %u\n", g[v].index);
|
||||
DEBUG_PRINTF("checking %zu\n", g[v].index);
|
||||
NFAVertex next = step(v);
|
||||
if (next == NFAGraph::null_vertex()) {
|
||||
if (next == NGHolder::null_vertex()) {
|
||||
break;
|
||||
}
|
||||
if (!visited.insert(next).second) {
|
||||
DEBUG_PRINTF("already visited %u, bailing\n",
|
||||
g[next].index);
|
||||
DEBUG_PRINTF("already visited %zu, bailing\n", g[next].index);
|
||||
break; /* don't want to get stuck in any complicated loops */
|
||||
}
|
||||
|
||||
const CharReach &reach_v = g[v].char_reach;
|
||||
const CharReach &reach_next = g[next].char_reach;
|
||||
if (!reach_v.isSubsetOf(reach_next)) {
|
||||
DEBUG_PRINTF("%u's reach is not a superset of %u's\n",
|
||||
DEBUG_PRINTF("%zu's reach is not a superset of %zu's\n",
|
||||
g[next].index, g[v].index);
|
||||
break;
|
||||
}
|
||||
@@ -1501,7 +1500,7 @@ struct StrawWalker {
|
||||
// If this is cyclic with the right reach, we're done. Note that
|
||||
// startDs fulfils this requirement.
|
||||
if (hasSelfLoop(next, g) && !isBoundedRepeatCyclic(next)) {
|
||||
DEBUG_PRINTF("found cyclic %u\n", g[next].index);
|
||||
DEBUG_PRINTF("found cyclic %zu\n", g[next].index);
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -1510,7 +1509,7 @@ struct StrawWalker {
|
||||
}
|
||||
|
||||
straw.clear();
|
||||
return NFAGraph::null_vertex();
|
||||
return NGHolder::null_vertex();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1525,8 +1524,8 @@ static
|
||||
NFAVertex walkStrawToCyclicRev(const NGHolder &g, NFAVertex v,
|
||||
const vector<BoundedRepeatData> &all_repeats,
|
||||
vector<NFAVertex> &straw) {
|
||||
typedef boost::reverse_graph<NFAGraph, const NFAGraph&> RevGraph;
|
||||
const RevGraph revg(g.g);
|
||||
typedef boost::reverse_graph<NGHolder, const NGHolder &> RevGraph;
|
||||
const RevGraph revg(g);
|
||||
|
||||
auto cyclic = StrawWalker<RevGraph>(g, revg, all_repeats).walk(v, straw);
|
||||
reverse(begin(straw), end(straw)); // path comes from cyclic
|
||||
@@ -1537,7 +1536,7 @@ static
|
||||
NFAVertex walkStrawToCyclicFwd(const NGHolder &g, NFAVertex v,
|
||||
const vector<BoundedRepeatData> &all_repeats,
|
||||
vector<NFAVertex> &straw) {
|
||||
return StrawWalker<NFAGraph>(g, g.g, all_repeats).walk(v, straw);
|
||||
return StrawWalker<NGHolder>(g, g, all_repeats).walk(v, straw);
|
||||
}
|
||||
|
||||
/** True if entries to this subgraph must pass through a cyclic state with
|
||||
@@ -1553,7 +1552,7 @@ bool hasCyclicSupersetEntryPath(const NGHolder &g, const ReachSubgraph &rsi,
|
||||
// until we encounter our cyclic, all of which must have superset reach.
|
||||
vector<NFAVertex> straw;
|
||||
return walkStrawToCyclicRev(g, rsi.vertices.front(), all_repeats, straw) !=
|
||||
NFAGraph::null_vertex();
|
||||
NGHolder::null_vertex();
|
||||
}
|
||||
|
||||
static
|
||||
@@ -1561,7 +1560,7 @@ bool hasCyclicSupersetExitPath(const NGHolder &g, const ReachSubgraph &rsi,
|
||||
const vector<BoundedRepeatData> &all_repeats) {
|
||||
vector<NFAVertex> straw;
|
||||
return walkStrawToCyclicFwd(g, rsi.vertices.back(), all_repeats, straw) !=
|
||||
NFAGraph::null_vertex();
|
||||
NGHolder::null_vertex();
|
||||
}
|
||||
|
||||
static
|
||||
@@ -1844,7 +1843,7 @@ void buildFeeder(NGHolder &g, const BoundedRepeatData &rd,
|
||||
add_edge(u, feeder, g);
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("added feeder %u\n", g[feeder].index);
|
||||
DEBUG_PRINTF("added feeder %zu\n", g[feeder].index);
|
||||
} else {
|
||||
// No neg trigger means feeder is empty, and unnecessary.
|
||||
assert(g[rd.pos_trigger].char_reach.all());
|
||||
@@ -1892,13 +1891,13 @@ bool improveLeadingRepeat(NGHolder &g, BoundedRepeatData &rd,
|
||||
// This transformation is only safe if the straw path from startDs that
|
||||
// we've discovered can *only* lead to this repeat, since we're going to
|
||||
// remove the self-loop on startDs.
|
||||
if (hasGreaterOutDegree(2, g.startDs, g)) {
|
||||
if (proper_out_degree(g.startDs, g) > 1) {
|
||||
DEBUG_PRINTF("startDs has other successors\n");
|
||||
return false;
|
||||
}
|
||||
for (const auto &v : straw) {
|
||||
if (proper_out_degree(v, g) != 1) {
|
||||
DEBUG_PRINTF("branch between startDs and repeat, from vertex %u\n",
|
||||
DEBUG_PRINTF("branch between startDs and repeat, from vertex %zu\n",
|
||||
g[v].index);
|
||||
return false;
|
||||
}
|
||||
@@ -2068,8 +2067,8 @@ public:
|
||||
const depth &our_depth_in)
|
||||
: top_depths(top_depths_in), our_depth(our_depth_in) {}
|
||||
|
||||
void discover_vertex(NFAVertex v, UNUSED const NFAGraph &g) {
|
||||
DEBUG_PRINTF("discovered %u (depth %s)\n", g[v].index,
|
||||
void discover_vertex(NFAVertex v, UNUSED const NGHolder &g) {
|
||||
DEBUG_PRINTF("discovered %zu (depth %s)\n", g[v].index,
|
||||
our_depth.str().c_str());
|
||||
|
||||
auto it = top_depths.find(v);
|
||||
@@ -2120,22 +2119,21 @@ void populateFixedTopInfo(const map<u32, u32> &fixed_depth_tops,
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("scanning from %u depth=%s\n", g[v].index,
|
||||
DEBUG_PRINTF("scanning from %zu depth=%s\n", g[v].index,
|
||||
td.str().c_str());
|
||||
/* for each vertex reachable from v update its map to reflect that it is
|
||||
* reachable from a top of depth td. */
|
||||
|
||||
depth_first_visit(
|
||||
g.g, v, pfti_visitor(top_depths, td),
|
||||
make_iterator_property_map(colours.begin(),
|
||||
get(&NFAGraphVertexProps::index, g.g)));
|
||||
depth_first_visit(g, v, pfti_visitor(top_depths, td),
|
||||
make_iterator_property_map(colours.begin(),
|
||||
get(vertex_index, g)));
|
||||
}
|
||||
|
||||
for (const auto &v_depth : top_depths) {
|
||||
const NFAVertex v = v_depth.first;
|
||||
const depth &d = v_depth.second;
|
||||
if (d.is_finite()) {
|
||||
DEBUG_PRINTF("%u reached by fixed tops at depth %s\n",
|
||||
DEBUG_PRINTF("%zu reached by fixed tops at depth %s\n",
|
||||
g[v].index, d.str().c_str());
|
||||
reached_by_fixed_tops->insert(v);
|
||||
}
|
||||
@@ -2152,19 +2150,16 @@ bool hasOverlappingRepeats(UNUSED const NGHolder &g,
|
||||
|
||||
for (const auto &br : repeats) {
|
||||
if (contains(involved, br.cyclic)) {
|
||||
DEBUG_PRINTF("already seen cyclic %u\n",
|
||||
g[br.cyclic].index);
|
||||
DEBUG_PRINTF("already seen cyclic %zu\n", g[br.cyclic].index);
|
||||
return true;
|
||||
}
|
||||
if (contains(involved, br.pos_trigger)) {
|
||||
DEBUG_PRINTF("already seen pos %u\n",
|
||||
g[br.pos_trigger].index);
|
||||
DEBUG_PRINTF("already seen pos %zu\n", g[br.pos_trigger].index);
|
||||
return true;
|
||||
}
|
||||
for (auto v : br.tug_triggers) {
|
||||
if (contains(involved, v)) {
|
||||
DEBUG_PRINTF("already seen tug %u\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("already seen tug %zu\n", g[v].index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2310,7 +2305,7 @@ void analyseRepeats(NGHolder &g, const ReportManager *rm,
|
||||
// Go to town on the remaining acceptable subgraphs.
|
||||
ue2::unordered_set<NFAVertex> created;
|
||||
for (auto &rsi : rs) {
|
||||
DEBUG_PRINTF("subgraph (beginning vertex %u) is a {%s,%s} repeat\n",
|
||||
DEBUG_PRINTF("subgraph (beginning vertex %zu) is a {%s,%s} repeat\n",
|
||||
g[rsi.vertices.front()].index,
|
||||
rsi.repeatMin.str().c_str(), rsi.repeatMax.str().c_str());
|
||||
|
||||
@@ -2343,7 +2338,7 @@ void analyseRepeats(NGHolder &g, const ReportManager *rm,
|
||||
|
||||
// Some of our analyses require correctly numbered vertices, so we
|
||||
// renumber after changes.
|
||||
g.renumberVertices();
|
||||
renumber_vertices(g);
|
||||
}
|
||||
|
||||
bool modified_start_ds = false;
|
||||
@@ -2384,8 +2379,8 @@ void analyseRepeats(NGHolder &g, const ReportManager *rm,
|
||||
|
||||
// We have modified the graph, so we need to ensure that our edges
|
||||
// and vertices are correctly numbered.
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
// Remove stray report IDs.
|
||||
clearReports(g);
|
||||
}
|
||||
@@ -2424,14 +2419,14 @@ bool isPureRepeat(const NGHolder &g, PureRepeat &repeat) {
|
||||
|
||||
// Must be start anchored.
|
||||
assert(edge(g.startDs, g.startDs, g).second);
|
||||
if (hasGreaterOutDegree(1, g.startDs, g)) {
|
||||
if (out_degree(g.startDs, g) > 1) {
|
||||
DEBUG_PRINTF("Unanchored\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must not be EOD-anchored.
|
||||
assert(edge(g.accept, g.acceptEod, g).second);
|
||||
if (hasGreaterInDegree(1, g.acceptEod, g)) {
|
||||
if (in_degree(g.acceptEod, g) > 1) {
|
||||
DEBUG_PRINTF("EOD anchored\n");
|
||||
return false;
|
||||
}
|
||||
|
@@ -52,11 +52,7 @@ namespace ue2 {
|
||||
static
|
||||
void wireStartToTops(NGHolder &g, const flat_set<NFAVertex> &tops,
|
||||
vector<NFAEdge> &tempEdges) {
|
||||
// Construct edges in vertex index order, for determinism.
|
||||
vector<NFAVertex> ordered_tops(begin(tops), end(tops));
|
||||
sort(begin(ordered_tops), end(ordered_tops), make_index_ordering(g));
|
||||
|
||||
for (NFAVertex v : ordered_tops) {
|
||||
for (NFAVertex v : tops) {
|
||||
assert(!isLeafNode(v, g));
|
||||
|
||||
const NFAEdge &e = add_edge(g.start, v, g).first;
|
||||
@@ -102,7 +98,7 @@ void getStateOrdering(NGHolder &g, const flat_set<NFAVertex> &tops,
|
||||
vector<NFAEdge> tempEdges;
|
||||
wireStartToTops(g, tops, tempEdges);
|
||||
|
||||
renumberGraphVertices(g);
|
||||
renumber_vertices(g);
|
||||
|
||||
vector<NFAVertex> temp = getTopoOrdering(g);
|
||||
|
||||
@@ -144,7 +140,7 @@ getStateIndices(const NGHolder &h, const vector<NFAVertex> &ordering) {
|
||||
|
||||
u32 stateNum = 0;
|
||||
for (auto v : ordering) {
|
||||
DEBUG_PRINTF("assigning state num %u to vertex %u\n", stateNum,
|
||||
DEBUG_PRINTF("assigning state num %u to vertex %zu\n", stateNum,
|
||||
h[v].index);
|
||||
states[v] = stateNum++;
|
||||
}
|
||||
@@ -187,7 +183,7 @@ void optimiseTightLoops(const NGHolder &g, vector<NFAVertex> &ordering) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("moving vertex %u next to %u\n", g[v].index, g[u].index);
|
||||
DEBUG_PRINTF("moving vertex %zu next to %zu\n", g[v].index, g[u].index);
|
||||
|
||||
ordering.erase(v_it);
|
||||
ordering.insert(++u_it, v);
|
||||
|
@@ -538,7 +538,7 @@ void getRegionRoseLiterals(const NGHolder &g,
|
||||
DEBUG_PRINTF("inspecting region %u\n", region);
|
||||
set<ue2_literal> s;
|
||||
for (auto v : vv) {
|
||||
DEBUG_PRINTF(" exit vertex: %u\n", g[v].index);
|
||||
DEBUG_PRINTF(" exit vertex: %zu\n", g[v].index);
|
||||
/* Note: RHS can not be depended on to take all subsequent revisits
|
||||
* to this vertex */
|
||||
set<ue2_literal> ss = getLiteralSet(g, v, false);
|
||||
@@ -573,8 +573,7 @@ void gatherBackEdges(const NGHolder &g,
|
||||
ue2::unordered_map<NFAVertex, vector<NFAVertex>> *out) {
|
||||
set<NFAEdge> backEdges;
|
||||
BackEdges<set<NFAEdge>> be(backEdges);
|
||||
depth_first_search(g.g, visitor(be).root_vertex(g.start).vertex_index_map(
|
||||
get(&NFAGraphVertexProps::index, g.g)));
|
||||
depth_first_search(g, visitor(be).root_vertex(g.start));
|
||||
|
||||
for (const auto &e : backEdges) {
|
||||
(*out)[source(e, g)].push_back(target(e, g));
|
||||
@@ -757,7 +756,7 @@ unique_ptr<VertLitInfo> LitCollection::pickNext() {
|
||||
unique_ptr<VertLitInfo> rv = move(lits.back());
|
||||
lits.pop_back();
|
||||
poisonCandidates(*rv);
|
||||
DEBUG_PRINTF("best is '%s' %u a%d t%d\n",
|
||||
DEBUG_PRINTF("best is '%s' %zu a%d t%d\n",
|
||||
dumpString(*(rv->lit.begin())).c_str(),
|
||||
g[rv->vv.front()].index,
|
||||
(int)createsAnchoredLHS(g, rv->vv, depths, grey),
|
||||
@@ -863,8 +862,6 @@ u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
|
||||
assert(delay <= lit.length());
|
||||
DEBUG_PRINTF("managed delay %u (of max %u)\n", delay, max_delay);
|
||||
|
||||
// For determinism, we make sure that we create these edges from vertices
|
||||
// in index-sorted order.
|
||||
set<NFAVertex> pred;
|
||||
for (auto v : curr) {
|
||||
insert(&pred, inv_adjacent_vertices_range(v, g));
|
||||
@@ -873,10 +870,7 @@ u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
|
||||
clear_in_edges(g.accept, g);
|
||||
clearReports(g);
|
||||
|
||||
vector<NFAVertex> verts(pred.begin(), pred.end());
|
||||
sort(verts.begin(), verts.end(), VertexIndexOrdering<NGHolder>(g));
|
||||
|
||||
for (auto v : verts) {
|
||||
for (auto v : pred) {
|
||||
NFAEdge e = add_edge(v, g.accept, g).first;
|
||||
g[v].reports.insert(0);
|
||||
if (is_triggered(g) && v == g.start) {
|
||||
@@ -921,8 +915,8 @@ void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
|
||||
g[u].reports.insert(0);
|
||||
}
|
||||
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
assert(allMatchStatesHaveReports(g));
|
||||
assert(isCorrectlyTopped(g));
|
||||
}
|
||||
@@ -1152,7 +1146,7 @@ void deanchorIfNeeded(NGHolder &g, bool *orig_anch) {
|
||||
succ_g.erase(g.startDs);
|
||||
|
||||
for (auto v : adjacent_vertices_range(g.start, g)) {
|
||||
DEBUG_PRINTF("inspecting cand %u || =%zu\n", g[v].index,
|
||||
DEBUG_PRINTF("inspecting cand %zu || =%zu\n", g[v].index,
|
||||
g[v].char_reach.size());
|
||||
|
||||
if (v == g.startDs || !g[v].char_reach.all()) {
|
||||
@@ -1170,7 +1164,7 @@ void deanchorIfNeeded(NGHolder &g, bool *orig_anch) {
|
||||
}
|
||||
clear_vertex(v, g);
|
||||
remove_vertex(v, g);
|
||||
g.renumberVertices();
|
||||
renumber_vertices(g);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1701,7 +1695,7 @@ void splitEdgesByCut(RoseInGraph &ig, const vector<RoseInEdge> &to_cut,
|
||||
/* TODO need to update v_mapping (if we were doing more cuts) */
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("splitting on pivot %u\n", h[pivot].index);
|
||||
DEBUG_PRINTF("splitting on pivot %zu\n", h[pivot].index);
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> temp_map;
|
||||
shared_ptr<NGHolder> new_lhs = make_shared<NGHolder>();
|
||||
splitLHS(h, pivot, new_lhs.get(), &temp_map);
|
||||
@@ -1774,8 +1768,8 @@ bool doNetflowCut(RoseInGraph &ig, const vector<RoseInEdge> &to_cut,
|
||||
return false;
|
||||
}
|
||||
|
||||
h.renumberVertices();
|
||||
h.renumberEdges();
|
||||
renumber_vertices(h);
|
||||
renumber_edges(h);
|
||||
/* Step 1: Get scores for all edges */
|
||||
vector<u64a> scores = scoreEdges(h); /* scores by edge_index */
|
||||
/* Step 2: poison scores for edges covered by successor literal */
|
||||
@@ -2573,7 +2567,7 @@ bool followedByStar(const vector<NFAVertex> &vv, const NGHolder &g) {
|
||||
|
||||
static
|
||||
bool isEodPrefixCandidate(const NGHolder &g) {
|
||||
if (hasGreaterInDegree(0, g.accept, g)) {
|
||||
if (in_degree(g.accept, g)) {
|
||||
DEBUG_PRINTF("graph isn't eod anchored\n");
|
||||
return false;
|
||||
}
|
||||
@@ -2644,7 +2638,7 @@ void processEodPrefixes(RoseInGraph &g) {
|
||||
}
|
||||
|
||||
// TODO: handle cases with multiple out-edges.
|
||||
if (hasGreaterOutDegree(1, source(e, g), g)) {
|
||||
if (out_degree(source(e, g), g) > 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2671,7 +2665,7 @@ void processEodPrefixes(RoseInGraph &g) {
|
||||
}
|
||||
|
||||
for (auto v : accepts) {
|
||||
if (!hasGreaterInDegree(0, v, g)) {
|
||||
if (!in_degree(v, g)) {
|
||||
remove_vertex(v, g);
|
||||
}
|
||||
}
|
||||
@@ -2813,6 +2807,7 @@ unique_ptr<RoseInGraph> buildRose(const NGHolder &h, bool desperation,
|
||||
|
||||
dumpPreRoseGraph(ig, cc.grey);
|
||||
|
||||
renumber_vertices(ig);
|
||||
calcVertexOffsets(ig);
|
||||
return igp;
|
||||
}
|
||||
@@ -2829,6 +2824,7 @@ void desperationImprove(RoseInGraph &ig, const CompileContext &cc) {
|
||||
handleLongMixedSensitivityLiterals(ig);
|
||||
dedupe(ig);
|
||||
pruneUseless(ig);
|
||||
renumber_vertices(ig);
|
||||
calcVertexOffsets(ig);
|
||||
}
|
||||
|
||||
@@ -2839,8 +2835,7 @@ bool splitOffRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
}
|
||||
|
||||
// We should have at least one edge into accept or acceptEod!
|
||||
assert(hasGreaterInDegree(0, h.accept, h) ||
|
||||
hasGreaterInDegree(1, h.acceptEod, h));
|
||||
assert(in_degree(h.accept, h) || in_degree(h.acceptEod, h) > 1);
|
||||
|
||||
unique_ptr<RoseInGraph> igp = buildRose(h, false, cc);
|
||||
if (igp && rose.addRose(*igp, prefilter)) {
|
||||
@@ -2932,6 +2927,7 @@ bool finalChanceRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
add_edge(v, a, RoseInEdgeProps(rhs, 0U), ig);
|
||||
}
|
||||
|
||||
renumber_vertices(ig);
|
||||
calcVertexOffsets(ig);
|
||||
|
||||
return rose.addRose(ig, prefilter, true /* final chance */);
|
||||
@@ -2944,8 +2940,7 @@ bool checkRose(const ReportManager &rm, const NGHolder &h, bool prefilter,
|
||||
}
|
||||
|
||||
// We should have at least one edge into accept or acceptEod!
|
||||
assert(hasGreaterInDegree(0, h.accept, h) ||
|
||||
hasGreaterInDegree(1, h.acceptEod, h));
|
||||
assert(in_degree(h.accept, h) || in_degree(h.acceptEod, h) > 1);
|
||||
|
||||
unique_ptr<RoseInGraph> igp;
|
||||
|
||||
|
@@ -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:
|
||||
@@ -125,7 +125,7 @@ bool findLiterals(const NGHolder &g,
|
||||
set<sls_literal> &out = built[g[v].index];
|
||||
read_count[g[v].index] = out_degree(v, g);
|
||||
|
||||
DEBUG_PRINTF("setting read_count to %zu for %u\n",
|
||||
DEBUG_PRINTF("setting read_count to %zu for %zu\n",
|
||||
read_count[g[v].index], g[v].index);
|
||||
|
||||
assert(out.empty());
|
||||
@@ -154,7 +154,7 @@ bool findLiterals(const NGHolder &g,
|
||||
}
|
||||
|
||||
set<sls_literal> &in = built[g[u].index];
|
||||
DEBUG_PRINTF("getting from %u (%zu reads to go)\n",
|
||||
DEBUG_PRINTF("getting from %zu (%zu reads to go)\n",
|
||||
g[u].index, read_count[g[u].index]);
|
||||
assert(!in.empty());
|
||||
assert(read_count[g[u].index]);
|
||||
@@ -188,7 +188,7 @@ bool findLiterals(const NGHolder &g,
|
||||
|
||||
read_count[g[u].index]--;
|
||||
if (!read_count[g[u].index]) {
|
||||
DEBUG_PRINTF("clearing %u as finished reading\n", g[u].index);
|
||||
DEBUG_PRINTF("clearing %zu as finished reading\n", g[u].index);
|
||||
in.clear();
|
||||
}
|
||||
}
|
||||
|
@@ -110,7 +110,7 @@ bool regionCanEstablishSom(const NGHolder &g,
|
||||
|
||||
DEBUG_PRINTF("region %u\n", region);
|
||||
for (UNUSED auto v : r_exits) {
|
||||
DEBUG_PRINTF(" exit %u\n", g[v].index);
|
||||
DEBUG_PRINTF(" exit %zu\n", g[v].index);
|
||||
}
|
||||
|
||||
/* simple if each region exit is at fixed distance from SOM. Note SOM does
|
||||
@@ -119,12 +119,12 @@ bool regionCanEstablishSom(const NGHolder &g,
|
||||
assert(regions.at(v) == region);
|
||||
const DepthMinMax &d = depths.at(g[v].index);
|
||||
if (d.min != d.max) {
|
||||
DEBUG_PRINTF("failing %u as %s != %s\n", g[v].index,
|
||||
DEBUG_PRINTF("failing %zu as %s != %s\n", g[v].index,
|
||||
d.min.str().c_str(), d.max.str().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF("region %u/%u is good\n", regions.at(r_exits[0]),
|
||||
DEBUG_PRINTF("region %u/%zu is good\n", regions.at(r_exits[0]),
|
||||
g[r_exits[0]].index);
|
||||
|
||||
return true;
|
||||
@@ -178,10 +178,7 @@ void buildRegionMapping(const NGHolder &g,
|
||||
|
||||
set<NFAEdge> be;
|
||||
BackEdges<set<NFAEdge> > backEdgeVisitor(be);
|
||||
depth_first_search(
|
||||
g.g, visitor(backEdgeVisitor)
|
||||
.root_vertex(g.start)
|
||||
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
|
||||
boost::depth_first_search(g, visitor(backEdgeVisitor).root_vertex(g.start));
|
||||
|
||||
for (const auto &e : be) {
|
||||
NFAVertex u = source(e, g);
|
||||
@@ -208,17 +205,17 @@ void buildRegionMapping(const NGHolder &g,
|
||||
r_i.optional ? " (optional)" : "");
|
||||
DEBUG_PRINTF(" enters:");
|
||||
for (u32 i = 0; i < r_i.enters.size(); i++) {
|
||||
printf(" %u", g[r_i.enters[i]].index);
|
||||
printf(" %zu", g[r_i.enters[i]].index);
|
||||
}
|
||||
printf("\n");
|
||||
DEBUG_PRINTF(" exits:");
|
||||
for (u32 i = 0; i < r_i.exits.size(); i++) {
|
||||
printf(" %u", g[r_i.exits[i]].index);
|
||||
printf(" %zu", g[r_i.exits[i]].index);
|
||||
}
|
||||
printf("\n");
|
||||
DEBUG_PRINTF(" all:");
|
||||
for (u32 i = 0; i < r_i.full.size(); i++) {
|
||||
printf(" %u", g[r_i.full[i]].index);
|
||||
printf(" %zu", g[r_i.full[i]].index);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -235,8 +232,7 @@ bool validateXSL(const NGHolder &g,
|
||||
u32 v_region = regions.at(v);
|
||||
if (!is_special(v, g) && v_region > region &&
|
||||
(escapes & g[v].char_reach).any()) {
|
||||
DEBUG_PRINTF("problem with escapes for %u\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("problem with escapes for %zu\n", g[v].index);
|
||||
first_bad_region = MIN(first_bad_region, v_region);
|
||||
}
|
||||
}
|
||||
@@ -402,7 +398,7 @@ makePrefix(const NGHolder &g, const ue2::unordered_map<NFAVertex, u32> ®ions,
|
||||
vector<NFAVertex> to_clear;
|
||||
assert(contains(lhs_map, curr_exits.front()));
|
||||
NFAVertex p_u = lhs_map[curr_exits.front()];
|
||||
DEBUG_PRINTF("p_u: %u\n", prefix[p_u].index);
|
||||
DEBUG_PRINTF("p_u: %zu\n", prefix[p_u].index);
|
||||
for (auto p_v : adjacent_vertices_range(p_u, prefix)) {
|
||||
auto v = rev_map.at(p_v);
|
||||
if (p_v == prefix.accept || regions.at(v) < dead_region) {
|
||||
@@ -412,7 +408,7 @@ makePrefix(const NGHolder &g, const ue2::unordered_map<NFAVertex, u32> ®ions,
|
||||
}
|
||||
|
||||
for (auto v : to_clear) {
|
||||
DEBUG_PRINTF("clearing in_edges on %u\n", prefix[v].index);
|
||||
DEBUG_PRINTF("clearing in_edges on %zu\n", prefix[v].index);
|
||||
clear_in_edges(v, prefix);
|
||||
}
|
||||
|
||||
@@ -575,7 +571,7 @@ void replaceExternalReportsWithSomRep(ReportManager &rm, NGHolder &g,
|
||||
ir.somDistance = param;
|
||||
ReportID rep = rm.getInternalId(ir);
|
||||
|
||||
DEBUG_PRINTF("vertex %u, replacing report %u with %u (type %u)\n",
|
||||
DEBUG_PRINTF("vertex %zu, replacing report %u with %u (type %u)\n",
|
||||
g[v].index, report_id, rep, ir_type);
|
||||
r_new.insert(rep);
|
||||
}
|
||||
@@ -713,7 +709,7 @@ void fillHolderForLockCheck(NGHolder *out, const NGHolder &g,
|
||||
|
||||
/* add all vertices in region, create mapping */
|
||||
for (auto v : jt->second.full) {
|
||||
DEBUG_PRINTF("adding v %u to midfix\n", g[v].index);
|
||||
DEBUG_PRINTF("adding v %zu to midfix\n", g[v].index);
|
||||
if (contains(v_map, v)) {
|
||||
continue;
|
||||
}
|
||||
@@ -758,7 +754,7 @@ void fillHolderForLockCheck(NGHolder *out, const NGHolder &g,
|
||||
}
|
||||
|
||||
assert(in_degree(midfix.accept, midfix));
|
||||
midfix.renumberVertices();
|
||||
renumber_vertices(midfix);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -785,7 +781,7 @@ void fillRoughMidfix(NGHolder *out, const NGHolder &g,
|
||||
|
||||
/* add all vertices in region, create mapping */
|
||||
for (auto v : jt->second.full) {
|
||||
DEBUG_PRINTF("adding v %u to midfix\n", g[v].index);
|
||||
DEBUG_PRINTF("adding v %zu to midfix\n", g[v].index);
|
||||
NFAVertex vnew = add_vertex(g[v], midfix);
|
||||
v_map[v] = vnew;
|
||||
}
|
||||
@@ -825,7 +821,7 @@ void fillRoughMidfix(NGHolder *out, const NGHolder &g,
|
||||
|
||||
do {
|
||||
for (auto v : jt->second.exits) {
|
||||
DEBUG_PRINTF("adding v %u to midfix\n", g[v].index);
|
||||
DEBUG_PRINTF("adding v %zu to midfix\n", g[v].index);
|
||||
NFAVertex vnew = add_vertex(g[v], midfix);
|
||||
v_map[v] = vnew;
|
||||
|
||||
@@ -1012,8 +1008,7 @@ bool addPlan(vector<som_plan> &plan, u32 parent) {
|
||||
// Fetches all preds of {accept, acceptEod} for this graph.
|
||||
static
|
||||
void addReporterVertices(const NGHolder &g, vector<NFAVertex> &reporters) {
|
||||
// Order reporter vertices by index for determinism.
|
||||
set<NFAVertex, VertexIndexOrdering<NGHolder> > tmp(g);
|
||||
set<NFAVertex> tmp;
|
||||
insert(&tmp, inv_adjacent_vertices(g.accept, g));
|
||||
insert(&tmp, inv_adjacent_vertices(g.acceptEod, g));
|
||||
tmp.erase(g.accept);
|
||||
@@ -1021,7 +1016,7 @@ void addReporterVertices(const NGHolder &g, vector<NFAVertex> &reporters) {
|
||||
#ifdef DEBUG
|
||||
DEBUG_PRINTF("add reporters:");
|
||||
for (UNUSED auto v : tmp) {
|
||||
printf(" %u", g[v].index);
|
||||
printf(" %zu", g[v].index);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
@@ -1035,7 +1030,7 @@ void addReporterVertices(const region_info &r, const NGHolder &g,
|
||||
vector<NFAVertex> &reporters) {
|
||||
for (auto v : r.exits) {
|
||||
if (edge(v, g.accept, g).second || edge(v, g.acceptEod, g).second) {
|
||||
DEBUG_PRINTF("add reporter %u\n", g[v].index);
|
||||
DEBUG_PRINTF("add reporter %zu\n", g[v].index);
|
||||
reporters.push_back(v);
|
||||
}
|
||||
}
|
||||
@@ -1048,7 +1043,7 @@ void addMappedReporterVertices(const region_info &r, const NGHolder &g,
|
||||
vector<NFAVertex> &reporters) {
|
||||
for (auto v : r.exits) {
|
||||
if (edge(v, g.accept, g).second || edge(v, g.acceptEod, g).second) {
|
||||
DEBUG_PRINTF("adding v=%u\n", g[v].index);
|
||||
DEBUG_PRINTF("adding v=%zu\n", g[v].index);
|
||||
ue2::unordered_map<NFAVertex, NFAVertex>::const_iterator it =
|
||||
mapping.find(v);
|
||||
assert(it != mapping.end());
|
||||
@@ -1105,7 +1100,7 @@ void expandGraph(NGHolder &g, ue2::unordered_map<NFAVertex, u32> ®ions,
|
||||
}
|
||||
|
||||
for (auto enter : enters) {
|
||||
DEBUG_PRINTF("processing enter %u\n", g[enter].index);
|
||||
DEBUG_PRINTF("processing enter %zu\n", g[enter].index);
|
||||
map<NFAVertex, NFAVertex> orig_to_copy;
|
||||
|
||||
// Make a copy of all of the tail vertices, storing region info along
|
||||
@@ -1155,7 +1150,7 @@ void expandGraph(NGHolder &g, ue2::unordered_map<NFAVertex, u32> ®ions,
|
||||
[&](const NFAEdge &e) {
|
||||
NFAVertex u = source(e, g);
|
||||
return regions.at(u) < split_region;
|
||||
}, g.g);
|
||||
}, g);
|
||||
}
|
||||
|
||||
new_enters.push_back(orig_to_copy[enter]);
|
||||
@@ -1327,7 +1322,7 @@ bool doTreePlanning(NGHolder &g,
|
||||
dumpHolder(g, g_regions, 14, "som_expandedtree", grey);
|
||||
|
||||
for (auto v : enters) {
|
||||
DEBUG_PRINTF("enter %u\n", g[v].index);
|
||||
DEBUG_PRINTF("enter %zu\n", g[v].index);
|
||||
|
||||
// For this entry vertex, construct a version of the graph without the
|
||||
// other entries in this region (g_path), and calculate its depths and
|
||||
@@ -1562,12 +1557,12 @@ void dumpSomPlan(UNUSED const NGHolder &g, UNUSED const som_plan &p,
|
||||
p.is_reset, p.parent);
|
||||
printf(" reporters:");
|
||||
for (auto v : p.reporters) {
|
||||
printf(" %u", g[v].index);
|
||||
printf(" %zu", g[v].index);
|
||||
}
|
||||
printf("\n");
|
||||
printf(" reporters_in:");
|
||||
for (auto v : p.reporters_in) {
|
||||
printf(" %u", g[v].index);
|
||||
printf(" %zu", g[v].index);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
@@ -1633,7 +1628,7 @@ void implementSomPlan(NG &ng, const NGWrapper &w, u32 comp_id, NGHolder &g,
|
||||
|
||||
/* create prefix to set the som_loc */
|
||||
if (!plan.front().no_implement) {
|
||||
plan.front().prefix->renumberVertices();
|
||||
renumber_vertices(*plan.front().prefix);
|
||||
assert(plan.front().prefix->kind == NFA_OUTFIX);
|
||||
if (!ng.addHolder(*plan.front().prefix)) {
|
||||
throw CompileError(w.expressionIndex, "Pattern is too large.");
|
||||
@@ -1745,7 +1740,7 @@ aligned_unique_ptr<NFA> makeBareSomRevNfa(const NGHolder &g,
|
||||
setZeroReports(g_rev);
|
||||
|
||||
// Prep for actual construction.
|
||||
g_rev.renumberVertices();
|
||||
renumber_vertices(g_rev);
|
||||
g_rev.kind = NFA_REV_PREFIX;
|
||||
reduceGraphEquivalences(g_rev, cc);
|
||||
removeRedundancy(g_rev, SOM_NONE);
|
||||
@@ -1785,7 +1780,7 @@ bool makeSomRevNfa(vector<SomRevNfa> &som_nfas, const NGHolder &g,
|
||||
return true;
|
||||
}
|
||||
|
||||
g2.renumberVertices(); // for findMinWidth, findMaxWidth.
|
||||
renumber_vertices(g2); // for findMinWidth, findMaxWidth.
|
||||
|
||||
aligned_unique_ptr<NFA> nfa = makeBareSomRevNfa(g2, cc);
|
||||
if (!nfa) {
|
||||
@@ -2220,7 +2215,7 @@ bool leadingLiterals(const NGHolder &g, set<ue2_literal> *lits,
|
||||
for (const auto &m : curr) {
|
||||
const NFAVertex u = m.first;
|
||||
const vector<ue2_literal> &base = m.second;
|
||||
DEBUG_PRINTF("expanding from %u\n", g[u].index);
|
||||
DEBUG_PRINTF("expanding from %zu\n", g[u].index);
|
||||
for (auto v : adjacent_vertices_range(u, g)) {
|
||||
if (v == g.startDs) {
|
||||
continue;
|
||||
@@ -2233,8 +2228,7 @@ bool leadingLiterals(const NGHolder &g, set<ue2_literal> *lits,
|
||||
DEBUG_PRINTF("match\n");
|
||||
goto skip_to_next_terminal;
|
||||
}
|
||||
if (g[v].char_reach.count()
|
||||
> 2 * MAX_LEADING_LITERALS) {
|
||||
if (g[v].char_reach.count() > 2 * MAX_LEADING_LITERALS) {
|
||||
DEBUG_PRINTF("wide\n");
|
||||
goto skip_to_next_terminal;
|
||||
}
|
||||
@@ -2250,8 +2244,8 @@ bool leadingLiterals(const NGHolder &g, set<ue2_literal> *lits,
|
||||
CharReach cr = g[v].char_reach;
|
||||
vector<ue2_literal> &out = next[v];
|
||||
|
||||
DEBUG_PRINTF("expanding to %u (|| = %zu)\n",
|
||||
g[v].index, cr.count());
|
||||
DEBUG_PRINTF("expanding to %zu (|| = %zu)\n", g[v].index,
|
||||
cr.count());
|
||||
for (size_t c = cr.find_first(); c != CharReach::npos;
|
||||
c = cr.find_next(c)) {
|
||||
bool nocase = ourisalpha(c) && cr.test(mytoupper(c))
|
||||
@@ -2327,7 +2321,7 @@ bool splitOffLeadingLiterals(const NGHolder &g, set<ue2_literal> *lit_out,
|
||||
set<NFAVertex> adj_term1;
|
||||
insert(&adj_term1, adjacent_vertices(*terms.begin(), g));
|
||||
for (auto v : terms) {
|
||||
DEBUG_PRINTF("term %u\n", g[v].index);
|
||||
DEBUG_PRINTF("term %zu\n", g[v].index);
|
||||
set<NFAVertex> temp;
|
||||
insert(&temp, adjacent_vertices(v, g));
|
||||
if (temp != adj_term1) {
|
||||
@@ -2354,7 +2348,7 @@ void findBestLiteral(const NGHolder &g,
|
||||
buildRegionMapping(g, regions, info, false);
|
||||
|
||||
ue2_literal best;
|
||||
NFAVertex best_v = nullptr;
|
||||
NFAVertex best_v = NGHolder::null_vertex();
|
||||
|
||||
map<u32, region_info>::const_iterator lit = info.begin();
|
||||
while (1) {
|
||||
@@ -2390,7 +2384,7 @@ bool splitOffBestLiteral(const NGHolder &g,
|
||||
const ue2::unordered_map<NFAVertex, u32> ®ions,
|
||||
ue2_literal *lit_out, NGHolder *lhs, NGHolder *rhs,
|
||||
const CompileContext &cc) {
|
||||
NFAVertex v = nullptr;
|
||||
NFAVertex v = NGHolder::null_vertex();
|
||||
|
||||
findBestLiteral(g, regions, lit_out, &v, cc);
|
||||
if (lit_out->empty()) {
|
||||
@@ -2404,7 +2398,7 @@ bool splitOffBestLiteral(const NGHolder &g,
|
||||
|
||||
splitGraph(g, v, lhs, &lhs_map, rhs, &rhs_map);
|
||||
|
||||
DEBUG_PRINTF("v = %u\n", g[v].index);
|
||||
DEBUG_PRINTF("v = %zu\n", g[v].index);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2624,7 +2618,7 @@ bool doHaigLitHaigSom(NG &ng, NGHolder &g,
|
||||
}
|
||||
} else {
|
||||
DEBUG_PRINTF("has start->accept edge\n");
|
||||
if (hasGreaterInDegree(1, g.acceptEod, g)) {
|
||||
if (in_degree(g.acceptEod, g) > 1) {
|
||||
DEBUG_PRINTF("also has a path to EOD\n");
|
||||
return false;
|
||||
}
|
||||
@@ -2825,7 +2819,7 @@ map<u32, region_info>::const_iterator tryForLaterRevNfaCut(const NGHolder &g,
|
||||
reverseHolder(*prefix, g_rev);
|
||||
anchorStarts(g_rev);
|
||||
|
||||
g_rev.renumberVertices();
|
||||
renumber_vertices(g_rev);
|
||||
g_rev.kind = NFA_REV_PREFIX;
|
||||
reduceGraphEquivalences(g_rev, cc);
|
||||
removeRedundancy(g_rev, SOM_NONE);
|
||||
@@ -2869,7 +2863,7 @@ unique_ptr<NGHolder> makePrefixForChain(NGHolder &g,
|
||||
}
|
||||
|
||||
depths->clear(); /* renumbering invalidates depths */
|
||||
prefix->renumberVertices();
|
||||
renumber_vertices(*prefix);
|
||||
|
||||
DEBUG_PRINTF("done\n");
|
||||
return prefix;
|
||||
@@ -2885,8 +2879,7 @@ sombe_rv doSom(NG &ng, NGHolder &g, const NGWrapper &w, u32 comp_id,
|
||||
|
||||
// Special case: if g is completely anchored or begins with a dot-star, we
|
||||
// know that we have an absolute SOM of zero all the time.
|
||||
assert(edge(g.startDs, g.startDs, g).second);
|
||||
if (!hasGreaterOutDegree(1, g.startDs, g) || beginsWithDotStar(g)) {
|
||||
if (!proper_out_degree(g.startDs, g) || beginsWithDotStar(g)) {
|
||||
makeSomAbsReports(rm, g, g.accept);
|
||||
makeSomAbsReports(rm, g, g.acceptEod);
|
||||
return SOMBE_HANDLED_INTERNAL;
|
||||
@@ -3003,7 +2996,7 @@ sombe_rv doSom(NG &ng, NGHolder &g, const NGWrapper &w, u32 comp_id,
|
||||
u32 rev_comp_id = doSomRevNfaPrefix(ng, w, *prefix, cc);
|
||||
updatePrefixReportsRevNFA(rm, *prefix, rev_comp_id);
|
||||
}
|
||||
prefix->renumberVertices();
|
||||
renumber_vertices(*prefix);
|
||||
if (!ng.addHolder(*prefix)) {
|
||||
DEBUG_PRINTF("failed to add holder\n");
|
||||
clear_graph(g);
|
||||
|
@@ -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:
|
||||
@@ -155,13 +155,13 @@ bool addSomRedundancy(NGHolder &g, vector<DepthMinMax> &depths) {
|
||||
if (is_special(v, g)) {
|
||||
continue;
|
||||
}
|
||||
if (!hasGreaterInDegree(0, v, g)) {
|
||||
if (!in_degree(v, g)) {
|
||||
continue; // unreachable, probably killed
|
||||
}
|
||||
|
||||
const DepthMinMax &d = getDepth(v, g, depths);
|
||||
|
||||
DEBUG_PRINTF("vertex %u has depths %s\n", g[v].index,
|
||||
DEBUG_PRINTF("vertex %zu has depths %s\n", g[v].index,
|
||||
d.str().c_str());
|
||||
|
||||
if (d.min == d.max) {
|
||||
|
@@ -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:
|
||||
@@ -76,7 +76,7 @@ vector<DepthMinMax> getDistancesFromSOM(const NGHolder &g_orig) {
|
||||
clear_in_edges(v, g);
|
||||
}
|
||||
|
||||
//dumpGraph("som_depth.dot", g.g);
|
||||
//dumpGraph("som_depth.dot", g);
|
||||
|
||||
vector<DepthMinMax> temp_depths; // numbered by vertex index in g
|
||||
calcDepthsFrom(g, g.start, temp_depths);
|
||||
@@ -143,7 +143,7 @@ bool firstMatchIsFirst(const NGHolder &p) {
|
||||
for (auto v : vertices_range(p)) {
|
||||
assert(!is_virtual_start(v, p));
|
||||
if (!is_special(v, p)) {
|
||||
DEBUG_PRINTF("turning on %u\n", p[v].index);
|
||||
DEBUG_PRINTF("turning on %zu\n", p[v].index);
|
||||
states.insert(v);
|
||||
}
|
||||
}
|
||||
@@ -154,9 +154,9 @@ bool firstMatchIsFirst(const NGHolder &p) {
|
||||
for (auto v : states) {
|
||||
/* need to check if this vertex may represent an infix match - ie
|
||||
* it does not have an edge to accept. */
|
||||
DEBUG_PRINTF("check %u\n", p[v].index);
|
||||
DEBUG_PRINTF("check %zu\n", p[v].index);
|
||||
if (!edge(v, p.accept, p).second) {
|
||||
DEBUG_PRINTF("fail %u\n", p[v].index);
|
||||
DEBUG_PRINTF("fail %zu\n", p[v].index);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -186,14 +186,11 @@ bool somMayGoBackwards(NFAVertex u, const NGHolder &g,
|
||||
return cache.smgb[u];
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("checking if som can go backwards on %u\n", g[u].index);
|
||||
DEBUG_PRINTF("checking if som can go backwards on %zu\n", g[u].index);
|
||||
|
||||
set<NFAEdge> be;
|
||||
BackEdges<set<NFAEdge>> backEdgeVisitor(be);
|
||||
depth_first_search(
|
||||
g.g, visitor(backEdgeVisitor)
|
||||
.root_vertex(g.start)
|
||||
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
|
||||
boost::depth_first_search(g, visitor(backEdgeVisitor).root_vertex(g.start));
|
||||
|
||||
bool rv;
|
||||
if (0) {
|
||||
@@ -210,8 +207,7 @@ bool somMayGoBackwards(NFAVertex u, const NGHolder &g,
|
||||
NFAVertex s = source(e, g);
|
||||
NFAVertex t = target(e, g);
|
||||
/* only need to worry about big cycles including/before u */
|
||||
DEBUG_PRINTF("back edge %u %u\n", g[s].index,
|
||||
g[t].index);
|
||||
DEBUG_PRINTF("back edge %zu %zu\n", g[s].index, g[t].index);
|
||||
if (s != t && region_map.at(s) <= u_region) {
|
||||
DEBUG_PRINTF("eek big cycle\n");
|
||||
rv = true; /* big cycle -> eek */
|
||||
@@ -268,13 +264,13 @@ bool somMayGoBackwards(NFAVertex u, const NGHolder &g,
|
||||
pruneUseless(c_g);
|
||||
|
||||
be.clear();
|
||||
depth_first_search(c_g.g, visitor(backEdgeVisitor).root_vertex(c_g.start).
|
||||
vertex_index_map(get(&NFAGraphVertexProps::index, c_g.g)));
|
||||
boost::depth_first_search(c_g, visitor(backEdgeVisitor)
|
||||
.root_vertex(c_g.start));
|
||||
|
||||
for (const auto &e : be) {
|
||||
NFAVertex s = source(e, c_g);
|
||||
NFAVertex t = target(e, c_g);
|
||||
DEBUG_PRINTF("back edge %u %u\n", c_g[s].index, c_g[t].index);
|
||||
DEBUG_PRINTF("back edge %zu %zu\n", c_g[s].index, c_g[t].index);
|
||||
if (s != t) {
|
||||
assert(0);
|
||||
DEBUG_PRINTF("eek big cycle\n");
|
||||
@@ -326,7 +322,7 @@ bool sentClearsTail(const NGHolder &g,
|
||||
}
|
||||
|
||||
for (UNUSED auto v : states) {
|
||||
DEBUG_PRINTF("start state: %u\n", g[v].index);
|
||||
DEBUG_PRINTF("start state: %zu\n", g[v].index);
|
||||
}
|
||||
|
||||
/* run the prefix the main graph */
|
||||
@@ -338,7 +334,7 @@ bool sentClearsTail(const NGHolder &g,
|
||||
continue; /* not in tail */
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("v %u is still on\n", g[v].index);
|
||||
DEBUG_PRINTF("v %zu is still on\n", g[v].index);
|
||||
assert(v != g.accept && v != g.acceptEod); /* no cr */
|
||||
|
||||
assert(contains(region_map, v));
|
||||
|
@@ -87,7 +87,7 @@ void splitLHS(const NGHolder &base, const vector<NFAVertex> &pivots,
|
||||
clearAccepts(*lhs);
|
||||
|
||||
for (auto pivot : pivots) {
|
||||
DEBUG_PRINTF("pivot is %u lv %zu lm %zu\n", base[pivot].index,
|
||||
DEBUG_PRINTF("pivot is %zu lv %zu lm %zu\n", base[pivot].index,
|
||||
num_vertices(*lhs), lhs_map->size());
|
||||
assert(contains(*lhs_map, pivot));
|
||||
|
||||
@@ -191,8 +191,8 @@ void findCommonSuccessors(const NGHolder &g, const vector<NFAVertex> &pivots,
|
||||
vector<NFAVertex> &succ) {
|
||||
assert(!pivots.empty());
|
||||
|
||||
// Note: for determinism, we must sort our successor sets by vertex_index.
|
||||
set<NFAVertex, VertexIndexOrdering<NGHolder> > adj(g), adj_temp(g);
|
||||
set<NFAVertex> adj;
|
||||
set<NFAVertex> adj_temp;
|
||||
|
||||
insert(&adj, adjacent_vertices(pivots.at(0), g));
|
||||
|
||||
|
@@ -134,8 +134,7 @@ void buildPDomTree(const NGHolder &g, PostDomTree &tree) {
|
||||
}
|
||||
NFAVertex pdom = postdominators[v];
|
||||
if (pdom) {
|
||||
DEBUG_PRINTF("vertex %u -> %u\n", g[pdom].index,
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu -> %zu\n", g[pdom].index, g[v].index);
|
||||
tree[pdom].insert(v);
|
||||
}
|
||||
}
|
||||
@@ -153,8 +152,7 @@ void buildSquashMask(NFAStateSet &mask, const NGHolder &g, NFAVertex v,
|
||||
som_type som, const vector<DepthMinMax> &som_depths,
|
||||
const ue2::unordered_map<NFAVertex, u32> ®ion_map,
|
||||
smgb_cache &cache) {
|
||||
DEBUG_PRINTF("build base squash mask for vertex %u)\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("build base squash mask for vertex %zu)\n", g[v].index);
|
||||
|
||||
vector<NFAVertex> q;
|
||||
|
||||
@@ -301,7 +299,7 @@ void findDerivedSquashers(const NGHolder &g, const vector<NFAVertex> &vByIndex,
|
||||
}
|
||||
|
||||
NFAStateSet u_squash(init.size());
|
||||
u32 u_index = g[u].index;
|
||||
size_t u_index = g[u].index;
|
||||
|
||||
buildSquashMask(u_squash, g, u, g[u].char_reach, init, vByIndex,
|
||||
pdom_tree, som, som_depths, region_map, cache);
|
||||
@@ -309,7 +307,7 @@ void findDerivedSquashers(const NGHolder &g, const vector<NFAVertex> &vByIndex,
|
||||
u_squash.set(u_index); /* never clear ourselves */
|
||||
|
||||
if ((~u_squash).any()) { // i.e. some bits unset in mask
|
||||
DEBUG_PRINTF("%u is an upstream squasher of %u\n", u_index,
|
||||
DEBUG_PRINTF("%zu is an upstream squasher of %zu\n", u_index,
|
||||
g[v].index);
|
||||
(*squash)[u] = u_squash;
|
||||
remaining.push_back(u);
|
||||
@@ -521,8 +519,7 @@ void filterSquashers(const NGHolder &g,
|
||||
if (!contains(squash, v)) {
|
||||
continue;
|
||||
}
|
||||
DEBUG_PRINTF("looking at squash set for vertex %u\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("looking at squash set for vertex %zu\n", g[v].index);
|
||||
|
||||
if (!hasSelfLoop(v, g)) {
|
||||
DEBUG_PRINTF("acyclic\n");
|
||||
@@ -600,7 +597,7 @@ void removeEdgesToAccept(NGHolder &g, NFAVertex v) {
|
||||
NFAVertex u = source(e, g);
|
||||
const auto &r = g[u].reports;
|
||||
if (!r.empty() && is_subset_of(r, reports)) {
|
||||
DEBUG_PRINTF("vertex %u\n", g[u].index);
|
||||
DEBUG_PRINTF("vertex %zu\n", g[u].index);
|
||||
dead.insert(e);
|
||||
}
|
||||
}
|
||||
@@ -609,7 +606,7 @@ void removeEdgesToAccept(NGHolder &g, NFAVertex v) {
|
||||
NFAVertex u = source(e, g);
|
||||
const auto &r = g[u].reports;
|
||||
if (!r.empty() && is_subset_of(r, reports)) {
|
||||
DEBUG_PRINTF("vertex %u\n", g[u].index);
|
||||
DEBUG_PRINTF("vertex %zu\n", g[u].index);
|
||||
dead.insert(e);
|
||||
}
|
||||
}
|
||||
@@ -620,7 +617,7 @@ void removeEdgesToAccept(NGHolder &g, NFAVertex v) {
|
||||
|
||||
static
|
||||
vector<NFAVertex> findUnreachable(const NGHolder &g) {
|
||||
const boost::reverse_graph<NFAGraph, const NFAGraph &> revg(g.g);
|
||||
const boost::reverse_graph<NGHolder, const NGHolder &> revg(g);
|
||||
|
||||
ue2::unordered_map<NFAVertex, boost::default_color_type> colours;
|
||||
colours.reserve(num_vertices(g));
|
||||
@@ -633,7 +630,7 @@ vector<NFAVertex> findUnreachable(const NGHolder &g) {
|
||||
vector<NFAVertex> unreach;
|
||||
for (auto v : vertices_range(revg)) {
|
||||
if (!contains(colours, v)) {
|
||||
unreach.push_back(v);
|
||||
unreach.push_back(NFAVertex(v));
|
||||
}
|
||||
}
|
||||
return unreach;
|
||||
@@ -656,7 +653,7 @@ findHighlanderSquashers(const NGHolder &g, const ReportManager &rm) {
|
||||
const u32 numStates = num_vertices(g);
|
||||
|
||||
for (auto v : verts) {
|
||||
DEBUG_PRINTF("vertex %u with %zu reports\n", g[v].index,
|
||||
DEBUG_PRINTF("vertex %zu with %zu reports\n", g[v].index,
|
||||
g[v].reports.size());
|
||||
|
||||
// Find the set of vertices that lead to v or any other reporter with a
|
||||
@@ -683,7 +680,7 @@ findHighlanderSquashers(const NGHolder &g, const ReportManager &rm) {
|
||||
NFAStateSet &mask = squash[v];
|
||||
|
||||
for (auto uv : unreach) {
|
||||
DEBUG_PRINTF("squashes index %u\n", h[uv].index);
|
||||
DEBUG_PRINTF("squashes index %zu\n", h[uv].index);
|
||||
mask.reset(h[uv].index);
|
||||
}
|
||||
}
|
||||
|
@@ -259,7 +259,7 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
|
||||
vmap[vic.startDs] = dest.startDs;
|
||||
vmap[vic.accept] = dest.accept;
|
||||
vmap[vic.acceptEod] = dest.acceptEod;
|
||||
vmap[nullptr] = nullptr;
|
||||
vmap[NGHolder::null_vertex()] = NGHolder::null_vertex();
|
||||
|
||||
// For vertices in the common len, add to vmap and merge in the reports, if
|
||||
// any.
|
||||
@@ -312,7 +312,7 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
|
||||
in_common_region = true;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("adding idx=%u (state %u) -> idx=%u (state %u)%s\n",
|
||||
DEBUG_PRINTF("adding idx=%zu (state %u) -> idx=%zu (state %u)%s\n",
|
||||
dest[u].index, dest_info.get(u),
|
||||
dest[v].index, dest_info.get(v),
|
||||
in_common_region ? " [common]" : "");
|
||||
@@ -338,8 +338,8 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
|
||||
add_edge(u, v, vic[e], dest);
|
||||
}
|
||||
|
||||
dest.renumberEdges();
|
||||
dest.renumberVertices();
|
||||
renumber_edges(dest);
|
||||
renumber_vertices(dest);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@@ -36,14 +36,13 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "nfagraph/ng_graph.h"
|
||||
#include "nfagraph/ng_holder.h"
|
||||
#include "util/ue2_containers.h"
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
struct CompileContext;
|
||||
struct Grey;
|
||||
class NGHolder;
|
||||
class ReportManager;
|
||||
|
||||
/**
|
||||
|
@@ -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:
|
||||
@@ -39,6 +39,10 @@
|
||||
#include "util/graph_range.h"
|
||||
#include "util/ue2_containers.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
|
||||
namespace ue2 {
|
||||
|
||||
/**
|
||||
@@ -51,7 +55,7 @@ namespace ue2 {
|
||||
typedef boost::adjacency_list<boost::setS, // out edges
|
||||
boost::listS, // vertices
|
||||
boost::undirectedS, // graph is undirected
|
||||
boost::property<boost::vertex_index_t, u32> >
|
||||
boost::property<boost::vertex_index_t, size_t> >
|
||||
NFAUndirectedGraph;
|
||||
|
||||
typedef NFAUndirectedGraph::vertex_descriptor NFAUndirectedVertex;
|
||||
@@ -60,16 +64,18 @@ typedef NFAUndirectedGraph::vertex_descriptor NFAUndirectedVertex;
|
||||
* Make a copy of an NFAGraph with undirected edges, optionally without start
|
||||
* vertices. Mappings from the original graph to the new one are provided.
|
||||
*
|
||||
* Note that new vertex indices are assigned contiguously in \a vertices(g) order.
|
||||
* Note that new vertex indices are assigned contiguously in \a vertices(g)
|
||||
* order.
|
||||
*/
|
||||
template <typename GraphT>
|
||||
void createUnGraph(const GraphT &g,
|
||||
bool excludeStarts,
|
||||
bool excludeAccepts,
|
||||
NFAUndirectedGraph &ug,
|
||||
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> &old2new,
|
||||
ue2::unordered_map<u32, NFAVertex> &newIdx2old) {
|
||||
u32 idx = 0;
|
||||
bool excludeStarts,
|
||||
bool excludeAccepts,
|
||||
NFAUndirectedGraph &ug,
|
||||
ue2::unordered_map<typename GraphT::vertex_descriptor,
|
||||
NFAUndirectedVertex> &old2new) {
|
||||
size_t idx = 0;
|
||||
typedef typename GraphT::vertex_descriptor VertexT;
|
||||
|
||||
for (auto v : ue2::vertices_range(g)) {
|
||||
// skip all accept nodes
|
||||
@@ -84,13 +90,12 @@ void createUnGraph(const GraphT &g,
|
||||
|
||||
NFAUndirectedVertex nuv = boost::add_vertex(ug);
|
||||
old2new[v] = nuv;
|
||||
newIdx2old[idx] = v;
|
||||
boost::put(boost::vertex_index, ug, nuv, idx++);
|
||||
}
|
||||
|
||||
for (const auto &e : ue2::edges_range(g)) {
|
||||
NFAVertex src = source(e, g);
|
||||
NFAVertex targ = target(e, g);
|
||||
VertexT src = source(e, g);
|
||||
VertexT targ = target(e, g);
|
||||
|
||||
if ((excludeAccepts && is_any_accept(src, g))
|
||||
|| (excludeStarts && is_any_start(src, g))) {
|
||||
|
@@ -176,7 +176,7 @@ void findSeeds(const NGHolder &h, const bool som, vector<NFAVertex> *seeds) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("%u is a seed\n", h[v].index);
|
||||
DEBUG_PRINTF("%zu is a seed\n", h[v].index);
|
||||
seeds->push_back(v);
|
||||
already_seeds.insert(v);
|
||||
}
|
||||
@@ -184,7 +184,7 @@ void findSeeds(const NGHolder &h, const bool som, vector<NFAVertex> *seeds) {
|
||||
|
||||
static
|
||||
bool expandCyclic(NGHolder &h, NFAVertex v) {
|
||||
DEBUG_PRINTF("inspecting %u\n", h[v].index);
|
||||
DEBUG_PRINTF("inspecting %zu\n", h[v].index);
|
||||
bool changes = false;
|
||||
|
||||
auto v_preds = preds(v, h);
|
||||
@@ -201,7 +201,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
|
||||
auto a_preds = preds(a, h);
|
||||
|
||||
if (a_preds == v_preds && isutf8start(h[a].char_reach)) {
|
||||
DEBUG_PRINTF("%u is a start v\n", h[a].index);
|
||||
DEBUG_PRINTF("%zu is a start v\n", h[a].index);
|
||||
start_siblings.insert(a);
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
|
||||
auto a_succs = succs(a, h);
|
||||
|
||||
if (a_succs == v_succs && h[a].char_reach == UTF_CONT_CR) {
|
||||
DEBUG_PRINTF("%u is a full tail cont\n", h[a].index);
|
||||
DEBUG_PRINTF("%zu is a full tail cont\n", h[a].index);
|
||||
end_siblings.insert(a);
|
||||
}
|
||||
}
|
||||
@@ -226,7 +226,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
|
||||
if (cr.isSubsetOf(UTF_TWO_START_CR)) {
|
||||
if (end_siblings.find(*adjacent_vertices(s, h).first)
|
||||
== end_siblings.end()) {
|
||||
DEBUG_PRINTF("%u is odd\n", h[s].index);
|
||||
DEBUG_PRINTF("%zu is odd\n", h[s].index);
|
||||
continue;
|
||||
}
|
||||
} else if (cr.isSubsetOf(UTF_THREE_START_CR)) {
|
||||
@@ -238,7 +238,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
|
||||
}
|
||||
if (end_siblings.find(*adjacent_vertices(m, h).first)
|
||||
== end_siblings.end()) {
|
||||
DEBUG_PRINTF("%u is odd\n", h[s].index);
|
||||
DEBUG_PRINTF("%zu is odd\n", h[s].index);
|
||||
continue;
|
||||
}
|
||||
} else if (cr.isSubsetOf(UTF_FOUR_START_CR)) {
|
||||
@@ -258,11 +258,11 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
|
||||
|
||||
if (end_siblings.find(*adjacent_vertices(m2, h).first)
|
||||
== end_siblings.end()) {
|
||||
DEBUG_PRINTF("%u is odd\n", h[s].index);
|
||||
DEBUG_PRINTF("%zu is odd\n", h[s].index);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
DEBUG_PRINTF("%u is bad\n", h[s].index);
|
||||
DEBUG_PRINTF("%zu is bad\n", h[s].index);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -52,7 +52,7 @@
|
||||
|
||||
using namespace std;
|
||||
using boost::default_color_type;
|
||||
using boost::filtered_graph;
|
||||
using boost::make_filtered_graph;
|
||||
using boost::make_assoc_property_map;
|
||||
using boost::adaptors::map_values;
|
||||
|
||||
@@ -172,15 +172,14 @@ namespace {
|
||||
struct CycleFound {};
|
||||
struct DetectCycles : public boost::default_dfs_visitor {
|
||||
explicit DetectCycles(const NGHolder &g) : startDs(g.startDs) {}
|
||||
void back_edge(const NFAEdge &e, const NFAGraph &g) const {
|
||||
void back_edge(const NFAEdge &e, const NGHolder &g) const {
|
||||
NFAVertex u = source(e, g), v = target(e, g);
|
||||
// We ignore the startDs self-loop.
|
||||
if (u == startDs && v == startDs) {
|
||||
return;
|
||||
}
|
||||
// Any other back-edge indicates a cycle.
|
||||
DEBUG_PRINTF("back edge %u->%u found\n", g[u].index,
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("back edge %zu->%zu found\n", g[u].index, g[v].index);
|
||||
throw CycleFound();
|
||||
}
|
||||
private:
|
||||
@@ -215,10 +214,8 @@ bool isFloating(const NGHolder &g) {
|
||||
|
||||
bool isAcyclic(const NGHolder &g) {
|
||||
try {
|
||||
depth_first_search(
|
||||
g.g, visitor(DetectCycles(g))
|
||||
.root_vertex(g.start)
|
||||
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
|
||||
boost::depth_first_search(g, visitor(DetectCycles(g))
|
||||
.root_vertex(g.start));
|
||||
} catch (const CycleFound &) {
|
||||
return false;
|
||||
}
|
||||
@@ -234,11 +231,11 @@ bool hasReachableCycle(const NGHolder &g, NFAVertex src) {
|
||||
try {
|
||||
// Use depth_first_visit, rather than depth_first_search, so that we
|
||||
// only search from src.
|
||||
auto index_map = get(&NFAGraphVertexProps::index, g.g);
|
||||
depth_first_visit(
|
||||
g.g, src, DetectCycles(g),
|
||||
make_iterator_property_map(colors.begin(), index_map));
|
||||
} catch (const CycleFound&) {
|
||||
auto index_map = get(vertex_index, g);
|
||||
boost::depth_first_visit(g, src, DetectCycles(g),
|
||||
make_iterator_property_map(colors.begin(),
|
||||
index_map));
|
||||
} catch (const CycleFound &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -249,10 +246,7 @@ bool hasBigCycles(const NGHolder &g) {
|
||||
assert(hasCorrectlyNumberedVertices(g));
|
||||
set<NFAEdge> dead;
|
||||
BackEdges<set<NFAEdge>> backEdgeVisitor(dead);
|
||||
depth_first_search(
|
||||
g.g, visitor(backEdgeVisitor)
|
||||
.root_vertex(g.start)
|
||||
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
|
||||
boost::depth_first_search(g, visitor(backEdgeVisitor).root_vertex(g.start));
|
||||
|
||||
for (const auto &e : dead) {
|
||||
if (source(e, g) != target(e, g)) {
|
||||
@@ -266,8 +260,7 @@ bool hasBigCycles(const NGHolder &g) {
|
||||
set<NFAVertex> findVerticesInCycles(const NGHolder &g) {
|
||||
map<NFAVertex, size_t> comp_map;
|
||||
|
||||
strong_components(g.g, make_assoc_property_map(comp_map),
|
||||
vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
|
||||
strong_components(g, make_assoc_property_map(comp_map));
|
||||
|
||||
map<size_t, set<NFAVertex> > comps;
|
||||
|
||||
@@ -298,8 +291,7 @@ set<NFAVertex> findVerticesInCycles(const NGHolder &g) {
|
||||
|
||||
bool can_never_match(const NGHolder &g) {
|
||||
assert(edge(g.accept, g.acceptEod, g).second);
|
||||
if (!hasGreaterInDegree(0, g.accept, g)
|
||||
&& !hasGreaterInDegree(1, g.acceptEod, g)) {
|
||||
if (in_degree(g.accept, g) == 0 && in_degree(g.acceptEod, g) == 1) {
|
||||
DEBUG_PRINTF("no paths into accept\n");
|
||||
return true;
|
||||
}
|
||||
@@ -308,7 +300,7 @@ bool can_never_match(const NGHolder &g) {
|
||||
}
|
||||
|
||||
bool can_match_at_eod(const NGHolder &h) {
|
||||
if (hasGreaterInDegree(1, h.acceptEod, h)) {
|
||||
if (in_degree(h.acceptEod, h) > 1) {
|
||||
DEBUG_PRINTF("more than one edge to acceptEod\n");
|
||||
return true;
|
||||
}
|
||||
@@ -396,21 +388,17 @@ vector<NFAVertex> getTopoOrdering(const NGHolder &g) {
|
||||
EdgeSet backEdges;
|
||||
BackEdges<EdgeSet> be(backEdges);
|
||||
|
||||
auto index_map = get(&NFAGraphVertexProps::index, g.g);
|
||||
depth_first_search(g.g, visitor(be)
|
||||
.root_vertex(g.start)
|
||||
.color_map(make_iterator_property_map(
|
||||
colour.begin(), index_map))
|
||||
.vertex_index_map(index_map));
|
||||
auto index_map = get(vertex_index, g);
|
||||
depth_first_search(g, visitor(be).root_vertex(g.start)
|
||||
.color_map(make_iterator_property_map(
|
||||
colour.begin(), index_map)));
|
||||
|
||||
auto acyclic_g = make_filtered_graph(g.g, make_bad_edge_filter(&backEdges));
|
||||
auto acyclic_g = make_filtered_graph(g, make_bad_edge_filter(&backEdges));
|
||||
|
||||
vector<NFAVertex> ordering;
|
||||
ordering.reserve(num_verts);
|
||||
topological_sort(
|
||||
acyclic_g, back_inserter(ordering),
|
||||
color_map(make_iterator_property_map(colour.begin(), index_map))
|
||||
.vertex_index_map(index_map));
|
||||
topological_sort(acyclic_g, back_inserter(ordering),
|
||||
color_map(make_iterator_property_map(colour.begin(), index_map)));
|
||||
|
||||
reorderSpecials(g, ordering);
|
||||
|
||||
@@ -434,12 +422,12 @@ void mustBeSetBefore_int(NFAVertex u, const NGHolder &g,
|
||||
}
|
||||
}
|
||||
|
||||
auto prefix = make_filtered_graph(g.g, make_bad_edge_filter(&dead));
|
||||
auto prefix = make_filtered_graph(g, make_bad_edge_filter(&dead));
|
||||
|
||||
depth_first_visit(
|
||||
prefix, g.start, make_dfs_visitor(boost::null_visitor()),
|
||||
make_iterator_property_map(vertexColor.begin(),
|
||||
get(&NFAGraphVertexProps::index, g.g)));
|
||||
get(vertex_index, g)));
|
||||
}
|
||||
|
||||
bool mustBeSetBefore(NFAVertex u, NFAVertex v, const NGHolder &g,
|
||||
@@ -456,15 +444,14 @@ bool mustBeSetBefore(NFAVertex u, NFAVertex v, const NGHolder &g,
|
||||
mustBeSetBefore_int(u, g, vertexColor);
|
||||
|
||||
for (auto vi : vertices_range(g)) {
|
||||
auto key2 = make_pair(g[u].index,
|
||||
g[vi].index);
|
||||
DEBUG_PRINTF("adding %u %u\n", key2.first, key2.second);
|
||||
auto key2 = make_pair(g[u].index, g[vi].index);
|
||||
DEBUG_PRINTF("adding %zu %zu\n", key2.first, key2.second);
|
||||
assert(!contains(cache.cache, key2));
|
||||
bool value = vertexColor[g[vi].index] == boost::white_color;
|
||||
cache.cache[key2] = value;
|
||||
assert(contains(cache.cache, key2));
|
||||
}
|
||||
DEBUG_PRINTF("cache miss %u %u (%zu)\n", key.first, key.second,
|
||||
DEBUG_PRINTF("cache miss %zu %zu (%zu)\n", key.first, key.second,
|
||||
cache.cache.size());
|
||||
return cache.cache[key];
|
||||
}
|
||||
@@ -592,12 +579,13 @@ void fillHolder(NGHolder *outp, const NGHolder &in, const deque<NFAVertex> &vv,
|
||||
fillHolderOutEdges(out, in, v_map, u);
|
||||
}
|
||||
|
||||
out.renumberEdges();
|
||||
out.renumberVertices();
|
||||
renumber_edges(out);
|
||||
renumber_vertices(out);
|
||||
}
|
||||
|
||||
void cloneHolder(NGHolder &out, const NGHolder &in) {
|
||||
assert(hasCorrectlyNumberedVertices(in));
|
||||
assert(hasCorrectlyNumberedVertices(out));
|
||||
out.kind = in.kind;
|
||||
|
||||
// Note: depending on the state of the input graph, some stylized edges
|
||||
@@ -607,6 +595,7 @@ void cloneHolder(NGHolder &out, const NGHolder &in) {
|
||||
/* remove the existing special edges */
|
||||
clear_vertex(out.startDs, out);
|
||||
clear_vertex(out.accept, out);
|
||||
renumber_edges(out);
|
||||
|
||||
vector<NFAVertex> out_mapping(num_vertices(in));
|
||||
out_mapping[NODE_START] = out.start;
|
||||
@@ -642,8 +631,8 @@ void cloneHolder(NGHolder &out, const NGHolder &in) {
|
||||
}
|
||||
|
||||
// Safety checks.
|
||||
assert(num_vertices(in.g) == num_vertices(out.g));
|
||||
assert(num_edges(in.g) == num_edges(out.g));
|
||||
assert(num_vertices(in) == num_vertices(out));
|
||||
assert(num_edges(in) == num_edges(out));
|
||||
assert(hasCorrectlyNumberedVertices(out));
|
||||
}
|
||||
|
||||
@@ -672,9 +661,8 @@ unique_ptr<NGHolder> cloneHolder(const NGHolder &in) {
|
||||
void reverseHolder(const NGHolder &g_in, NGHolder &g) {
|
||||
// Make the BGL do the grunt work.
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> vertexMap;
|
||||
boost::transpose_graph(g_in.g, g.g,
|
||||
orig_to_copy(boost::make_assoc_property_map(vertexMap)).
|
||||
vertex_index_map(get(&NFAGraphVertexProps::index, g_in.g)));
|
||||
boost::transpose_graph(g_in, g,
|
||||
orig_to_copy(boost::make_assoc_property_map(vertexMap)));
|
||||
|
||||
// The transpose_graph operation will have created extra copies of our
|
||||
// specials. We have to rewire their neighbours to the 'real' specials and
|
||||
@@ -716,8 +704,8 @@ void reverseHolder(const NGHolder &g_in, NGHolder &g) {
|
||||
|
||||
// Renumber so that g's properties (number of vertices, edges) are
|
||||
// accurate.
|
||||
g.renumberVertices();
|
||||
g.renumberEdges();
|
||||
renumber_vertices(g);
|
||||
renumber_edges(g);
|
||||
|
||||
assert(num_vertices(g) == num_vertices(g_in));
|
||||
assert(num_edges(g) == num_edges(g_in));
|
||||
@@ -729,8 +717,7 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
|
||||
unordered_set<NFAVertex> reporters;
|
||||
for (auto v : inv_adjacent_vertices_range(g.accept, g)) {
|
||||
if (g[v].reports.empty()) {
|
||||
DEBUG_PRINTF("vertex %u has no reports!\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu has no reports!\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
reporters.insert(v);
|
||||
@@ -741,8 +728,7 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
|
||||
continue; // stylised edge
|
||||
}
|
||||
if (g[v].reports.empty()) {
|
||||
DEBUG_PRINTF("vertex %u has no reports!\n",
|
||||
g[v].index);
|
||||
DEBUG_PRINTF("vertex %zu has no reports!\n", g[v].index);
|
||||
return false;
|
||||
}
|
||||
reporters.insert(v);
|
||||
@@ -750,7 +736,7 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
|
||||
|
||||
for (auto v : vertices_range(g)) {
|
||||
if (!contains(reporters, v) && !g[v].reports.empty()) {
|
||||
DEBUG_PRINTF("vertex %u is not a match state, but has reports!\n",
|
||||
DEBUG_PRINTF("vertex %zu is not a match state, but has reports!\n",
|
||||
g[v].index);
|
||||
return false;
|
||||
}
|
||||
@@ -759,34 +745,6 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasCorrectlyNumberedVertices(const NGHolder &g) {
|
||||
size_t count = num_vertices(g);
|
||||
vector<bool> ids(count, false);
|
||||
for (auto v : vertices_range(g)) {
|
||||
u32 id = g[v].index;
|
||||
if (id >= count || ids[id]) {
|
||||
return false; // duplicate
|
||||
}
|
||||
ids[id] = true;
|
||||
}
|
||||
return find(ids.begin(), ids.end(), false) == ids.end()
|
||||
&& num_vertices(g) == num_vertices(g.g);
|
||||
}
|
||||
|
||||
bool hasCorrectlyNumberedEdges(const NGHolder &g) {
|
||||
size_t count = num_edges(g);
|
||||
vector<bool> ids(count, false);
|
||||
for (const auto &e : edges_range(g)) {
|
||||
u32 id = g[e].index;
|
||||
if (id >= count || ids[id]) {
|
||||
return false; // duplicate
|
||||
}
|
||||
ids[id] = true;
|
||||
}
|
||||
return find(ids.begin(), ids.end(), false) == ids.end()
|
||||
&& num_edges(g) == num_edges(g.g);
|
||||
}
|
||||
|
||||
bool isCorrectlyTopped(const NGHolder &g) {
|
||||
if (is_triggered(g)) {
|
||||
for (const auto &e : out_edges_range(g.start, g)) {
|
||||
@@ -805,7 +763,6 @@ bool isCorrectlyTopped(const NGHolder &g) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif // NDEBUG
|
||||
|
||||
} // namespace ue2
|
||||
|
@@ -65,9 +65,8 @@ bool is_dot(NFAVertex v, const GraphT &g) {
|
||||
template<class U>
|
||||
static really_inline
|
||||
void succ(const NGHolder &g, NFAVertex v, U *s) {
|
||||
NGHolder::adjacency_iterator ai, ae;
|
||||
tie(ai, ae) = adjacent_vertices(v, g);
|
||||
s->insert(ai, ae);
|
||||
auto rv = adjacent_vertices(v, g);
|
||||
s->insert(rv.first, rv.second);
|
||||
}
|
||||
|
||||
template<class ContTemp = flat_set<NFAVertex>>
|
||||
@@ -81,9 +80,8 @@ ContTemp succs(NFAVertex u, const NGHolder &g) {
|
||||
template<class U>
|
||||
static really_inline
|
||||
void pred(const NGHolder &g, NFAVertex v, U *p) {
|
||||
NGHolder::inv_adjacency_iterator it, ite;
|
||||
tie(it, ite) = inv_adjacent_vertices(v, g);
|
||||
p->insert(it, ite);
|
||||
auto rv = inv_adjacent_vertices(v, g);
|
||||
p->insert(rv.first, rv.second);
|
||||
}
|
||||
|
||||
template<class ContTemp = flat_set<NFAVertex>>
|
||||
@@ -138,42 +136,11 @@ public:
|
||||
BackEdgeSet &backEdges;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic code to renumber all the vertices in a graph. Assumes that we're
|
||||
* using a vertex_index property of type u32, and that we always have
|
||||
* N_SPECIALS special vertices already present (which we don't want to
|
||||
* renumber).
|
||||
*/
|
||||
template<typename GraphT>
|
||||
static really_inline
|
||||
size_t renumberGraphVertices(GraphT &g) {
|
||||
size_t num = N_SPECIALS;
|
||||
for (const auto &v : vertices_range(g)) {
|
||||
if (!is_special(v, g)) {
|
||||
g[v].index = num++;
|
||||
assert(num > 0); // no wrapping
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
/** Renumber all the edges in a graph. */
|
||||
template<typename GraphT>
|
||||
static really_inline
|
||||
size_t renumberGraphEdges(GraphT &g) {
|
||||
size_t num = 0;
|
||||
for (const auto &e : edges_range(g)) {
|
||||
g[e].index = num++;
|
||||
assert(num > 0); // no wrapping
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
/** Returns true if the vertex is either of the real starts (NODE_START,
|
||||
* NODE_START_DOTSTAR). */
|
||||
template <typename GraphT>
|
||||
static really_inline
|
||||
bool is_any_start(const NFAVertex v, const GraphT &g) {
|
||||
bool is_any_start(typename GraphT::vertex_descriptor v, const GraphT &g) {
|
||||
u32 i = g[v].index;
|
||||
return i == NODE_START || i == NODE_START_DOTSTAR;
|
||||
}
|
||||
@@ -181,16 +148,14 @@ bool is_any_start(const NFAVertex v, const GraphT &g) {
|
||||
bool is_virtual_start(NFAVertex v, const NGHolder &g);
|
||||
|
||||
template <typename GraphT>
|
||||
static really_inline
|
||||
bool is_any_accept(const NFAVertex v, const GraphT &g) {
|
||||
bool is_any_accept(typename GraphT::vertex_descriptor v, const GraphT &g) {
|
||||
u32 i = g[v].index;
|
||||
return i == NODE_ACCEPT || i == NODE_ACCEPT_EOD;
|
||||
}
|
||||
|
||||
/** returns true iff v has an edge to accept or acceptEod */
|
||||
template <typename GraphT>
|
||||
static really_inline
|
||||
bool is_match_vertex(NFAVertex v, const GraphT &g) {
|
||||
bool is_match_vertex(typename GraphT::vertex_descriptor v, const GraphT &g) {
|
||||
return edge(v, g.accept, g).second || edge(v, g.acceptEod, g).second;
|
||||
}
|
||||
|
||||
@@ -202,25 +167,6 @@ bool is_match_vertex(NFAVertex v, const GraphT &g) {
|
||||
*/
|
||||
std::vector<NFAVertex> getTopoOrdering(const NGHolder &g);
|
||||
|
||||
/** Comparison functor used to sort by vertex_index. */
|
||||
template<typename Graph>
|
||||
struct VertexIndexOrdering {
|
||||
VertexIndexOrdering(const Graph &g_in) : g(&g_in) {}
|
||||
bool operator()(typename Graph::vertex_descriptor a,
|
||||
typename Graph::vertex_descriptor b) const {
|
||||
assert(a == b || (*g)[a].index != (*g)[b].index);
|
||||
return (*g)[a].index < (*g)[b].index;
|
||||
}
|
||||
private:
|
||||
const Graph *g;
|
||||
};
|
||||
|
||||
template<typename Graph>
|
||||
static
|
||||
VertexIndexOrdering<Graph> make_index_ordering(const Graph &g) {
|
||||
return VertexIndexOrdering<Graph>(g);
|
||||
}
|
||||
|
||||
bool onlyOneTop(const NGHolder &g);
|
||||
|
||||
/** Return the set of the tops on the given graph. */
|
||||
@@ -340,18 +286,6 @@ void reverseHolder(const NGHolder &g, NGHolder &out);
|
||||
*/
|
||||
bool allMatchStatesHaveReports(const NGHolder &g);
|
||||
|
||||
/**
|
||||
* Assertion: returns true if the vertices in this graph are contiguously (and
|
||||
* uniquely) numbered from zero.
|
||||
*/
|
||||
bool hasCorrectlyNumberedVertices(const NGHolder &g);
|
||||
|
||||
/**
|
||||
* Assertion: returns true if the edges in this graph are contiguously (and
|
||||
* uniquely) numbered from zero.
|
||||
*/
|
||||
bool hasCorrectlyNumberedEdges(const NGHolder &g);
|
||||
|
||||
/**
|
||||
* Assertion: returns true if the graph is triggered and all edges out of start
|
||||
* have tops OR if the graph is not-triggered and all edges out of start have no
|
||||
|
@@ -464,7 +464,7 @@ void getRegionRoseLiterals(const NGHolder &g, bool seeking_anchored,
|
||||
DEBUG_PRINTF("inspecting region %u\n", region);
|
||||
set<ue2_literal> s;
|
||||
for (auto v : vv) {
|
||||
DEBUG_PRINTF(" exit vertex: %u\n", g[v].index);
|
||||
DEBUG_PRINTF(" exit vertex: %zu\n", g[v].index);
|
||||
/* Note: RHS can not be depended on to take all subsequent revisits
|
||||
* to this vertex */
|
||||
set<ue2_literal> ss = getLiteralSet(g, v, false);
|
||||
@@ -669,7 +669,7 @@ unique_ptr<VertLitInfo> findBestSplit(const NGHolder &g,
|
||||
lits.pop_back();
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("best is '%s' %u a%d t%d\n",
|
||||
DEBUG_PRINTF("best is '%s' %zu a%d t%d\n",
|
||||
dumpString(*best->lit.begin()).c_str(),
|
||||
g[best->vv.front()].index,
|
||||
depths ? (int)createsAnchoredLHS(g, best->vv, *depths, cc.grey) : 0,
|
||||
@@ -777,7 +777,7 @@ set<NFAVertex> poisonVertices(const NGHolder &h, const RoseInGraph &vg,
|
||||
set<NFAVertex> bad_vertices;
|
||||
for (const NFAEdge &e : bad_edges) {
|
||||
bad_vertices.insert(target(e, h));
|
||||
DEBUG_PRINTF("bad: %u->%u\n", h[source(e, h)].index,
|
||||
DEBUG_PRINTF("bad: %zu->%zu\n", h[source(e, h)].index,
|
||||
h[target(e, h)].index);
|
||||
}
|
||||
|
||||
@@ -1144,7 +1144,7 @@ void splitEdgesByCut(NGHolder &h, RoseInGraph &vg,
|
||||
NFAVertex prev_v = source(e, h);
|
||||
NFAVertex pivot = target(e, h);
|
||||
|
||||
DEBUG_PRINTF("splitting on pivot %u\n", h[pivot].index);
|
||||
DEBUG_PRINTF("splitting on pivot %zu\n", h[pivot].index);
|
||||
ue2::unordered_map<NFAVertex, NFAVertex> temp_map;
|
||||
shared_ptr<NGHolder> new_lhs = make_shared<NGHolder>();
|
||||
splitLHS(h, pivot, new_lhs.get(), &temp_map);
|
||||
@@ -1324,7 +1324,7 @@ bool deanchorIfNeeded(NGHolder &g) {
|
||||
succ_g.erase(g.startDs);
|
||||
|
||||
for (auto v : adjacent_vertices_range(g.start, g)) {
|
||||
DEBUG_PRINTF("inspecting cand %u || = %zu\n", g[v].index,
|
||||
DEBUG_PRINTF("inspecting cand %zu || = %zu\n", g[v].index,
|
||||
g[v].char_reach.count());
|
||||
|
||||
if (v == g.startDs || !g[v].char_reach.all()) {
|
||||
@@ -2339,7 +2339,7 @@ bool leadingDotStartLiteral(const NGHolder &h, VertLitInfo *out) {
|
||||
make_nocase(&lit);
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("%u found %s\n", h[v].index, dumpString(lit).c_str());
|
||||
DEBUG_PRINTF("%zu found %s\n", h[v].index, dumpString(lit).c_str());
|
||||
out->vv = {v};
|
||||
out->lit = {lit};
|
||||
return true;
|
||||
@@ -2468,7 +2468,7 @@ bool trailingDotStarLiteral(const NGHolder &h, VertLitInfo *out) {
|
||||
}
|
||||
|
||||
ue2_literal lit = reverse_literal(rv.second);
|
||||
DEBUG_PRINTF("%u found %s\n", h[v].index, dumpString(lit).c_str());
|
||||
DEBUG_PRINTF("%zu found %s\n", h[v].index, dumpString(lit).c_str());
|
||||
|
||||
if (bad_mixed_sensitivity(lit)) {
|
||||
make_nocase(&lit);
|
||||
@@ -2672,6 +2672,7 @@ bool doViolet(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
|
||||
pruneUseless(vg);
|
||||
dumpPreRoseGraph(vg, cc.grey);
|
||||
renumber_vertices(vg);
|
||||
calcVertexOffsets(vg);
|
||||
bool rv = rose.addRose(vg, prefilter);
|
||||
DEBUG_PRINTF("violet: %s\n", rv ? "success" : "fail");
|
||||
|
@@ -58,18 +58,18 @@ namespace {
|
||||
struct SpecialEdgeFilter {
|
||||
SpecialEdgeFilter() {}
|
||||
explicit SpecialEdgeFilter(const NGHolder &h_in) : h(&h_in) {}
|
||||
explicit SpecialEdgeFilter(const NGHolder &h_in, u32 top_in)
|
||||
SpecialEdgeFilter(const NGHolder &h_in, u32 top_in)
|
||||
: h(&h_in), single_top(true), top(top_in) {}
|
||||
|
||||
bool operator()(const NFAEdge &e) const {
|
||||
const NFAGraph &g = h->g;
|
||||
NFAVertex u = source(e, g), v = target(e, g);
|
||||
if ((is_any_start(u, g) && is_any_start(v, g)) ||
|
||||
(is_any_accept(u, g) && is_any_accept(v, g))) {
|
||||
NFAVertex u = source(e, *h);
|
||||
NFAVertex v = target(e, *h);
|
||||
if ((is_any_start(u, *h) && is_any_start(v, *h)) ||
|
||||
(is_any_accept(u, *h) && is_any_accept(v, *h))) {
|
||||
return false;
|
||||
}
|
||||
if (single_top) {
|
||||
if (u == h->start && !contains(g[e].tops, top)) {
|
||||
if (u == h->start && !contains((*h)[e].tops, top)) {
|
||||
return false;
|
||||
}
|
||||
if (u == h->startDs) {
|
||||
@@ -94,7 +94,7 @@ depth findMinWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
|
||||
return depth::unreachable();
|
||||
}
|
||||
|
||||
boost::filtered_graph<NFAGraph, SpecialEdgeFilter> g(h.g, filter);
|
||||
boost::filtered_graph<NGHolder, SpecialEdgeFilter> g(h, filter);
|
||||
|
||||
assert(hasCorrectlyNumberedVertices(h));
|
||||
const size_t num = num_vertices(h);
|
||||
@@ -106,11 +106,10 @@ depth findMinWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
|
||||
// Since we are interested in the single-source shortest paths on a graph
|
||||
// with the same weight on every edge, using BFS will be faster than
|
||||
// Dijkstra here.
|
||||
breadth_first_search(
|
||||
g, src,
|
||||
breadth_first_search(g, src,
|
||||
visitor(make_bfs_visitor(record_distances(
|
||||
make_iterator_property_map(distance.begin(), index_map),
|
||||
boost::on_tree_edge()))).vertex_index_map(index_map));
|
||||
boost::on_tree_edge()))));
|
||||
|
||||
DEBUG_PRINTF("d[accept]=%s, d[acceptEod]=%s\n",
|
||||
distance.at(NODE_ACCEPT).str().c_str(),
|
||||
@@ -130,7 +129,7 @@ depth findMinWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
|
||||
static
|
||||
depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
|
||||
NFAVertex src) {
|
||||
if (isLeafNode(src, h.g)) {
|
||||
if (isLeafNode(src, h)) {
|
||||
return depth::unreachable();
|
||||
}
|
||||
|
||||
@@ -139,7 +138,7 @@ depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
|
||||
return depth::infinity();
|
||||
}
|
||||
|
||||
boost::filtered_graph<NFAGraph, SpecialEdgeFilter> g(h.g, filter);
|
||||
boost::filtered_graph<NGHolder, SpecialEdgeFilter> g(h, filter);
|
||||
|
||||
assert(hasCorrectlyNumberedVertices(h));
|
||||
const size_t num = num_vertices(h);
|
||||
@@ -149,11 +148,9 @@ depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
|
||||
auto index_map = get(&NFAGraphVertexProps::index, g);
|
||||
|
||||
// DAG shortest paths with negative edge weights.
|
||||
dag_shortest_paths(
|
||||
g, src,
|
||||
dag_shortest_paths(g, src,
|
||||
distance_map(make_iterator_property_map(distance.begin(), index_map))
|
||||
.weight_map(boost::make_constant_property<NFAEdge>(-1))
|
||||
.vertex_index_map(index_map)
|
||||
.color_map(make_iterator_property_map(colors.begin(), index_map)));
|
||||
|
||||
depth acceptDepth, acceptEodDepth;
|
||||
|
Reference in New Issue
Block a user