mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-09-30 03:34:25 +03:00
shift all early_dfa creation logic to ng_violet/ng_rose
This commit is contained in:
@@ -255,7 +255,7 @@ bool addComponent(NG &ng, NGHolder &g, const NGWrapper &w, const som_type som,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (splitOffRose(*ng.rose, g, w.prefilter, cc)) {
|
||||
if (splitOffRose(*ng.rose, g, w.prefilter, ng.rm, cc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ bool addComponent(NG &ng, NGHolder &g, const NGWrapper &w, const som_type som,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (splitOffRose(*ng.rose, g, w.prefilter, cc)) {
|
||||
if (splitOffRose(*ng.rose, g, w.prefilter, ng.rm, cc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ bool addComponent(NG &ng, NGHolder &g, const NGWrapper &w, const som_type som,
|
||||
}
|
||||
}
|
||||
|
||||
if (finalChanceRose(*ng.rose, g, w.prefilter, cc)) {
|
||||
if (finalChanceRose(*ng.rose, g, w.prefilter, ng.rm, cc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -533,16 +533,16 @@ bool NG::addHolder(NGHolder &w) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (splitOffRose(*rose, w, prefilter, cc)) {
|
||||
if (splitOffRose(*rose, w, prefilter, rm, cc)) {
|
||||
return true;
|
||||
}
|
||||
if (splitOffPuffs(*rose, rm, w, prefilter, cc)) {
|
||||
return true;
|
||||
}
|
||||
if (splitOffRose(*rose, w, prefilter, cc)) {
|
||||
if (splitOffRose(*rose, w, prefilter, rm, cc)) {
|
||||
return true;
|
||||
}
|
||||
if (finalChanceRose(*rose, w, prefilter, cc)) {
|
||||
if (finalChanceRose(*rose, w, prefilter, rm, cc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -48,6 +48,7 @@
|
||||
#include "ng_reports.h"
|
||||
#include "ng_split.h"
|
||||
#include "ng_util.h"
|
||||
#include "ng_violet.h"
|
||||
#include "ng_width.h"
|
||||
#include "rose/rose_build.h"
|
||||
#include "rose/rose_build_util.h"
|
||||
@@ -2833,8 +2834,19 @@ void desperationImprove(RoseInGraph &ig, const CompileContext &cc) {
|
||||
calcVertexOffsets(ig);
|
||||
}
|
||||
|
||||
static
|
||||
bool addRose(RoseBuild &rose, RoseInGraph &ig, bool prefilter,
|
||||
bool final_chance, const ReportManager &rm,
|
||||
const CompileContext &cc) {
|
||||
if (!ensureImplementable(rose, ig, false, final_chance, rm, cc)
|
||||
&& !prefilter) {
|
||||
return false;
|
||||
}
|
||||
return rose.addRose(ig, prefilter);
|
||||
}
|
||||
|
||||
bool splitOffRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
const CompileContext &cc) {
|
||||
const ReportManager &rm, const CompileContext &cc) {
|
||||
if (!cc.grey.allowRose) {
|
||||
return false;
|
||||
}
|
||||
@@ -2843,20 +2855,20 @@ bool splitOffRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
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)) {
|
||||
if (igp && addRose(rose, *igp, prefilter, false, rm, cc)) {
|
||||
goto ok;
|
||||
}
|
||||
|
||||
igp = buildRose(h, true, cc);
|
||||
|
||||
if (igp) {
|
||||
if (rose.addRose(*igp, prefilter)) {
|
||||
if (addRose(rose, *igp, prefilter, false, rm, cc)) {
|
||||
goto ok;
|
||||
}
|
||||
|
||||
desperationImprove(*igp, cc);
|
||||
|
||||
if (rose.addRose(*igp, prefilter)) {
|
||||
if (addRose(rose, *igp, prefilter, false, rm, cc)) {
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
@@ -2870,7 +2882,7 @@ ok:
|
||||
}
|
||||
|
||||
bool finalChanceRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
const CompileContext &cc) {
|
||||
const ReportManager &rm, const CompileContext &cc) {
|
||||
DEBUG_PRINTF("final chance rose\n");
|
||||
if (!cc.grey.allowRose) {
|
||||
return false;
|
||||
@@ -2935,7 +2947,7 @@ bool finalChanceRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
renumber_vertices(ig);
|
||||
calcVertexOffsets(ig);
|
||||
|
||||
return rose.addRose(ig, prefilter, true /* final chance */);
|
||||
return addRose(rose, ig, prefilter, true /* final chance */, rm, cc);
|
||||
}
|
||||
|
||||
bool checkRose(const ReportManager &rm, const NGHolder &h, bool prefilter,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
* Copyright (c) 2015-2017, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -50,13 +50,13 @@ struct ue2_literal;
|
||||
/** \brief Attempt to consume the entire pattern in graph \a h with Rose.
|
||||
* Returns true if successful. */
|
||||
bool splitOffRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
const CompileContext &cc);
|
||||
const ReportManager &rm, const CompileContext &cc);
|
||||
|
||||
/** \brief Attempt to consume the entire pattern in graph \a h with Rose.
|
||||
* This is the last attempt to handle a pattern before we resort to an outfix.
|
||||
* Returns true if successful. */
|
||||
bool finalChanceRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
const CompileContext &cc);
|
||||
const ReportManager &rm, const CompileContext &cc);
|
||||
|
||||
/** \brief True if the pattern in \a h is consumable by Rose. This function
|
||||
* may be conservative (return false even if supported) for efficiency. */
|
||||
|
@@ -2660,8 +2660,8 @@ vector<vector<CharReach>> getDfaTriggers(RoseInGraph &vg,
|
||||
|
||||
static
|
||||
bool doEarlyDfa(RoseBuild &rose, RoseInGraph &vg, NGHolder &h,
|
||||
const vector<RoseInEdge> &edges, const ReportManager &rm,
|
||||
const CompileContext &cc) {
|
||||
const vector<RoseInEdge> &edges, bool final_chance,
|
||||
const ReportManager &rm, const CompileContext &cc) {
|
||||
DEBUG_PRINTF("trying for dfa\n");
|
||||
|
||||
bool single_trigger;
|
||||
@@ -2680,7 +2680,7 @@ bool doEarlyDfa(RoseBuild &rose, RoseInGraph &vg, NGHolder &h,
|
||||
}
|
||||
|
||||
shared_ptr<raw_dfa> dfa = buildMcClellan(h, &rm, single_trigger, triggers,
|
||||
cc.grey);
|
||||
cc.grey, final_chance);
|
||||
|
||||
if (!dfa) {
|
||||
return false;
|
||||
@@ -2695,30 +2695,72 @@ bool doEarlyDfa(RoseBuild &rose, RoseInGraph &vg, NGHolder &h,
|
||||
}
|
||||
|
||||
static
|
||||
void ensureImplementable(RoseBuild &rose, RoseInGraph &vg,
|
||||
const ReportManager &rm, const CompileContext &cc) {
|
||||
map<const NGHolder *, vector<RoseInEdge> > edges_by_graph;
|
||||
vector<NGHolder *> graphs;
|
||||
for (const RoseInEdge &ve : edges_range(vg)) {
|
||||
if (vg[ve].graph) {
|
||||
NGHolder *h = vg[ve].graph.get();
|
||||
if (!contains(edges_by_graph, h)) {
|
||||
graphs.push_back(h);
|
||||
bool splitForImplemtabilty(UNUSED RoseInGraph &vg, UNUSED NGHolder &h,
|
||||
UNUSED const vector<RoseInEdge> &edges,
|
||||
UNUSED const CompileContext &cc) {
|
||||
/* TODO: need to add literals back to the graph? */
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MAX_IMPLEMENTABLE_SPLITS 200
|
||||
|
||||
bool ensureImplementable(RoseBuild &rose, RoseInGraph &vg, bool allow_changes,
|
||||
bool final_chance, const ReportManager &rm,
|
||||
const CompileContext &cc) {
|
||||
DEBUG_PRINTF("checking for impl\n");
|
||||
bool changed = false;
|
||||
u32 added_count = 0;
|
||||
do {
|
||||
map<const NGHolder *, vector<RoseInEdge> > edges_by_graph;
|
||||
vector<NGHolder *> graphs;
|
||||
for (const RoseInEdge &ve : edges_range(vg)) {
|
||||
if (vg[ve].graph) {
|
||||
NGHolder *h = vg[ve].graph.get();
|
||||
if (!contains(edges_by_graph, h)) {
|
||||
graphs.push_back(h);
|
||||
}
|
||||
edges_by_graph[h].push_back(ve);
|
||||
}
|
||||
edges_by_graph[h].push_back(ve);
|
||||
}
|
||||
}
|
||||
for (NGHolder *h : graphs) {
|
||||
if (isImplementableNFA(*h, &rm, cc)) {
|
||||
continue;
|
||||
for (NGHolder *h : graphs) {
|
||||
if (isImplementableNFA(*h, &rm, cc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tryForEarlyDfa(*h, cc)
|
||||
&& doEarlyDfa(rose, vg, *h, edges_by_graph[h], final_chance, rm,
|
||||
cc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("eek\n");
|
||||
if (!allow_changes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (splitForImplemtabilty(vg, *h, edges_by_graph[h], cc)) {
|
||||
added_count++;
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tryForEarlyDfa(*h, cc)
|
||||
&& doEarlyDfa(rose, vg, *h, edges_by_graph[h], rm, cc)) {
|
||||
continue;
|
||||
if (added_count > MAX_IMPLEMENTABLE_SPLITS) {
|
||||
return false;
|
||||
}
|
||||
DEBUG_PRINTF("eek\n");
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
removeRedundantLiterals(vg, cc);
|
||||
pruneUseless(vg);
|
||||
renumber_vertices(vg);
|
||||
calcVertexOffsets(vg);
|
||||
}
|
||||
} while (changed);
|
||||
|
||||
DEBUG_PRINTF("ok!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool doViolet(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
@@ -2779,9 +2821,10 @@ bool doViolet(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
|
||||
|
||||
/* Step 5: avoid unimplementable, or overly large engines if possible */
|
||||
if (last_chance) {
|
||||
ensureImplementable(rose, vg, rm, cc);
|
||||
if (!ensureImplementable(rose, vg, last_chance, last_chance, rm, cc)) {
|
||||
return false;
|
||||
}
|
||||
dumpPreRoseGraph(vg, cc.grey, "post_ensure_rose.dot");
|
||||
|
||||
/* Step 6: send to rose */
|
||||
bool rv = rose.addRose(vg, prefilter);
|
||||
|
@@ -42,6 +42,7 @@ class RoseBuild;
|
||||
|
||||
struct CompileContext;
|
||||
class ReportManager;
|
||||
struct RoseInGraph;
|
||||
|
||||
/** \brief Attempt to consume the entire pattern in graph \a h with Rose.
|
||||
* Returns true if successful. */
|
||||
@@ -49,6 +50,9 @@ bool doViolet(RoseBuild &rose, const NGHolder &h, bool prefilter,
|
||||
bool last_chance, const ReportManager &rm,
|
||||
const CompileContext &cc);
|
||||
|
||||
bool ensureImplementable(RoseBuild &rose, RoseInGraph &vg, bool allow_changes,
|
||||
bool final_chance, const ReportManager &rm,
|
||||
const CompileContext &cc);
|
||||
} // namespace ue2
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user