diff --git a/src/rose/rose_build_bytecode.cpp b/src/rose/rose_build_bytecode.cpp index e62c9e18..b0de73bc 100644 --- a/src/rose/rose_build_bytecode.cpp +++ b/src/rose/rose_build_bytecode.cpp @@ -2687,30 +2687,22 @@ void buildLeftInfoTable(const RoseBuildImpl &tbi, build_context &bc, static RoseProgram makeLiteralProgram(const RoseBuildImpl &build, build_context &bc, ProgramBuild &prog_build, u32 lit_id, - const map> &lit_edge_map, + const vector> &lit_edge_map, bool is_anchored_replay_program) { - const vector no_edges; - DEBUG_PRINTF("lit_id=%u\n", lit_id); - const vector *edges_ptr; - if (contains(lit_edge_map, lit_id)) { - edges_ptr = &lit_edge_map.at(lit_id); - } else { - /* literal may happen only in a delay context */ - edges_ptr = &no_edges; - } + assert(lit_id < lit_edge_map.size()); return makeLiteralProgram(build, bc.leftfix_info, bc.suffixes, - bc.engine_info_by_queue, - bc.roleStateIndices, prog_build, lit_id, - *edges_ptr, is_anchored_replay_program); + bc.engine_info_by_queue, bc.roleStateIndices, + prog_build, lit_id, lit_edge_map.at(lit_id), + is_anchored_replay_program); } static RoseProgram makeFragmentProgram(const RoseBuildImpl &build, build_context &bc, ProgramBuild &prog_build, const vector &lit_ids, - const map> &lit_edge_map) { + const vector> &lit_edge_map) { assert(!lit_ids.empty()); vector blocks; @@ -2728,28 +2720,27 @@ RoseProgram makeFragmentProgram(const RoseBuildImpl &build, build_context &bc, * vertices with that literal ID. */ static -map> findEdgesByLiteral(const RoseBuildImpl &build) { - // Use a set of edges while building the map to cull duplicates. - map> unique_lit_edge_map; +vector> findEdgesByLiteral(const RoseBuildImpl &build) { + vector> lit_edge_map(build.literals.size()); const auto &g = build.g; - for (const auto &e : edges_range(g)) { - const auto &v = target(e, g); + for (const auto &v : vertices_range(g)) { for (const auto &lit_id : g[v].literals) { - unique_lit_edge_map[lit_id].insert(e); + assert(lit_id < lit_edge_map.size()); + auto &edge_list = lit_edge_map.at(lit_id); + insert(&edge_list, edge_list.end(), in_edges(v, g)); } } - // Build output map, sorting edges by (source, target) vertex index. - map> lit_edge_map; - for (const auto &m : unique_lit_edge_map) { - auto edge_list = vector(begin(m.second), end(m.second)); - sort(begin(edge_list), end(edge_list), - [&g](const RoseEdge &a, const RoseEdge &b) { - return tie(g[source(a, g)].index, g[target(a, g)].index) < - tie(g[source(b, g)].index, g[target(b, g)].index); - }); - lit_edge_map.emplace(m.first, std::move(edge_list)); + // Sort edges in each edge list by (source, target) indices. This gives us + // less surprising ordering in program generation for a literal with many + // edges. + for (auto &edge_list : lit_edge_map) { + sort(begin(edge_list), end(edge_list), [&g](const RoseEdge &a, + const RoseEdge &b) { + return tie(g[source(a, g)].index, g[target(a, g)].index) < + tie(g[source(b, g)].index, g[target(b, g)].index); + }); } return lit_edge_map; @@ -2906,7 +2897,7 @@ static void buildFragmentPrograms(const RoseBuildImpl &build, vector &fragments, build_context &bc, ProgramBuild &prog_build, - const map> &lit_edge_map) { + const vector> &lit_edge_map) { // Sort fragments based on literal length and case info to build // included literal programs before their parent programs. vector ordered_fragments(fragments);