static bool hasOffsetAdjustments(const ReportManager &rm, const NGHolder &g) { for (auto report : all_reports(g)) { const Report &ir = rm.getReport(report); if (ir.offsetAdjust) { return true; } } return false; }
static bool hasOffsetAdjust(const ReportManager &rm, NGWrapper &g, int *adjust) { const auto &reports = all_reports(g); if (reports.empty()) { assert(0); return false; } int offsetAdjust = rm.getReport(*reports.begin()).offsetAdjust; for (auto report : reports) { const Report &ir = rm.getReport(report); if (ir.offsetAdjust != offsetAdjust) { DEBUG_PRINTF("different adjusts!\n"); return false; } } *adjust = offsetAdjust; return true; }
/** Remove any edges from vertices that generate accepts (for Highlander * graphs). */ void pruneHighlanderAccepts(NGHolder &g, const ReportManager &rm) { // Safety check: all reports must be simple exhaustible reports, or this is // not safe. This optimisation should be called early enough that no // internal reports have been added. for (auto report_id : all_reports(g)) { const Report &ir = rm.getReport(report_id); if (ir.ekey == INVALID_EKEY || ir.hasBounds() || !isExternalReport(ir)) { DEBUG_PRINTF("report %u is not external highlander with " "no bounds\n", report_id); return; } } vector<NFAEdge> dead; 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.push_back(e); } } } if (dead.empty()) { return; } DEBUG_PRINTF("found %zu removable edges due to single match\n", dead.size()); remove_edges(dead, g); pruneUseless(g); }
RoseDedupeAuxImpl::RoseDedupeAuxImpl(const RoseBuildImpl &build_in) : build(build_in) { const RoseGraph &g = build.g; set<suffix_id> suffixes; for (auto v : vertices_range(g)) { insert(&live_reports, g[v].reports); // Literals in the small block table are "shadow" copies of literals in // the other tables that do not run in the same runtime invocation. // Dedupe key assignment will be taken care of by the real literals. if (build.hasLiteralInTable(v, ROSE_ANCHORED_SMALL_BLOCK)) { for (const auto &report_id : g[v].reports) { sb_vert_map[report_id].insert(v); } } else { for (const auto &report_id : g[v].reports) { vert_map[report_id].insert(v); } } // Several vertices may share a suffix, so we collect the set of // suffixes first to avoid repeating work. if (g[v].suffix) { suffixes.insert(g[v].suffix); } } for (const auto &suffix : suffixes) { for (const auto &report_id : all_reports(suffix)) { suffix_map[report_id].insert(suffix); live_reports.insert(report_id); } } for (const auto &outfix : build.outfixes) { for (const auto &report_id : all_reports(outfix)) { outfix_map[report_id].insert(&outfix); live_reports.insert(report_id); } } if (build.mpv_outfix) { auto *mpv = build.mpv_outfix->mpv(); for (const auto &puff : mpv->puffettes) { puff_map[puff.report].insert(&puff); live_reports.insert(puff.report); } for (const auto &puff : mpv->triggered_puffettes) { puff_map[puff.report].insert(&puff); live_reports.insert(puff.report); } } // Collect live reports from boundary reports. insert(&live_reports, build.boundary.report_at_0); insert(&live_reports, build.boundary.report_at_0_eod); insert(&live_reports, build.boundary.report_at_eod); DEBUG_PRINTF("%zu of %zu reports are live\n", live_reports.size(), build.rm.numReports()); }