rose: return a vector from findEdgesByLiteral

This commit is contained in:
Justin Viiret 2017-07-31 16:02:55 +10:00 committed by Matthew Barr
parent 927501175c
commit 09938d532f

View File

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