Merge branch 'develop' into wip-cppcheck271-part2

This commit is contained in:
g. economou
2024-05-17 11:08:09 +03:00
committed by GitHub
211 changed files with 3167 additions and 2125 deletions

View File

@@ -193,9 +193,6 @@ void reduceGraph(NGHolder &g, som_type som, bool utf8,
if (!som) {
mergeCyclicDotStars(g);
}
if (!som) {
removeSiblingsOfStartDotStar(g);
}
}
@@ -292,7 +289,7 @@ bool addComponent(NG &ng, NGHolder &g, const ExpressionInfo &expr,
// Returns true if all components have been added.
static
bool processComponents(NG &ng, ExpressionInfo &expr,
bool processComponents(NG &ng, const ExpressionInfo &expr,
deque<unique_ptr<NGHolder>> &g_comp,
const som_type som) {
const u32 num_components = g_comp.size();

View File

@@ -166,9 +166,9 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
return;
}
NFAVertex dotV = NGHolder::null_vertex();
set<NFAVertex> otherV;
dotV = findReformable(g, compAnchoredStarts, otherV);
NFAVertex dotV = findReformable(g, compAnchoredStarts, otherV);
if (dotV == NGHolder::null_vertex()) {
DEBUG_PRINTF("no candidate reformable dot found.\n");
return;
@@ -258,7 +258,7 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
static
void reformUnanchoredRepeatsComponent(NGHolder &g,
set<NFAVertex> &compAnchoredStarts,
const set<NFAVertex> &compAnchoredStarts,
set<NFAVertex> &compUnanchoredStarts,
set<NFAVertex> &dead,
depth *startBegin, depth *startEnd) {
@@ -269,9 +269,9 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
}
while (true) {
NFAVertex dotV = NGHolder::null_vertex();
set<NFAVertex> otherV;
dotV = findReformable(g, compUnanchoredStarts, otherV);
NFAVertex dotV = findReformable(g, compUnanchoredStarts, otherV);
if (dotV == NGHolder::null_vertex()) {
DEBUG_PRINTF("no candidate reformable dot found.\n");
return;
@@ -488,15 +488,15 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
// Collect all the other optional dot vertices and the successor vertices
// by walking down the graph from initialDot
set<NFAVertex> dots, succ;
if (!gatherParticipants(g, start, initialDot, dots, succ)) {
set<NFAVertex> dots, succr;
if (!gatherParticipants(g, start, initialDot, dots, succr)) {
DEBUG_PRINTF("gatherParticipants failed\n");
return;
}
DEBUG_PRINTF("optional dot repeat with %zu participants, "
"terminating in %zu non-dot nodes\n",
dots.size(), succ.size());
dots.size(), succr.size());
// Remove all the participants and set the start offset
dead.insert(dots.begin(), dots.end());
@@ -512,7 +512,7 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
assert(startEnd->is_reachable());
// Connect our successor vertices to both start and startDs.
for (auto v : succ) {
for (auto v : succr) {
add_edge_if_not_present(g.start, v, g);
add_edge_if_not_present(g.startDs, v, g);
}
@@ -558,7 +558,7 @@ void collapseVariableRepeats(NGHolder &g, depth *startBegin, depth *startEnd) {
}
static
void addDotsBetween(NGHolder &g, NFAVertex lhs, vector<NFAVertex> &rhs,
void addDotsBetween(NGHolder &g, NFAVertex lhs, const vector<NFAVertex> &rhs,
depth min_repeat, depth max_repeat) {
const bool unbounded = max_repeat.is_infinite();
if (unbounded) {

View File

@@ -92,11 +92,12 @@ static const CharReach CHARREACH_NONWORD_UCP_PRE(CHARREACH_NONWORD);
static
vector<NFAEdge> getAsserts(const NGHolder &g) {
vector<NFAEdge> out;
for (const auto &e : edges_range(g)) {
if (g[e].assert_flags) {
out.emplace_back(e);
}
}
auto assertflags = [&g=g](const NFAEdge &e) {
return (g[e].assert_flags);
};
const auto &er = edges_range(g);
std::copy_if(begin(er), end(er), std::back_inserter(out), assertflags);
return out;
}
@@ -384,7 +385,10 @@ void resolveEdges(ReportManager &rm, NGHolder &g, const ExpressionInfo &expr,
/* there may already be a different edge from start to eod if so
* we need to make it unconditional and alive
*/
if (NFAEdge start_eod = edge(u, g.acceptEod, g)) {
NFAEdge start_eod;
bool exists;
std::tie(start_eod, exists) = edge(u, g.acceptEod, g);
if (exists) {
g[start_eod].assert_flags = 0;
dead->erase(start_eod);
} else {
@@ -437,7 +441,10 @@ void resolveEdges(ReportManager &rm, NGHolder &g, const ExpressionInfo &expr,
/* there may already be a different edge from start to eod if so
* we need to make it unconditional and alive
*/
if (NFAEdge start_eod = edge(u, g.acceptEod, g)) {
NFAEdge start_eod;
bool exists;
std::tie(start_eod, exists) = edge(u, g.acceptEod, g);
if (exists) {
g[start_eod].assert_flags = 0;
dead->erase(start_eod);
} else {
@@ -496,7 +503,8 @@ void ensureCodePointStart(ReportManager &rm, NGHolder &g,
* boundaries. Assert resolution handles the badness coming from asserts.
* The only other source of trouble is startDs->accept connections.
*/
NFAEdge orig = edge(g.startDs, g.accept, g);
NFAEdge orig;
std::tie(orig, std::ignore) = edge(g.startDs, g.accept, g);
if (expr.utf8 && orig) {
DEBUG_PRINTF("rectifying %u\n", expr.report);
Report ir = rm.getBasicInternalReport(expr);

View File

@@ -514,17 +514,17 @@ bool removeSiblingsOfStartDotStar(NGHolder &g) {
* for SOM mode. (see UE-1544) */
bool optimiseVirtualStarts(NGHolder &g) {
vector<NFAEdge> dead;
auto deads = [&g=g](const NFAEdge &e) {
return (!is_any_start(source(e, g), g));
};
for (auto v : adjacent_vertices_range(g.startDs, g)) {
u32 flags = g[v].assert_flags;
if (!(flags & POS_FLAG_VIRTUAL_START)) {
continue;
}
for (const auto &e : in_edges_range(v, g)) {
if (!is_any_start(source(e, g), g)) {
dead.emplace_back(e);
}
}
const auto &e = in_edges_range(v, g);
std::copy_if(begin(e), end(e), std::back_inserter(dead), deads);
}
if (dead.empty()) {

View File

@@ -98,9 +98,9 @@ class ClassInfo {
public:
struct ClassDepth {
ClassDepth() {}
ClassDepth(const NFAVertexDepth &d)
explicit ClassDepth(const NFAVertexDepth &d)
: d1(d.fromStart), d2(d.fromStartDotStar) {}
ClassDepth(const NFAVertexRevDepth &rd)
explicit ClassDepth(const NFAVertexRevDepth &rd)
: d1(rd.toAccept), d2(rd.toAcceptEod) {}
DepthMinMax d1;
DepthMinMax d2;
@@ -159,7 +159,7 @@ public:
return id;
}
void append(WorkQueue &other) {
void append(const WorkQueue &other) {
for (const auto &e : other) {
push(e);
}
@@ -193,7 +193,7 @@ private:
}
static
bool outIsIrreducible(NFAVertex &v, const NGHolder &g) {
bool outIsIrreducible(const NFAVertex &v, const NGHolder &g) {
unsigned nonSpecialVertices = 0;
for (auto w : adjacent_vertices_range(v, g)) {
if (!is_special(w, g) && w != v) {
@@ -205,7 +205,7 @@ bool outIsIrreducible(NFAVertex &v, const NGHolder &g) {
}
static
bool inIsIrreducible(NFAVertex &v, const NGHolder &g) {
bool inIsIrreducible(const NFAVertex &v, const NGHolder &g) {
unsigned nonSpecialVertices = 0;
for (auto u : inv_adjacent_vertices_range(v, g)) {
if (!is_special(u, g) && u != v) {
@@ -339,9 +339,9 @@ vector<VertexInfoSet> partitionGraph(vector<unique_ptr<VertexInfo>> &infos,
ClassInfo::ClassDepth depth;
if (eq == LEFT_EQUIVALENCE) {
depth = depths[vi->vert_index];
depth = ClassInfo::ClassDepth(depths[vi->vert_index]);
} else {
depth = rdepths[vi->vert_index];
depth = ClassInfo::ClassDepth(rdepths[vi->vert_index]);
}
ClassInfo ci(g, *vi, depth, eq);
@@ -549,8 +549,8 @@ void mergeClass(vector<unique_ptr<VertexInfo>> &infos, NGHolder &g,
pred_info->succ.erase(old_vertex_info);
// if edge doesn't exist, create it
NFAEdge e = add_edge_if_not_present(pred_info->v, new_v, g);
NFAEdge e;
std::tie(e, std::ignore) = add_edge_if_not_present(pred_info->v, new_v, g);
// put edge tops, if applicable
if (!edgetops.empty()) {
assert(g[e].tops.empty() || g[e].tops == edgetops);
@@ -560,7 +560,8 @@ void mergeClass(vector<unique_ptr<VertexInfo>> &infos, NGHolder &g,
pred_info->succ.insert(new_vertex_info);
if (new_v_eod) {
NFAEdge ee = add_edge_if_not_present(pred_info->v, new_v_eod,
NFAEdge ee;
std::tie(ee, std::ignore) = add_edge_if_not_present(pred_info->v, new_v_eod,
g);
// put edge tops, if applicable

View File

@@ -432,7 +432,7 @@ NFAVertex findSingleCyclic(const NGHolder &g) {
}
static
bool hasOffsetAdjust(const ReportManager &rm, NGHolder &g,
bool hasOffsetAdjust(const ReportManager &rm, const NGHolder &g,
int *adjust) {
const auto &reports = all_reports(g);
if (reports.empty()) {
@@ -509,14 +509,14 @@ bool transformMinLengthToRepeat(NGHolder &g, ReportManager &rm) {
while (v != cyclic) {
DEBUG_PRINTF("vertex %zu\n", g[v].index);
width++;
auto succ = succs(v, g);
if (contains(succ, cyclic)) {
if (succ.size() == 1) {
auto s = succs(v, g);
if (contains(s, cyclic)) {
if (s.size() == 1) {
v = cyclic;
} else if (succ.size() == 2) {
} else if (s.size() == 2) {
// Cyclic and jump edge.
succ.erase(cyclic);
NFAVertex v2 = *succ.begin();
s.erase(cyclic);
NFAVertex v2 = *s.begin();
if (!edge(cyclic, v2, g).second) {
DEBUG_PRINTF("bad form\n");
return false;
@@ -527,11 +527,11 @@ bool transformMinLengthToRepeat(NGHolder &g, ReportManager &rm) {
return false;
}
} else {
if (succ.size() != 1) {
if (s.size() != 1) {
DEBUG_PRINTF("bad form\n");
return false;
}
v = *succ.begin();
v = *s.begin();
}
}
@@ -547,12 +547,12 @@ bool transformMinLengthToRepeat(NGHolder &g, ReportManager &rm) {
while (!is_any_accept(v, g)) {
DEBUG_PRINTF("vertex %zu\n", g[v].index);
width++;
auto succ = succs(v, g);
if (succ.size() != 1) {
auto s = succs(v, g);
if (s.size() != 1) {
DEBUG_PRINTF("bad form\n");
return false;
}
v = *succ.begin();
v = *s.begin();
}
int offsetAdjust = 0;
@@ -572,27 +572,28 @@ bool transformMinLengthToRepeat(NGHolder &g, ReportManager &rm) {
return true;
}
vector<NFAVertex> preds;
vector<NFAVertex> predcs;
vector<NFAEdge> dead;
auto deads = [&g=g](const NFAEdge &e) {
return (target(e, g) != g.startDs);
};
for (auto u : inv_adjacent_vertices_range(cyclic, g)) {
DEBUG_PRINTF("pred %zu\n", g[u].index);
if (u == cyclic) {
continue;
}
preds.emplace_back(u);
predcs.emplace_back(u);
// We want to delete the out-edges of each predecessor, but need to
// make sure we don't delete the startDs self loop.
for (const auto &e : out_edges_range(u, g)) {
if (target(e, g) != g.startDs) {
dead.emplace_back(e);
}
}
const auto &e = out_edges_range(u, g);
std::copy_if(begin(e), end(e), std::back_inserter(dead), deads);
}
remove_edges(dead, g);
assert(!preds.empty());
assert(!predcs.empty());
const CharReach &cr = g[cyclic].char_reach;
@@ -600,14 +601,14 @@ bool transformMinLengthToRepeat(NGHolder &g, ReportManager &rm) {
v = add_vertex(g);
g[v].char_reach = cr;
for (auto u : preds) {
for (auto u : predcs) {
add_edge(u, v, g);
}
preds.clear();
preds.emplace_back(v);
predcs.clear();
predcs.emplace_back(v);
}
assert(!preds.empty());
for (auto u : preds) {
assert(!predcs.empty());
for (auto u : predcs) {
add_edge(u, cyclic, g);
}

View File

@@ -66,15 +66,15 @@ bool findMask(const NGHolder &g, vector<CharReach> *mask, bool *anchored,
return false;
}
set<NFAVertex> &succs = *anchored ? s_succ : sds_succ;
succs.erase(g.startDs);
if (succs.size() != 1) {
set<NFAVertex> &succrs = *anchored ? s_succ : sds_succ;
succrs.erase(g.startDs);
if (succrs.size() != 1) {
DEBUG_PRINTF("branchy root\n");
return false;
}
NFAVertex u = *anchored ? g.start : g.startDs;
NFAVertex v = *succs.begin();
NFAVertex v = *succrs.begin();
while (true) {
DEBUG_PRINTF("validating vertex %zu\n", g[v].index);

View File

@@ -71,13 +71,13 @@ vector<flat_set<NFAVertex>> gatherSuccessorsByDepth(const NGHolder &g,
continue;
}
for (auto succ : adjacent_vertices_range(v, g)) {
for (auto succr : adjacent_vertices_range(v, g)) {
// ignore self-loops
if (v == succ) {
if (v == succr) {
continue;
}
DEBUG_PRINTF("Node %zu depth %u\n", g[succ].index, d + 1);
next.insert(succ);
next.insert(succr);
}
}
result[d] = next;
@@ -113,13 +113,13 @@ vector<flat_set<NFAVertex>> gatherPredecessorsByDepth(const NGHolder &g,
for (unsigned d = 1; d < depth; d++) {
// collect all successors for all current level vertices
for (auto v : cur) {
for (auto pred : inv_adjacent_vertices_range(v, g)) {
for (auto predc : inv_adjacent_vertices_range(v, g)) {
// ignore self-loops
if (v == pred) {
if (v == predc) {
continue;
}
DEBUG_PRINTF("Node %zu depth %u\n", g[pred].index, d + 1);
next.insert(pred);
next.insert(predc);
}
}
result[d] = next;
@@ -582,11 +582,11 @@ private:
// set up all reports
bool clone = false;
for (auto &pair : reports_to_vertices) {
for (const auto &pair : reports_to_vertices) {
const auto &reports = pair.first;
const auto &vertices = pair.second;
const auto &svertices = pair.second;
for (auto src : vertices) {
for (auto src : svertices) {
// get all predecessors up to edit distance
auto src_vertices_by_depth =
gatherPredecessorsByDepth(g, src, edit_distance);
@@ -594,7 +594,8 @@ private:
// find which accepts source vertex connects to
flat_set<NFAVertex> targets;
for (const auto &accept : accepts) {
NFAEdge e = edge(src, accept, g);
NFAEdge e;
std::tie(e, std::ignore) = edge(src, accept, g);
if (e) {
targets.insert(accept);
}
@@ -602,8 +603,8 @@ private:
assert(targets.size());
for (unsigned d = 0; d < src_vertices_by_depth.size(); d++) {
const auto &preds = src_vertices_by_depth[d];
for (auto v : preds) {
const auto &predcs = src_vertices_by_depth[d];
for (auto v : predcs) {
// only clone a node if it already contains reports
if (clone && !g[v].reports.empty()) {
create_clone(v, reports, edit_distance - d,

View File

@@ -514,12 +514,12 @@ static
bool doHaig(const NGHolder &g, som_type som,
const vector<vector<CharReach>> &triggers, bool unordered_som,
raw_som_dfa *rdfa) {
u32 state_limit = HAIG_FINAL_DFA_STATE_LIMIT; /* haig never backs down from
a fight */
using StateSet = typename Auto::StateSet;
vector<StateSet> nfa_state_map;
Auto n(g, som, triggers, unordered_som);
try {
u32 state_limit = HAIG_FINAL_DFA_STATE_LIMIT; /* haig never backs down from
a fight */
if (!determinise(n, rdfa->states, state_limit, &nfa_state_map)) {
DEBUG_PRINTF("state limit exceeded\n");
return false;

View File

@@ -154,7 +154,7 @@ bytecode_ptr<NFA> buildLbrDot(const CharReach &cr, const depth &repeatMin,
const depth &repeatMax, u32 minPeriod,
bool is_reset, ReportID report) {
if (!cr.all()) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
enum RepeatType rtype = chooseRepeatType(repeatMin, repeatMax, minPeriod,
@@ -176,7 +176,7 @@ bytecode_ptr<NFA> buildLbrVerm(const CharReach &cr, const depth &repeatMin,
const CharReach escapes(~cr);
if (escapes.count() != 1) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
enum RepeatType rtype = chooseRepeatType(repeatMin, repeatMax, minPeriod,
@@ -199,7 +199,7 @@ bytecode_ptr<NFA> buildLbrNVerm(const CharReach &cr, const depth &repeatMin,
const CharReach escapes(cr);
if (escapes.count() != 1) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
enum RepeatType rtype = chooseRepeatType(repeatMin, repeatMax, minPeriod,
@@ -228,7 +228,7 @@ bytecode_ptr<NFA> buildLbrShuf(const CharReach &cr, const depth &repeatMin,
minPeriod, rtype);
if (shuftiBuildMasks(~cr, (u8 *)&ls->mask_lo, (u8 *)&ls->mask_hi) == -1) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
DEBUG_PRINTF("built shuf lbr\n");
@@ -296,7 +296,7 @@ bytecode_ptr<NFA> constructLBR(const CharReach &cr, const depth &repeatMin,
if (!nfa) {
assert(0);
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
return nfa;
@@ -307,11 +307,11 @@ bytecode_ptr<NFA> constructLBR(const CastleProto &proto,
const CompileContext &cc,
const ReportManager &rm) {
if (!cc.grey.allowLbr) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
if (proto.repeats.size() != 1) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
const PureRepeat &repeat = proto.repeats.begin()->second;
@@ -319,7 +319,7 @@ bytecode_ptr<NFA> constructLBR(const CastleProto &proto,
if (repeat.reports.size() != 1) {
DEBUG_PRINTF("too many reports\n");
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
bool is_reset;
@@ -346,16 +346,16 @@ bytecode_ptr<NFA> constructLBR(const NGHolder &g,
const CompileContext &cc,
const ReportManager &rm) {
if (!cc.grey.allowLbr) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
PureRepeat repeat;
if (!isPureRepeat(g, repeat)) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
if (repeat.reports.size() != 1) {
DEBUG_PRINTF("too many reports\n");
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
CastleProto proto(g.kind, repeat);

View File

@@ -39,7 +39,7 @@ bytecode_ptr<NFA> buildLbrVerm16(const CharReach &cr, const depth &repeatMin,
const CharReach escapes(~cr);
if (escapes.count() > 16) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
enum RepeatType rtype = chooseRepeatType(repeatMin, repeatMax, minPeriod,
@@ -62,7 +62,7 @@ bytecode_ptr<NFA> buildLbrNVerm16(const CharReach &cr, const depth &repeatMin,
const CharReach escapes(cr);
if (escapes.count() > 16) {
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
enum RepeatType rtype = chooseRepeatType(repeatMin, repeatMax, minPeriod,

View File

@@ -342,7 +342,7 @@ void attemptToUseAsStart(const NGHolder &g, NFAVertex u,
map<NFAVertex, flat_set<u32>> &unhandled_succ_tops,
map<u32, set<NFAVertex>> &tops_out) {
flat_set<u32> top_inter = unhandled_succ_tops.at(u);
flat_set<NFAVertex> succs;
flat_set<NFAVertex> f_succs;
for (NFAVertex v : adjacent_vertices_range(u, g)) {
if (!contains(unhandled_succ_tops, v)) {
return;
@@ -360,7 +360,7 @@ void attemptToUseAsStart(const NGHolder &g, NFAVertex u,
set_intersection(top_inter.begin(), top_inter.end(),
v_tops.begin(), v_tops.end(), ni_inserter);
top_inter = std::move(new_inter);
succs.insert(v);
f_succs.insert(v);
}
if (top_inter.empty()) {
@@ -373,7 +373,7 @@ void attemptToUseAsStart(const NGHolder &g, NFAVertex u,
}
DEBUG_PRINTF("reusing %zu is a start vertex\n", g[u].index);
markTopSuccAsHandled(u, top_inter, succs, tops_out, unhandled_top_succs,
markTopSuccAsHandled(u, top_inter, f_succs, tops_out, unhandled_top_succs,
unhandled_succ_tops);
}
@@ -389,11 +389,11 @@ void reusePredsAsStarts(const NGHolder &g, const map<u32, CharReach> &top_reach,
/* 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) {
if (hasSelfLoop(u, g)) {
cand_starts.emplace_back(u);
}
}
auto cands = [&g=g](const NFAVertex &u) {
return (hasSelfLoop(u, g));
};
const auto &u = unhandled_succ_tops | map_keys;
std::copy_if(begin(u), end(u), std::back_inserter(cand_starts), cands);
for (NFAVertex u : cand_starts) {
if (!contains(unhandled_succ_tops, u)) {
@@ -652,7 +652,7 @@ constructNFA(const NGHolder &h_in, const ReportManager *rm,
u32 numStates = countStates(state_ids);
if (numStates > NFA_MAX_STATES) {
DEBUG_PRINTF("Can't build an NFA with %u states\n", numStates);
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
map<NFAVertex, BoundedRepeatSummary> br_cyclic;
@@ -722,14 +722,14 @@ bytecode_ptr<NFA> constructReversedNFA_i(const NGHolder &h_in, u32 hint,
assert(h.kind == NFA_REV_PREFIX); /* triggered, raises internal callbacks */
// Do state numbering.
auto state_ids = numberStates(h, {});
auto state_ids = numberStates(h, flat_set<graph_detail::vertex_descriptor<ue2_graph<NGHolder, NFAGraphVertexProps, NFAGraphEdgeProps>>>());
// Quick exit: if we've got an embarrassment of riches, i.e. more states
// than we can implement in our largest NFA model, bail here.
u32 numStates = countStates(state_ids);
if (numStates > NFA_MAX_STATES) {
DEBUG_PRINTF("Can't build an NFA with %u states\n", numStates);
return nullptr;
return bytecode_ptr<NFA>(nullptr);
}
assert(sanityCheckGraph(h, state_ids));

View File

@@ -62,12 +62,12 @@ namespace ue2 {
static
void findAccelFriendGeneration(const NGHolder &g, const CharReach &cr,
const flat_set<NFAVertex> &cands,
const flat_set<NFAVertex> &preds,
const flat_set<NFAVertex> &f_preds,
flat_set<NFAVertex> *next_cands,
flat_set<NFAVertex> *next_preds,
flat_set<NFAVertex> *friends) {
for (auto v : cands) {
if (contains(preds, v)) {
if (contains(f_preds, v)) {
continue;
}
@@ -80,7 +80,7 @@ void findAccelFriendGeneration(const NGHolder &g, const CharReach &cr,
}
for (auto u : inv_adjacent_vertices_range(v, g)) {
if (!contains(preds, u)) {
if (!contains(f_preds, u)) {
DEBUG_PRINTF("bad pred\n");
goto next_cand;
}
@@ -116,8 +116,8 @@ void findAccelFriends(const NGHolder &g, NFAVertex v,
u32 friend_depth = offset + 1;
flat_set<NFAVertex> preds;
insert(&preds, inv_adjacent_vertices(v, g));
flat_set<NFAVertex> f_preds;
insert(&f_preds, inv_adjacent_vertices(v, g));
const CharReach &cr = g[v].char_reach;
flat_set<NFAVertex> cands;
@@ -126,9 +126,9 @@ void findAccelFriends(const NGHolder &g, NFAVertex v,
flat_set<NFAVertex> next_preds;
flat_set<NFAVertex> next_cands;
for (u32 i = 0; i < friend_depth; i++) {
findAccelFriendGeneration(g, cr, cands, preds, &next_cands, &next_preds,
findAccelFriendGeneration(g, cr, cands, f_preds, &next_cands, &next_preds,
friends);
preds.insert(next_preds.begin(), next_preds.end());
f_preds.insert(next_preds.begin(), next_preds.end());
next_preds.clear();
cands.swap(next_cands);
next_cands.clear();
@@ -321,7 +321,7 @@ struct DAccelScheme {
bool cd_a = buildDvermMask(a.double_byte);
bool cd_b = buildDvermMask(b.double_byte);
if (cd_a != cd_b) {
return cd_a > cd_b;
return cd_a;
}
}
@@ -811,11 +811,9 @@ depth_done:
return true;
}
}
}
// Second option: a two-byte shufti (i.e. less than eight 2-byte
// literals)
if (depth > 1) {
for (unsigned int i = 0; i < (depth - 1); i++) {
if (depthReach[i].count() * depthReach[i+1].count()
<= DOUBLE_SHUFTI_LIMIT) {

View File

@@ -490,9 +490,9 @@ vector<LitEdge> add_reverse_edges_and_index(LitGraph &lg) {
const size_t edge_count = num_edges(lg);
vector<LitEdge> fwd_edges;
fwd_edges.reserve(edge_count);
for (const auto &e : edges_range(lg)) {
fwd_edges.push_back(e);
}
const auto &e = edges_range(lg);
std::copy(begin(e), end(e), std::back_inserter(fwd_edges));
vector<LitEdge> rev_map(2 * edge_count);

View File

@@ -70,7 +70,7 @@ bool bad_mixed_sensitivity(const ue2_literal &s);
* Score all the edges in the given graph, returning them in \p scores indexed
* by edge_index. */
std::vector<u64a> scoreEdges(const NGHolder &h,
const flat_set<NFAEdge> &known_bad = {});
const flat_set<NFAEdge> &known_bad = flat_set<NFAEdge>());
/** Returns a score for a literal set. Lower scores are better. */
u64a scoreSet(const std::set<ue2_literal> &s);

View File

@@ -98,7 +98,7 @@ void addToString(string &s, const NGHolder &g, NFAVertex v) {
}
static
bool splitOffLiteral(NG &ng, NGHolder &g, NFAVertex v, const bool anchored,
bool splitOffLiteral(NG &ng, const NGHolder &g, NFAVertex v, const bool anchored,
set<NFAVertex> &dead) {
DEBUG_PRINTF("examine vertex %zu\n", g[v].index);
bool nocase = false, casefixed = false;

View File

@@ -94,7 +94,7 @@ void transition_graph(autom &nfa, const std::vector<NFAVertex> &vByStateId,
/* generate top transitions, false -> top = selfloop */
bool top_allowed = is_triggered(graph);
StateSet succ = nfa.dead;
StateSet succr = nfa.dead;
for (size_t i = in.find_first(); i != in.npos; i = in.find_next(i)) {
NFAVertex u = vByStateId[i];
@@ -102,7 +102,7 @@ void transition_graph(autom &nfa, const std::vector<NFAVertex> &vByStateId,
if (contains(unused, v)) {
continue;
}
succ.set(graph[v].index);
succr.set(graph[v].index);
}
if (top_allowed && !nfa.toppable.test(i)) {
@@ -112,15 +112,15 @@ void transition_graph(autom &nfa, const std::vector<NFAVertex> &vByStateId,
}
}
StateSet active_squash = succ & squash;
StateSet active_squash = succr & squash;
if (active_squash.any()) {
for (size_t j = active_squash.find_first(); j != active_squash.npos;
j = active_squash.find_next(j)) {
succ &= squash_mask.find(j)->second;
succr &= squash_mask.find(j)->second;
}
}
for (size_t j = succ.find_first(); j != succ.npos; j = succ.find_next(j)) {
for (size_t j = succr.find_first(); j != succr.npos; j = succr.find_next(j)) {
const CharReach &cr = cr_by_index[j];
for (size_t s = cr.find_first(); s != cr.npos; s = cr.find_next(s)) {
next[s].set(j); /* already alpha'ed */

View File

@@ -404,19 +404,19 @@ CharReach reduced_cr(NFAVertex v, const NGHolder &g,
return v_cr;
}
NFAVertex pred = getSoleSourceVertex(g, v);
assert(pred);
NFAVertex s_pred = getSoleSourceVertex(g, v);
assert(s_pred);
/* require pred to be fed by one vertex OR (start + startDS) */
/* require s_pred to be fed by one vertex OR (start + startDS) */
NFAVertex predpred;
size_t idp = in_degree(pred, g);
if (hasSelfLoop(pred, g)) {
size_t idp = in_degree(s_pred, g);
if (hasSelfLoop(s_pred, g)) {
return v_cr; /* not cliche */
} else if (idp == 1) {
predpred = getSoleSourceVertex(g, pred);
predpred = getSoleSourceVertex(g, s_pred);
} else if (idp == 2
&& edge(g.start, pred, g).second
&& edge(g.startDs, pred, g).second) {
&& edge(g.start, s_pred, g).second
&& edge(g.startDs, s_pred, g).second) {
predpred = g.startDs;
} else {
return v_cr; /* not cliche */
@@ -425,7 +425,7 @@ CharReach reduced_cr(NFAVertex v, const NGHolder &g,
assert(predpred);
/* require predpred to be cyclic and its cr to be a superset of
pred and v */
s_pred and v */
if (!hasSelfLoop(predpred, g)) {
return v_cr; /* not cliche */
}
@@ -435,7 +435,7 @@ CharReach reduced_cr(NFAVertex v, const NGHolder &g,
return v_cr; /* fake cyclic */
}
const CharReach &p_cr = g[pred].char_reach;
const CharReach &p_cr = g[s_pred].char_reach;
const CharReach &pp_cr = g[predpred].char_reach;
if (!v_cr.isSubsetOf(pp_cr) || !p_cr.isSubsetOf(pp_cr)) {
return v_cr; /* not cliche */
@@ -446,7 +446,7 @@ CharReach reduced_cr(NFAVertex v, const NGHolder &g,
set<NFAVertex> v_succ;
insert(&v_succ, adjacent_vertices(v, g));
set<NFAVertex> p_succ;
insert(&p_succ, adjacent_vertices(pred, g));
insert(&p_succ, adjacent_vertices(s_pred, g));
if (!is_subset_of(v_succ, p_succ)) {
DEBUG_PRINTF("fail\n");
@@ -456,7 +456,7 @@ CharReach reduced_cr(NFAVertex v, const NGHolder &g,
if (contains(v_succ, g.accept) || contains(v_succ, g.acceptEod)) {
/* need to check that reports of v are a subset of p's */
if (!is_subset_of(g[v].reports,
g[pred].reports)) {
g[s_pred].reports)) {
DEBUG_PRINTF("fail - reports not subset\n");
return v_cr; /* not cliche */
}

View File

@@ -93,7 +93,8 @@ void addReverseEdges(NGHolder &g, vector<NFAEdge> &reverseEdge,
if (it == allEdges.end()) {
// No reverse edge, add one.
NFAVertex u = source(fwd, g), v = target(fwd, g);
NFAEdge rev = add_edge(v, u, g);
NFAEdge rev;
std::tie(rev, std::ignore) = add_edge(v, u, g);
it = allEdges.insert(make_pair(make_pair(vidx, uidx), rev)).first;
// Add to capacity map.
u32 revIndex = g[rev].index;

View File

@@ -62,11 +62,13 @@ void pruneUnreachable(NGHolder &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)) {
if (!is_special(v, g)) {
dead.emplace_back(v);
}
}
auto deads = [&g=g](const NFAVertex &v) {
return (!is_special(v, g));
};
const auto &vr = vertices_range(g);
std::copy_if(begin(vr), end(vr), std::back_inserter(dead), deads);
} else {
// Walk a reverse graph from acceptEod with Boost's depth_first_visit
// call.
@@ -199,17 +201,17 @@ void pruneHighlanderAccepts(NGHolder &g, const ReportManager &rm) {
}
vector<NFAEdge> dead;
auto deads = [&g=g](const NFAEdge &e) {
return (!is_any_accept(target(e, g), g));
};
for (auto u : inv_adjacent_vertices_range(g.accept, g)) {
if (is_special(u, g)) {
continue;
}
// We can prune any out-edges that aren't accepts
for (const auto &e : out_edges_range(u, g)) {
if (!is_any_accept(target(e, g), g)) {
dead.emplace_back(e);
}
}
const auto &er = out_edges_range(u, g);
std::copy_if(begin(er), end(er), std::back_inserter(dead), deads);
}
if (dead.empty()) {

View File

@@ -244,7 +244,7 @@ u32 allowedSquashDistance(const CharReach &cr, u32 min_width, const NGHolder &g,
/** Gives a stronger puff trigger when the trigger is connected to a wide
* cyclic state (aside from sds) */
static
void improveHead(NGHolder &g, NFAVertex *a, vector<NFAVertex> *nodes) {
void improveHead(const NGHolder &g, NFAVertex *a, vector<NFAVertex> *nodes) {
DEBUG_PRINTF("attempting to improve puff trigger\n");
assert(!nodes->empty());
const CharReach &puff_cr = g[nodes->back()].char_reach;
@@ -263,7 +263,7 @@ void improveHead(NGHolder &g, NFAVertex *a, vector<NFAVertex> *nodes) {
}
static
void constructPuff(NGHolder &g, const NFAVertex a, const NFAVertex puffv,
void constructPuff(const NGHolder &g, const NFAVertex a, const NFAVertex puffv,
const CharReach &cr, const ReportID report, u32 width,
bool fixed_depth, bool unbounded, bool auto_restart,
RoseBuild &rose, ReportManager &rm,
@@ -361,9 +361,7 @@ bool doComponent(RoseBuild &rose, ReportManager &rm, NGHolder &g, NFAVertex a,
// single report ID on a vertex
if (is_match_vertex(a, g)) {
DEBUG_PRINTF("stop puffing due to vertex that leads to accept\n");
if (!nodes.empty()) {
nodes.pop_back();
}
nodes.pop_back();
break;
}
}

View File

@@ -307,13 +307,15 @@ void markForRemoval(const NFAVertex v, VertexInfoMap &infoMap,
static
bool hasInEdgeTops(const NGHolder &g, NFAVertex v) {
NFAEdge e = edge(g.start, v, g);
NFAEdge e;
std::tie(e, std::ignore) = edge(g.start, v, g);
return e && !g[e].tops.empty();
}
/** Transform (1), removal of redundant vertices. */
static
bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
bool doUselessMergePass(const NGHolder &g, const som_type som, VertexInfoMap &infoMap,
set<NFAVertex> &removable) {
/* useless merges can be done in any order, no need to take any care with
* ordering */
@@ -323,7 +325,7 @@ bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
bool changed = false;
for (auto v : vertices_range(g)) {
VertexInfo &info = infoMap[v];
const VertexInfo &info = infoMap[v];
if (info.isRemoved) {
continue;
@@ -439,7 +441,7 @@ bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
continue; // Conservatively skip anything with nonzero tops.
}
CharReach &otherReach = g[t].char_reach;
const CharReach &otherReach = g[t].char_reach;
if (currReach.isSubsetOf(otherReach)) {
DEBUG_PRINTF("removing redundant vertex %zu (keeping %zu)\n",
g[v].index, g[t].index);
@@ -636,12 +638,12 @@ bool reversePathReachSubset(const NFAEdge &e, const NFAVertex &dom,
NFAVertex start = source(e, g);
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 {
map<RevGraph::vertex_descriptor, boost::default_color_type> vertexColor;
depth_first_visit(RevGraph(g), start,
ReachSubsetVisitor(domReach),
make_assoc_property_map(vertexColor),
@@ -664,12 +666,12 @@ bool forwardPathReachSubset(const NFAEdge &e, const NFAVertex &dom,
}
NFAVertex start = target(e, g);
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 {
map<NFAVertex, boost::default_color_type> vertexColor;
depth_first_visit(g, start, ReachSubsetVisitor(domReach),
make_assoc_property_map(vertexColor),
VertexIs<NGHolder, NFAVertex>(dom));
@@ -748,7 +750,7 @@ u32 findCyclic(const NGHolder &g, vector<bool> &cyclic) {
}
static
void findCyclicDom(NGHolder &g, vector<bool> &cyclic,
void findCyclicDom(const NGHolder &g, vector<bool> &cyclic,
set<NFAEdge> &dead, som_type som) {
auto dominators = findDominators(g);
@@ -792,7 +794,7 @@ void findCyclicDom(NGHolder &g, vector<bool> &cyclic,
}
static
void findCyclicPostDom(NGHolder &g, vector<bool> &cyclic,
void findCyclicPostDom(const NGHolder &g, vector<bool> &cyclic,
set<NFAEdge> &dead) {
auto postdominators = findPostDominators(g);

View File

@@ -393,9 +393,9 @@ void checkReachSubgraphs(const NGHolder &g, vector<ReachSubgraph> &rs,
unordered_set<NFAVertex> involved(rsi.vertices.begin(),
rsi.vertices.end());
unordered_set<NFAVertex> tail(involved); // to look for back-edges.
unordered_set<NFAVertex> pred, succ;
proper_pred(g, rsi.vertices.front(), pred);
proper_succ(g, rsi.vertices.back(), succ);
unordered_set<NFAVertex> v_pred, v_succ;
proper_pred(g, rsi.vertices.front(), v_pred);
proper_succ(g, rsi.vertices.back(), v_succ);
flat_set<ReportID> reports;
findFirstReports(g, rsi, reports);
@@ -406,7 +406,7 @@ void checkReachSubgraphs(const NGHolder &g, vector<ReachSubgraph> &rs,
for (auto v : rsi.vertices) {
tail.erase(v); // now contains all vertices _after_ this one.
if (vertexIsBad(g, v, involved, tail, pred, succ, reports)) {
if (vertexIsBad(g, v, involved, tail, v_pred, v_succ, reports)) {
recalc = true;
continue;
}
@@ -793,10 +793,10 @@ void replaceSubgraphWithSpecial(NGHolder &g, ReachSubgraph &rsi,
const unordered_set<NFAVertex> involved(rsi.vertices.begin(),
rsi.vertices.end());
vector<NFAVertex> succs;
getSuccessors(g, rsi, &succs);
vector<NFAVertex> g_succs;
getSuccessors(g, rsi, &g_succs);
unpeelNearEnd(g, rsi, depths, &succs);
unpeelNearEnd(g, rsi, depths, &g_succs);
// Create our replacement cyclic state with the same reachability and
// report info as the last vertex in our topo-ordered list.
@@ -824,7 +824,7 @@ void replaceSubgraphWithSpecial(NGHolder &g, ReachSubgraph &rsi,
// Wire cyclic state to tug trigger states built from successors.
vector<NFAVertex> tugs;
for (auto v : succs) {
for (auto v : g_succs) {
buildTugTrigger(g, cyclic, v, involved, depths, tugs);
}
created.insert(tugs.begin(), tugs.end());
@@ -859,11 +859,9 @@ void replaceSubgraphWithLazySpecial(NGHolder &g, ReachSubgraph &rsi,
assert(rsi.repeatMax >= rsi.repeatMin);
DEBUG_PRINTF("entry\n");
const unordered_set<NFAVertex> involved(rsi.vertices.begin(),
rsi.vertices.end());
vector<NFAVertex> succs;
getSuccessors(g, rsi, &succs);
vector<NFAVertex> g_succs;
getSuccessors(g, rsi, &g_succs);
// Create our replacement cyclic state with the same reachability and
// report info as the last vertex in our topo-ordered list.
@@ -892,15 +890,15 @@ void replaceSubgraphWithLazySpecial(NGHolder &g, ReachSubgraph &rsi,
// In the rose case, our tug is our cyclic, and it's wired to our
// successors (which should be just the accept).
vector<NFAVertex> tugs;
assert(succs.size() == 1);
for (auto v : succs) {
assert(g_succs.size() == 1);
for (auto v : g_succs) {
add_edge(cyclic, v, g);
}
// Wire pos trigger to accept if min repeat is one -- this deals with cases
// where we can get a pos and tug trigger on the same byte.
if (rsi.repeatMin == depth(1)) {
for (auto v : succs) {
for (auto v : g_succs) {
add_edge(pos_trigger, v, g);
g[pos_trigger].reports = g[cyclic].reports;
}
@@ -1144,7 +1142,7 @@ NFAVertex buildTriggerStates(NGHolder &g, const vector<CharReach> &trigger,
g[v].char_reach = cr;
add_edge(u, v, g);
if (u == g.start) {
g[edge(u, v, g)].tops.insert(top);
g[edge(u, v, g).first].tops.insert(top);
}
u = v;
}
@@ -1467,9 +1465,9 @@ struct StrawWalker {
}
if (ai != ae) {
DEBUG_PRINTF("more than one succ\n");
set<NFAVertex> succs;
insert(&succs, adjacent_vertices(v, g));
succs.erase(v);
set<NFAVertex> a_succs;
insert(&a_succs, adjacent_vertices(v, g));
a_succs.erase(v);
for (tie(ai, ae) = adjacent_vertices(v, g); ai != ae; ++ai) {
next = *ai;
DEBUG_PRINTF("checking %zu\n", g[next].index);
@@ -1479,7 +1477,7 @@ struct StrawWalker {
set<NFAVertex> lsuccs;
insert(&lsuccs, adjacent_vertices(next, g));
if (lsuccs != succs) {
if (lsuccs != a_succs) {
continue;
}
@@ -1887,7 +1885,7 @@ void buildFeeder(NGHolder &g, const BoundedRepeatData &rd,
* offset.
*/
static
bool improveLeadingRepeat(NGHolder &g, BoundedRepeatData &rd,
bool improveLeadingRepeat(NGHolder &g, const BoundedRepeatData &rd,
unordered_set<NFAVertex> &created,
const vector<BoundedRepeatData> &all_repeats) {
assert(edge(g.startDs, g.startDs, g).second);
@@ -1908,9 +1906,9 @@ bool improveLeadingRepeat(NGHolder &g, BoundedRepeatData &rd,
}
vector<NFAVertex> straw;
NFAVertex pred =
NFAVertex w_pred =
walkStrawToCyclicRev(g, rd.pos_trigger, all_repeats, straw);
if (pred != g.startDs) {
if (w_pred != g.startDs) {
DEBUG_PRINTF("straw walk doesn't lead to startDs\n");
return false;
}
@@ -1958,7 +1956,7 @@ bool improveLeadingRepeat(NGHolder &g, BoundedRepeatData &rd,
}
static
vector<NFAVertex> makeOwnStraw(NGHolder &g, BoundedRepeatData &rd,
vector<NFAVertex> makeOwnStraw(NGHolder &g, const BoundedRepeatData &rd,
const vector<NFAVertex> &straw) {
// Straw runs from startDs to our pos trigger.
assert(!straw.empty());
@@ -1992,7 +1990,7 @@ vector<NFAVertex> makeOwnStraw(NGHolder &g, BoundedRepeatData &rd,
* rewire the straw to start instead of removing the startDs self-loop.
*/
static
bool improveLeadingRepeatOutfix(NGHolder &g, BoundedRepeatData &rd,
bool improveLeadingRepeatOutfix(NGHolder &g, const BoundedRepeatData &rd,
unordered_set<NFAVertex> &created,
const vector<BoundedRepeatData> &all_repeats) {
assert(g.kind == NFA_OUTFIX);
@@ -2013,9 +2011,9 @@ bool improveLeadingRepeatOutfix(NGHolder &g, BoundedRepeatData &rd,
}
vector<NFAVertex> straw;
NFAVertex pred =
NFAVertex w_pred =
walkStrawToCyclicRev(g, rd.pos_trigger, all_repeats, straw);
if (pred != g.startDs) {
if (w_pred != g.startDs) {
DEBUG_PRINTF("straw walk doesn't lead to startDs\n");
return false;
}

View File

@@ -54,8 +54,8 @@ void wireStartToTops(NGHolder &g, const flat_set<NFAVertex> &tops,
vector<NFAEdge> &tempEdges) {
for (NFAVertex v : tops) {
assert(!isLeafNode(v, g));
const NFAEdge &e = add_edge(g.start, v, g);
auto edge_result = add_edge(g.start, v, g);
const NFAEdge &e = edge_result.first;
tempEdges.emplace_back(e);
}
}

View File

@@ -877,18 +877,18 @@ bool beginsWithDotStar(const NGHolder &g) {
// We can ignore the successors of start, as matches that begin there will
// necessarily have a SOM of 0.
set<NFAVertex> succ;
insert(&succ, adjacent_vertices(g.startDs, g));
succ.erase(g.startDs);
set<NFAVertex> a_succ;
insert(&a_succ, adjacent_vertices(g.startDs, g));
a_succ.erase(g.startDs);
for (auto v : succ) {
for (auto v : a_succ) {
// We want 'dot' states that aren't virtual starts.
if (g[v].char_reach.all() &&
!g[v].assert_flags) {
hasDot = true;
set<NFAVertex> dotsucc;
insert(&dotsucc, adjacent_vertices(v, g));
if (dotsucc != succ) {
if (dotsucc != a_succ) {
DEBUG_PRINTF("failed dot-star succ check\n");
return false;
}
@@ -1178,7 +1178,7 @@ void expandGraph(NGHolder &g, unordered_map<NFAVertex, u32> &regions,
}
static
bool doTreePlanningIntl(NGHolder &g,
bool doTreePlanningIntl(const NGHolder &g,
const unordered_map<NFAVertex, u32> &regions,
const map<u32, region_info> &info,
map<u32, region_info>::const_iterator picked, u32 bad_region,
@@ -1293,8 +1293,8 @@ bool doTreePlanningIntl(NGHolder &g,
DEBUG_PRINTF("add mapped reporters for region %u\n", it->first);
addMappedReporterVertices(it->second, g, copy_to_orig,
plan.back().reporters);
} while (it->second.optional && it != info.rend() &&
(++it)->first > furthest->first);
} while (it != info.rend() && it->second.optional &&
(++it)->first > furthest->first);
return true;
}
@@ -1409,7 +1409,7 @@ bool doSomPlanning(NGHolder &g, bool stuck_in,
/* Need to verify how far the lock covers */
u32 bad_region;
NGHolder *ap_pref = plan.back().prefix.get();
const NGHolder *ap_pref = plan.back().prefix.get();
NGHolder ap_temp;
if (hasBigCycles(*ap_pref)) {
fillRoughMidfix(&ap_temp, g, regions, info, picked);
@@ -1552,7 +1552,7 @@ bool doSomPlanning(NGHolder &g, bool stuck_in,
DEBUG_PRINTF("region %u contributes reporters to last plan\n",
it->first);
addReporterVertices(it->second, g, plan.back().reporters);
} while (it->second.optional && it != info.rend() &&
} while (it != info.rend() && it->second.optional &&
(++it)->first > furthest->first);
DEBUG_PRINTF("done!\n");
@@ -1856,7 +1856,7 @@ bool doSomRevNfa(NG &ng, NGHolder &g, const CompileContext &cc) {
}
static
u32 doSomRevNfaPrefix(NG &ng, const ExpressionInfo &expr, NGHolder &g,
u32 doSomRevNfaPrefix(NG &ng, const ExpressionInfo &expr, const NGHolder &g,
const CompileContext &cc) {
depth maxWidth = findMaxWidth(g);
@@ -2012,7 +2012,7 @@ void setReportOnHaigPrefix(RoseBuild &rose, NGHolder &h) {
}
static
bool tryHaig(RoseBuild &rose, NGHolder &g,
bool tryHaig(RoseBuild &rose, const NGHolder &g,
const unordered_map<NFAVertex, u32> &regions,
som_type som, u32 somPrecision,
map<u32, region_info>::const_iterator picked,
@@ -2444,13 +2444,9 @@ void makeReportsSomPass(ReportManager &rm, NGHolder &g) {
}
static
bool doLitHaigSom(NG &ng, NGHolder &g, som_type som) {
bool doLitHaigSom(NG &ng, const NGHolder &g, som_type som) {
ue2_literal lit;
shared_ptr<NGHolder> rhs = make_shared<NGHolder>();
if (!rhs) {
assert(0);
throw std::bad_alloc();
}
if (!ng.cc.grey.allowLitHaig) {
return false;
}
@@ -2515,10 +2511,6 @@ bool doHaigLitHaigSom(NG &ng, NGHolder &g,
ue2_literal lit;
shared_ptr<NGHolder> rhs = make_shared<NGHolder>();
shared_ptr<NGHolder> lhs = make_shared<NGHolder>();
if (!rhs || !lhs) {
assert(0);
throw std::bad_alloc();
}
if (!splitOffBestLiteral(g, regions, &lit, &*lhs, &*rhs, ng.cc)) {
return false;
@@ -2661,7 +2653,7 @@ bool doHaigLitHaigSom(NG &ng, NGHolder &g,
}
static
bool doMultiLitHaigSom(NG &ng, NGHolder &g, som_type som) {
bool doMultiLitHaigSom(NG &ng, const NGHolder &g, som_type som) {
set<ue2_literal> lits;
shared_ptr<NGHolder> rhs = make_shared<NGHolder>();
if (!ng.cc.grey.allowLitHaig) {
@@ -3135,7 +3127,7 @@ sombe_rv doSomWithHaig(NG &ng, NGHolder &g, const ExpressionInfo &expr,
// try a redundancy pass.
if (addSomRedundancy(g, depths)) {
depths = getDistancesFromSOM(g);
depths = getDistancesFromSOM(g); // cppcheck-suppress unreadVariable
}
auto regions = assignRegions(g);

View File

@@ -113,9 +113,9 @@ bool forkVertex(NFAVertex v, NGHolder &g, vector<DepthMinMax> &depths,
}
*numNewVertices += predGroups.size();
for (auto &group : predGroups) {
for (const auto &group : predGroups) {
const depth &predDepth = group.first;
const vector<NFAEdge> &preds = group.second;
const vector<NFAEdge> &gspreds = group.second;
// Clone v for this depth with all its associated out-edges.
u32 clone_idx = depths.size(); // next index to be used
@@ -131,8 +131,8 @@ bool forkVertex(NFAVertex v, NGHolder &g, vector<DepthMinMax> &depths,
add_edge(clone, target(e, g), g[e], g);
}
// Add in-edges from preds in this group.
for (const auto &e : preds) {
// Add in-edges from gspreds in this group.
for (const auto &e : gspreds) {
add_edge(source(e, g), clone, g[e], g);
}
}

View File

@@ -58,11 +58,12 @@ vector<DepthMinMax> getDistancesFromSOM(const NGHolder &g_orig) {
cloneHolder(g, g_orig, &vmap);
vector<NFAVertex> vstarts;
for (auto v : vertices_range(g)) {
if (is_virtual_start(v, g)) {
vstarts.emplace_back(v);
}
}
auto vstart = [&g=g](const NFAVertex &v) {
return (is_virtual_start(v, g));
};
const auto &vr = vertices_range(g);
std::copy_if(begin(vr), end(vr), std::back_inserter(vstarts), vstart);
vstarts.emplace_back(g.startDs);
// wire the successors of every virtual start or startDs to g.start.
@@ -269,18 +270,6 @@ bool somMayGoBackwards(NFAVertex u, const NGHolder &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 %zu %zu\n", c_g[s].index, c_g[t].index);
if (s != t) {
assert(0);
DEBUG_PRINTF("eek big cycle\n");
rv = true; /* big cycle -> eek */
goto exit;
}
}
DEBUG_PRINTF("checking acyclic+selfloop graph\n");
rv = !firstMatchIsFirst(c_g);

View File

@@ -151,7 +151,8 @@ void splitRHS(const NGHolder &base, const vector<NFAVertex> &pivots,
for (auto pivot : pivots) {
assert(contains(*rhs_map, pivot));
NFAEdge e = add_edge(rhs->start, (*rhs_map)[pivot], *rhs);
auto edge_result = add_edge(rhs->start, (*rhs_map)[pivot], *rhs);
NFAEdge e = edge_result.first;
(*rhs)[e].tops.insert(DEFAULT_TOP);
}

View File

@@ -255,19 +255,19 @@ void buildSquashMask(NFAStateSet &mask, const NGHolder &g, NFAVertex v,
}
static
void buildSucc(NFAStateSet &succ, const NGHolder &g, NFAVertex v) {
void buildSucc(NFAStateSet &ssucc, const NGHolder &g, NFAVertex v) {
for (auto w : adjacent_vertices_range(v, g)) {
if (!is_special(w, g)) {
succ.set(g[w].index);
ssucc.set(g[w].index);
}
}
}
static
void buildPred(NFAStateSet &pred, const NGHolder &g, NFAVertex v) {
void buildPred(NFAStateSet &spred, const NGHolder &g, NFAVertex v) {
for (auto u : inv_adjacent_vertices_range(v, g)) {
if (!is_special(u, g)) {
pred.set(g[u].index);
spred.set(g[u].index);
}
}
}
@@ -409,19 +409,19 @@ unordered_map<NFAVertex, NFAStateSet> findSquashers(const NGHolder &g,
DEBUG_PRINTF("state %u is cyclic\n", i);
NFAStateSet mask(numStates), succ(numStates), pred(numStates);
NFAStateSet mask(numStates), ssucc(numStates), spred(numStates);
buildSquashMask(mask, g, v, cr, initStates, vByIndex, pdom_tree, som,
som_depths, region_map, cache);
buildSucc(succ, g, v);
buildPred(pred, g, v);
buildSucc(ssucc, g, v);
buildPred(spred, g, v);
const auto &reports = g[v].reports;
for (size_t j = succ.find_first(); j != succ.npos;
j = succ.find_next(j)) {
for (size_t j = ssucc.find_first(); j != ssucc.npos;
j = ssucc.find_next(j)) {
NFAVertex vj = vByIndex[j];
NFAStateSet pred2(numStates);
buildPred(pred2, g, vj);
if (pred2 == pred) {
if (pred2 == spred) {
DEBUG_PRINTF("adding the sm from %zu to %u's sm\n", j, i);
NFAStateSet tmp(numStates);
buildSquashMask(tmp, g, vj, cr, initStates, vByIndex, pdom_tree,
@@ -430,14 +430,14 @@ unordered_map<NFAVertex, NFAStateSet> findSquashers(const NGHolder &g,
}
}
for (size_t j = pred.find_first(); j != pred.npos;
j = pred.find_next(j)) {
for (size_t j = spred.find_first(); j != spred.npos;
j = spred.find_next(j)) {
NFAVertex vj = vByIndex[j];
NFAStateSet succ2(numStates);
buildSucc(succ2, g, vj);
/* we can use j as a basis for squashing if its succs are a subset
* of ours */
if ((succ2 & ~succ).any()) {
if ((succ2 & ~ssucc).any()) {
continue;
}
@@ -590,7 +590,7 @@ void getHighlanderReporters(const NGHolder &g, const NFAVertex accept,
verts.insert(v);
next_vertex:
continue;
;
}
}

View File

@@ -196,10 +196,11 @@ u32 commonPrefixLength(const NGHolder &ga, const ranking_info &a_ranking,
}
a_count++;
NFAEdge b_edge;
bool b_edge_bool;
std::tie(b_edge, b_edge_bool) = edge(b_ranking.at(i), b_ranking.at(sid), gb);
NFAEdge b_edge = edge(b_ranking.at(i), b_ranking.at(sid), gb);
if (!b_edge) {
if (!b_edge_bool) {
max = i;
DEBUG_PRINTF("lowering max to %u due to edge %zu->%u\n",
max, i, sid);
@@ -319,7 +320,7 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
DEBUG_PRINTF("skipping common edge\n");
assert(edge(u, v, dest).second);
// Should never merge edges with different top values.
assert(vic[e].tops == dest[edge(u, v, dest)].tops);
assert(vic[e].tops == dest[edge(u, v, dest).first].tops);
continue;
} else {
assert(is_any_accept(v, dest));
@@ -454,8 +455,8 @@ void buildNfaMergeQueue(const vector<NGHolder *> &cluster,
}
}
NGHolder &g_i = *(cluster[ci]);
NGHolder &g_j = *(cluster[cj]);
const NGHolder &g_i = *(cluster[ci]);
const NGHolder &g_j = *(cluster[cj]);
if (!compatibleStarts(g_i, g_j)) {
continue;
@@ -505,16 +506,26 @@ bool mergeableStarts(const NGHolder &h1, const NGHolder &h2) {
/* TODO: relax top checks if reports match */
// If both graphs have edge (start, accept), the tops must match.
NFAEdge e1_accept = edge(h1.start, h1.accept, h1);
NFAEdge e2_accept = edge(h2.start, h2.accept, h2);
if (e1_accept && e2_accept && h1[e1_accept].tops != h2[e2_accept].tops) {
bool bool_e1_accept;
NFAEdge e1_accept;
NFAEdge e2_accept;
std::tie(e1_accept, bool_e1_accept) = edge(h1.start, h1.accept, h1);
bool bool_e2_accept;
std::tie(e2_accept, bool_e2_accept) = edge(h2.start, h2.accept, h2);
if (bool_e1_accept && bool_e2_accept && h1[e1_accept].tops != h2[e2_accept].tops) {
return false;
}
// If both graphs have edge (start, acceptEod), the tops must match.
NFAEdge e1_eod = edge(h1.start, h1.acceptEod, h1);
NFAEdge e2_eod = edge(h2.start, h2.acceptEod, h2);
if (e1_eod && e2_eod && h1[e1_eod].tops != h2[e2_eod].tops) {
bool bool_e1_eod;
NFAEdge e1_eod;
NFAEdge e2_eod;
std::tie(e1_eod, bool_e1_eod) = edge(h1.start, h1.acceptEod, h1);
bool bool_e2_eod;
std::tie(e2_eod, bool_e2_eod) = edge(h2.start, h2.acceptEod, h2);
if (bool_e1_eod && bool_e2_eod && h1[e1_eod].tops != h2[e2_eod].tops) {
return false;
}

View File

@@ -128,7 +128,7 @@ void clone_out_edges(NGHolder &g, NFAVertex source, NFAVertex dest) {
if (edge(dest, t, g).second) {
continue;
}
NFAEdge clone = add_edge(dest, t, g);
NFAEdge clone = add_edge(dest, t, g).first;
u32 idx = g[clone].index;
g[clone] = g[e];
g[clone].index = idx;
@@ -139,7 +139,7 @@ void clone_in_edges(NGHolder &g, NFAVertex s, NFAVertex dest) {
for (const auto &e : in_edges_range(s, g)) {
NFAVertex ss = source(e, g);
assert(!edge(ss, dest, g).second);
NFAEdge clone = add_edge(ss, dest, g);
NFAEdge clone = add_edge(ss, dest, g).first;
u32 idx = g[clone].index;
g[clone] = g[e];
g[clone].index = idx;
@@ -282,9 +282,11 @@ bool can_only_match_at_eod(const NGHolder &g) {
}
bool matches_everywhere(const NGHolder &h) {
NFAEdge e = edge(h.startDs, h.accept, h);
bool bool_e;
NFAEdge e;
std::tie(e, bool_e) = edge(h.startDs, h.accept, h);
return e && !h[e].assert_flags;
return bool_e && !h[e].assert_flags;
}
bool is_virtual_start(NFAVertex v, const NGHolder &g) {
@@ -409,9 +411,10 @@ void appendLiteral(NGHolder &h, const ue2_literal &s) {
DEBUG_PRINTF("adding '%s' to graph\n", dumpString(s).c_str());
vector<NFAVertex> tail;
assert(in_degree(h.acceptEod, h) == 1);
for (auto v : inv_adjacent_vertices_range(h.accept, h)) {
tail.emplace_back(v);
}
const auto &vr = inv_adjacent_vertices_range(h.accept, h);
std::copy(begin(vr), end(vr), std::back_inserter(tail));
assert(!tail.empty());
for (auto v : tail) {
@@ -572,7 +575,7 @@ void cloneHolder(NGHolder &out, const NGHolder &in) {
NFAVertex s = out_mapping[si];
NFAVertex t = out_mapping[ti];
NFAEdge e2 = add_edge(s, t, out);
NFAEdge e2 = add_edge(s, t, out).first;
out[e2] = in[e];
}
@@ -713,16 +716,16 @@ u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
assert(delay <= lit.length());
DEBUG_PRINTF("managed delay %u (of max %u)\n", delay, max_delay);
set<NFAVertex> pred;
set<NFAVertex> predv;
for (auto v : curr) {
insert(&pred, inv_adjacent_vertices_range(v, g));
insert(&predv, inv_adjacent_vertices_range(v, g));
}
clear_in_edges(g.accept, g);
clearReports(g);
for (auto v : pred) {
NFAEdge e = add_edge(v, g.accept, g);
for (auto v : predv) {
NFAEdge e = add_edge(v, g.accept, g).first;
g[v].reports.insert(0);
if (is_triggered(g) && v == g.start) {
g[e].tops.insert(DEFAULT_TOP);

View File

@@ -314,7 +314,7 @@ void duplicateReport(NGHolder &g, ReportID r_old, ReportID r_new);
/** Construct a reversed copy of an arbitrary NGHolder, mapping starts to
* accepts. */
void reverseHolder(const NGHolder &g, NGHolder &out);
void reverseHolder(const NGHolder &g_in, NGHolder &g);
/** \brief Returns the delay or ~0U if the graph cannot match with
* the trailing literal. */

View File

@@ -354,10 +354,9 @@ void getSimpleRoseLiterals(const NGHolder &g, bool seeking_anchored,
map<NFAVertex, u64a> scores;
map<NFAVertex, unique_ptr<VertLitInfo>> lit_info;
set<ue2_literal> s;
for (auto v : a_dom) {
s = getLiteralSet(g, v, true); /* RHS will take responsibility for any
set<ue2_literal> s = getLiteralSet(g, v, true); /* RHS will take responsibility for any
revisits to the target vertex */
if (s.empty()) {
@@ -695,7 +694,7 @@ unique_ptr<VertLitInfo> findBestSplit(const NGHolder &g,
}
if (seeking_transient) {
for (auto &a : lits) {
for (const auto &a : lits) {
a->creates_transient
= createsTransientLHS(g, a->vv, *depths, cc.grey);
}
@@ -704,20 +703,20 @@ unique_ptr<VertLitInfo> findBestSplit(const NGHolder &g,
if (last_chance) {
const size_t num_verts = num_vertices(g);
auto color_map = make_small_color_map(g);
for (auto &a : lits) {
for (const auto &a : lits) {
size_t num_reachable = count_reachable(g, a->vv, color_map);
double ratio = (double)num_reachable / (double)num_verts;
a->split_ratio = ratio > 0.5 ? 1 - ratio : ratio;
}
}
auto cmp = LitComparator(g, seeking_anchored, seeking_transient,
auto lcmp = LitComparator(g, seeking_anchored, seeking_transient,
last_chance);
unique_ptr<VertLitInfo> best = std::move(lits.back());
lits.pop_back();
while (!lits.empty()) {
if (cmp(best, lits.back())) {
if (lcmp(best, lits.back())) {
best = std::move(lits.back());
}
lits.pop_back();
@@ -819,7 +818,7 @@ flat_set<NFAEdge> poisonEdges(const NGHolder &h,
/* poison edges covered by successor literal */
set<pair<ue2_literal, bool> > succs;
set<pair<ue2_literal, bool> > lsuccs;
for (const RoseInEdge &ve : ee) {
if (vg[target(ve, vg)].type != RIV_LITERAL) {
/* nothing to poison in suffixes/outfixes */
@@ -827,15 +826,15 @@ flat_set<NFAEdge> poisonEdges(const NGHolder &h,
assert(is_any_accept_type(vg[target(ve, vg)].type));
continue;
}
succs.insert({vg[target(ve, vg)].s,
lsuccs.insert({vg[target(ve, vg)].s,
vg[source(ve, vg)].type == RIV_LITERAL});
}
DEBUG_PRINTF("poisoning edges %zu successor literals\n", succs.size());
DEBUG_PRINTF("poisoning edges %zu successor literals\n", lsuccs.size());
flat_set<NFAEdge> bad;
for (const auto &p : succs) {
for (const auto &p : lsuccs) {
poisonFromSuccessor(h, p.first, p.second, bad);
}
@@ -1043,11 +1042,6 @@ bool splitRoseEdge(const NGHolder &base_graph, RoseInGraph &vg,
shared_ptr<NGHolder> lhs = make_shared<NGHolder>();
shared_ptr<NGHolder> rhs = make_shared<NGHolder>();
if (!lhs || !rhs) {
assert(0);
throw std::bad_alloc();
}
unordered_map<NFAVertex, NFAVertex> lhs_map;
unordered_map<NFAVertex, NFAVertex> rhs_map;
@@ -1179,7 +1173,7 @@ bool splitRoseEdge(const NGHolder &base_graph, RoseInGraph &vg,
#define MAX_LEN_2_LITERALS_PER_CUT 3
static
bool checkValidNetflowLits(NGHolder &h, const vector<u64a> &scores,
bool checkValidNetflowLits(const NGHolder &h, const vector<u64a> &scores,
const map<NFAEdge, set<ue2_literal>> &cut_lits,
u32 min_allowed_length) {
DEBUG_PRINTF("cut width %zu; min allowed %u\n", cut_lits.size(),
@@ -1217,7 +1211,7 @@ bool checkValidNetflowLits(NGHolder &h, const vector<u64a> &scores,
}
static
void splitEdgesByCut(NGHolder &h, RoseInGraph &vg,
void splitEdgesByCut(const NGHolder &h, RoseInGraph &vg,
const vector<RoseInEdge> &to_cut,
const vector<NFAEdge> &cut,
const map<NFAEdge, set<ue2_literal>> &cut_lits) {
@@ -1242,17 +1236,14 @@ void splitEdgesByCut(NGHolder &h, RoseInGraph &vg,
DEBUG_PRINTF("splitting on pivot %zu\n", h[pivot].index);
unordered_map<NFAVertex, NFAVertex> temp_map;
shared_ptr<NGHolder> new_lhs = make_shared<NGHolder>();
if (!new_lhs) {
assert(0);
throw std::bad_alloc();
}
splitLHS(h, pivot, new_lhs.get(), &temp_map);
/* want to cut off paths to pivot from things other than the pivot -
* makes a more svelte graphy */
clear_in_edges(temp_map[pivot], *new_lhs);
NFAEdge pivot_edge = add_edge(temp_map[prev_v], temp_map[pivot],
*new_lhs);
*new_lhs).first;
if (is_triggered(h) && prev_v == h.start) {
(*new_lhs)[pivot_edge].tops.insert(DEFAULT_TOP);
}
@@ -1327,10 +1318,7 @@ void splitEdgesByCut(NGHolder &h, RoseInGraph &vg,
if (!contains(done_rhs, adj)) {
unordered_map<NFAVertex, NFAVertex> temp_map;
shared_ptr<NGHolder> new_rhs = make_shared<NGHolder>();
if (!new_rhs) {
assert(0);
throw std::bad_alloc();
}
splitRHS(h, adj, new_rhs.get(), &temp_map);
remove_edge(new_rhs->start, new_rhs->accept, *new_rhs);
remove_edge(new_rhs->start, new_rhs->acceptEod, *new_rhs);
@@ -1442,11 +1430,11 @@ bool deanchorIfNeeded(NGHolder &g) {
if (succ_v == succ_g) {
DEBUG_PRINTF("found ^.*\n");
for (auto succ : adjacent_vertices_range(g.start, g)) {
if (succ == g.startDs) {
for (auto asucc : adjacent_vertices_range(g.start, g)) {
if (asucc == g.startDs) {
continue;
}
add_edge(g.startDs, succ, g);
add_edge(g.startDs, asucc, g);
}
clear_vertex(v, g);
remove_vertex(v, g);
@@ -1693,18 +1681,18 @@ void removeRedundantLiteralsFromInfix(const NGHolder &h, RoseInGraph &ig,
* successor literal. This would require using distinct report ids and also
* taking into account overlap of successor literals. */
set<ue2_literal> preds;
set<ue2_literal> succs;
set<ue2_literal> lpreds;
set<ue2_literal> lsuccs;
for (const RoseInEdge &e : ee) {
RoseInVertex u = source(e, ig);
assert(ig[u].type == RIV_LITERAL);
assert(!ig[u].delay);
preds.insert(ig[u].s);
lpreds.insert(ig[u].s);
RoseInVertex v = target(e, ig);
assert(ig[v].type == RIV_LITERAL);
assert(!ig[v].delay);
succs.insert(ig[v].s);
lsuccs.insert(ig[v].s);
if (ig[e].graph_lag) {
/* already removed redundant parts of literals */
@@ -1716,9 +1704,9 @@ void removeRedundantLiteralsFromInfix(const NGHolder &h, RoseInGraph &ig,
map<ue2_literal, pair<shared_ptr<NGHolder>, u32> > graphs; /* + delay */
for (const ue2_literal &right : succs) {
for (const ue2_literal &right : lsuccs) {
size_t max_overlap = 0;
for (const ue2_literal &left : preds) {
for (const ue2_literal &left : lpreds) {
size_t overlap = maxOverlap(left, right, 0);
ENSURE_AT_LEAST(&max_overlap, overlap);
}
@@ -1755,13 +1743,13 @@ void removeRedundantLiteralsFromInfix(const NGHolder &h, RoseInGraph &ig,
for (const RoseInEdge &e : ee) {
RoseInVertex v = target(e, ig);
const ue2_literal &succ = ig[v].s;
if (!contains(graphs, succ)) {
const ue2_literal &igsucc = ig[v].s;
if (!contains(graphs, igsucc)) {
continue;
}
ig[e].graph = graphs[succ].first;
ig[e].graph_lag = graphs[succ].second;
ig[e].graph = graphs[igsucc].first;
ig[e].graph_lag = graphs[igsucc].second;
if (isStarCliche(*ig[e].graph)) {
DEBUG_PRINTF("is a X star!\n");
@@ -1800,9 +1788,9 @@ void removeRedundantLiteralsFromInfixes(RoseInGraph &g,
}
for (const auto &m : infixes) {
NGHolder *h = m.first;
const auto &edges = m.second;
removeRedundantLiteralsFromInfix(*h, g, edges, cc);
const NGHolder *h = m.first;
const auto &medges = m.second;
removeRedundantLiteralsFromInfix(*h, g, medges, cc);
}
}
@@ -1813,7 +1801,7 @@ void removeRedundantLiterals(RoseInGraph &g, const CompileContext &cc) {
}
static
RoseInVertex getStart(RoseInGraph &vg) {
RoseInVertex getStart(const RoseInGraph &vg) {
for (RoseInVertex v : vertices_range(vg)) {
// cppcheck-suppress useStlAlgorithm
if (vg[v].type == RIV_START || vg[v].type == RIV_ANCHORED_START) {
@@ -1880,7 +1868,7 @@ unique_ptr<NGHolder> make_chain(u32 count) {
#define SHORT_TRIGGER_LEN 16
static
bool makeTransientFromLongLiteral(NGHolder &h, RoseInGraph &vg,
bool makeTransientFromLongLiteral(const NGHolder &h, RoseInGraph &vg,
const vector<RoseInEdge> &ee,
const CompileContext &cc) {
/* check max width and literal lengths to see if possible */
@@ -1963,7 +1951,7 @@ bool makeTransientFromLongLiteral(NGHolder &h, RoseInGraph &vg,
static
void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 delay, const vector<NFAVertex> &preds) {
u32 delay, const vector<NFAVertex> &lpreds) {
assert(delay <= lit.length());
assert(isCorrectlyTopped(g));
DEBUG_PRINTF("adding on '%s' %u\n", dumpString(lit).c_str(), delay);
@@ -1979,8 +1967,8 @@ void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
prev = curr;
}
for (auto v : preds) {
NFAEdge e = add_edge_if_not_present(v, prev, g);
for (auto v : lpreds) {
NFAEdge e = add_edge_if_not_present(v, prev, g).first;
if (v == g.start && is_triggered(g)) {
g[e].tops.insert(DEFAULT_TOP);
}
@@ -1998,11 +1986,11 @@ void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
static
void restoreTrailingLiteralStates(NGHolder &g,
const vector<pair<ue2_literal, u32>> &lits) {
vector<NFAVertex> preds;
insert(&preds, preds.end(), inv_adjacent_vertices(g.accept, g));
vector<NFAVertex> vpreds;
insert(&vpreds, vpreds.end(), inv_adjacent_vertices(g.accept, g));
clear_in_edges(g.accept, g);
for (auto v : preds) {
for (auto v : vpreds) {
g[v].reports.clear(); /* clear report from old accepts */
}
@@ -2010,7 +1998,7 @@ void restoreTrailingLiteralStates(NGHolder &g,
const ue2_literal &lit = p.first;
u32 delay = p.second;
restoreTrailingLiteralStates(g, lit, delay, preds);
restoreTrailingLiteralStates(g, lit, delay, vpreds);
}
}
@@ -2144,14 +2132,14 @@ void findBetterPrefixes(RoseInGraph &vg, const CompileContext &cc) {
/* look for bad prefixes and try to split */
for (const auto &m : prefixes) {
NGHolder *h = m.first;
const auto &edges = m.second;
const auto &medges = m.second;
depth max_width = findMaxWidth(*h);
if (willBeTransient(max_width, cc)
|| willBeAnchoredTable(max_width, cc.grey)) {
continue;
}
changed = improvePrefix(*h, vg, edges, cc);
changed = improvePrefix(*h, vg, medges, cc);
}
} while (changed && gen++ < MAX_FIND_BETTER_PREFIX_GEN);
}
@@ -2160,7 +2148,7 @@ void findBetterPrefixes(RoseInGraph &vg, const CompileContext &cc) {
#define MAX_EXTRACT_STRONG_LITERAL_GRAPHS 10
static
bool extractStrongLiteral(NGHolder &h, RoseInGraph &vg,
bool extractStrongLiteral(const NGHolder &h, RoseInGraph &vg,
const vector<RoseInEdge> &ee,
const CompileContext &cc) {
DEBUG_PRINTF("looking for string literal\n");
@@ -2208,12 +2196,12 @@ void extractStrongLiterals(RoseInGraph &vg, const CompileContext &cc) {
for (const auto &m : edges_by_graph) {
NGHolder *g = m.first;
const auto &edges = m.second;
const auto &medges = m.second;
if (contains(stuck, g)) {
DEBUG_PRINTF("already known to be bad\n");
continue;
}
bool rv = extractStrongLiteral(*g, vg, edges, cc);
bool rv = extractStrongLiteral(*g, vg, medges, cc);
if (rv) {
changed = true;
} else {
@@ -2291,8 +2279,8 @@ void improveWeakInfixes(RoseInGraph &vg, const CompileContext &cc) {
for (const auto &m : weak_edges) {
NGHolder *h = m.first;
const auto &edges = m.second;
improveInfix(*h, vg, edges, cc);
const auto &medges = m.second;
improveInfix(*h, vg, medges, cc);
}
}
@@ -2304,10 +2292,7 @@ void splitEdgesForSuffix(const NGHolder &base_graph, RoseInGraph &vg,
assert(!splitters.empty());
shared_ptr<NGHolder> lhs = make_shared<NGHolder>();
if (!lhs) {
assert(0);
throw bad_alloc();
}
unordered_map<NFAVertex, NFAVertex> v_map;
cloneHolder(*lhs, base_graph, &v_map);
lhs->kind = NFA_INFIX;
@@ -2316,7 +2301,7 @@ void splitEdgesForSuffix(const NGHolder &base_graph, RoseInGraph &vg,
add_edge(lhs->accept, lhs->acceptEod, *lhs);
clearReports(*lhs);
for (NFAVertex v : splitters) {
NFAEdge e = add_edge(v_map[v], lhs->accept, *lhs);
NFAEdge e = add_edge(v_map[v], lhs->accept, *lhs).first;
if (v == base_graph.start) {
(*lhs)[e].tops.insert(DEFAULT_TOP);
}
@@ -2417,14 +2402,14 @@ bool replaceSuffixWithInfix(const NGHolder &h, RoseInGraph &vg,
assert(!by_reports.empty());
/* TODO: how strong a min len do we want here ? */
u32 min_len = cc.grey.minRoseLiteralLength;
ENSURE_AT_LEAST(&min_len, MIN_SUFFIX_LEN);
u32 rose_min_len = cc.grey.minRoseLiteralLength;
ENSURE_AT_LEAST(&rose_min_len, MIN_SUFFIX_LEN);
for (auto &vli : by_reports | map_values) {
u64a score = sanitizeAndCompressAndScore(vli.lit);
if (vli.lit.empty()
|| !validateRoseLiteralSetQuality(vli.lit, score, false, min_len,
|| !validateRoseLiteralSetQuality(vli.lit, score, false, rose_min_len,
false, false)) {
return false;
}
@@ -2468,8 +2453,8 @@ void avoidSuffixes(RoseInGraph &vg, const CompileContext &cc) {
/* look at suffixes and try to split */
for (const auto &m : suffixes) {
const NGHolder *h = m.first;
const auto &edges = m.second;
replaceSuffixWithInfix(*h, vg, edges, cc);
const auto &medges = m.second;
replaceSuffixWithInfix(*h, vg, medges, cc);
}
}
@@ -2563,8 +2548,8 @@ void lookForDoubleCut(RoseInGraph &vg, const CompileContext &cc) {
for (const auto &m : right_edges) {
const NGHolder *h = m.first;
const auto &edges = m.second;
lookForDoubleCut(*h, edges, vg, cc.grey);
const auto &medges = m.second;
lookForDoubleCut(*h, medges, vg, cc.grey);
}
}
@@ -2755,8 +2740,8 @@ void lookForCleanEarlySplits(RoseInGraph &vg, const CompileContext &cc) {
for (const auto &m : rightfixes) {
const NGHolder *h = m.first;
const auto &edges = m.second;
lookForCleanSplit(*h, edges, vg, cc);
const auto &medges = m.second;
lookForCleanSplit(*h, medges, vg, cc);
}
prev = std::move(curr);
@@ -2815,7 +2800,7 @@ bool tryForEarlyDfa(const NGHolder &h, const CompileContext &cc) {
}
static
vector<vector<CharReach>> getDfaTriggers(RoseInGraph &vg,
vector<vector<CharReach>> getDfaTriggers(const RoseInGraph &vg,
const vector<RoseInEdge> &edges,
bool *single_trigger) {
vector<vector<CharReach>> triggers;
@@ -2879,7 +2864,6 @@ static
bool splitForImplementability(RoseInGraph &vg, NGHolder &h,
const vector<RoseInEdge> &edges,
const CompileContext &cc) {
vector<pair<ue2_literal, u32>> succ_lits;
DEBUG_PRINTF("trying to split %s with %zu vertices on %zu edges\n",
to_string(h.kind).c_str(), num_vertices(h), edges.size());
@@ -2888,6 +2872,7 @@ bool splitForImplementability(RoseInGraph &vg, NGHolder &h,
}
if (!generates_callbacks(h)) {
vector<pair<ue2_literal, u32>> succ_lits;
for (const auto &e : edges) {
const auto &lit = vg[target(e, vg)].s;
u32 delay = vg[e].graph_lag;
@@ -2900,8 +2885,8 @@ bool splitForImplementability(RoseInGraph &vg, NGHolder &h,
}
unique_ptr<VertLitInfo> split;
bool last_chance = true;
if (h.kind == NFA_PREFIX) {
bool last_chance = true;
auto depths = calcDepths(h);
split = findBestPrefixSplit(h, depths, vg, edges, last_chance, cc);
@@ -2938,7 +2923,7 @@ bool ensureImplementable(RoseBuild &rose, RoseInGraph &vg, bool allow_changes,
vector<RoseInEdge>> edges_by_graph;
for (const RoseInEdge &ve : edges_range(vg)) {
if (vg[ve].graph && !vg[ve].dfa) {
auto &h = vg[ve].graph;
const auto &h = vg[ve].graph;
edges_by_graph[h].emplace_back(ve);
}
}
@@ -2953,10 +2938,10 @@ bool ensureImplementable(RoseBuild &rose, RoseInGraph &vg, bool allow_changes,
continue;
}
const auto &edges = m.second;
const auto &medges = m.second;
if (tryForEarlyDfa(*h, cc) &&
doEarlyDfa(rose, vg, *h, edges, final_chance, rm, cc)) {
doEarlyDfa(rose, vg, *h, medges, final_chance, rm, cc)) {
continue;
}
@@ -2965,7 +2950,7 @@ bool ensureImplementable(RoseBuild &rose, RoseInGraph &vg, bool allow_changes,
return false;
}
if (splitForImplementability(vg, *h, edges, cc)) {
if (splitForImplementability(vg, *h, medges, cc)) {
added_count++;
if (added_count > MAX_IMPLEMENTABLE_SPLITS) {
DEBUG_PRINTF("added_count hit limit\n");