ue2::unordered_set<RoseVertex> hash_cont; /* member checks */
};
-/**
- * \brief Mapping from a particular rose engine to a set of associated
- * vertices.
- */
-typedef ue2::unordered_map<left_id, set<RoseVertex> > revRoseMap;
-
-} // namespace
+struct RoseAliasingInfo {
+ RoseAliasingInfo(const RoseBuildImpl &build) {
+ const auto &g = build.g;
+
+ // Populate reverse leftfix map.
+ for (auto v : vertices_range(g)) {
+ if (g[v].left) {
+ rev_leftfix[g[v].left].insert(v);
+ }
+ }
-static
-void populateRevRoseMap(const RoseGraph &g, revRoseMap *out) {
- for (auto v : vertices_range(g)) {
- if (g[v].left) {
- (*out)[g[v].left].insert(v);
+ // Populate reverse ghost vertex map.
+ for (const auto &m : build.ghost) {
+ rev_ghost[m.second].insert(m.first);
}
}
-}
+
+ /** \brief Mapping from leftfix to vertices. */
+ ue2::unordered_map<left_id, set<RoseVertex>> rev_leftfix;
+
+ /** \brief Mapping from undelayed ghost to delayed vertices. */
+ ue2::unordered_map<RoseVertex, set<RoseVertex>> rev_ghost;
+};
+
+} // namespace
// Check successor set: must lead to the same vertices via edges with the
// same properties.
}
static
-bool sameGhostProperties(const RoseBuildImpl &build, RoseVertex a,
+bool sameGhostProperties(const RoseBuildImpl &build,
+ const RoseAliasingInfo &rai, RoseVertex a,
RoseVertex b) {
// If these are ghost mapping keys, then they must map to the same vertex.
if (contains(build.ghost, a) || contains(build.ghost, b)) {
}
// If they are ghost vertices, then they must have the same literals.
- // FIXME: get rid of linear scan
- vector<RoseVertex> ghost_a, ghost_b;
- for (const auto &e : build.ghost) {
- if (e.second == a) {
- ghost_a.push_back(e.first);
- }
- if (e.second == b) {
- ghost_b.push_back(e.first);
+ if (contains(rai.rev_ghost, a) || contains(rai.rev_ghost, b)) {
+ if (!contains(rai.rev_ghost, a) || !contains(rai.rev_ghost, b)) {
+ DEBUG_PRINTF("missing ghost reverse mapping\n");
+ return false;
}
+ return build.g[a].literals == build.g[b].literals;
}
- if (ghost_a.empty() && ghost_b.empty()) {
- return true;
- }
-
- if (ghost_a.empty() || ghost_b.empty()) {
- DEBUG_PRINTF("only one is a ghost vertex\n");
- return false;
- }
-
- // Both are ghost vertices: it is only safe to merge them if their literals
- // are the same.
- return build.g[a].literals == build.g[b].literals;
+ return true;
}
static
-bool sameRoleProperties(const RoseBuildImpl &build, RoseVertex a, RoseVertex b) {
+bool sameRoleProperties(const RoseBuildImpl &build, const RoseAliasingInfo &rai,
+ RoseVertex a, RoseVertex b) {
const RoseGraph &g = build.g;
const RoseVertexProps &aprops = g[a], &bprops = g[b];
return false;
}
- if (!sameGhostProperties(build, a, b)) {
+ if (!sameGhostProperties(build, rai, a, b)) {
return false;
}
}
static
-void removeVertexFromMaps(RoseVertex v, RoseBuildImpl &build, revRoseMap &rrm) {
+void removeVertexFromMaps(RoseVertex v, RoseBuildImpl &build,
+ RoseAliasingInfo &rai) {
if (build.g[v].left) {
const left_id left(build.g[v].left);
- assert(contains(rrm[left], v));
- rrm[left].erase(v);
+ assert(contains(rai.rev_leftfix[left], v));
+ rai.rev_leftfix[left].erase(v);
}
}
}
static
-void updateGhostMap(RoseBuildImpl &build, RoseVertex a, RoseVertex b) {
- // Ghost keys.
+void updateGhostMap(RoseBuildImpl &build, RoseAliasingInfo &rai, RoseVertex a,
+ RoseVertex b) {
if (contains(build.ghost, a)) {
- auto it = build.ghost.find(a);
- assert(it->second == build.ghost[b]);
- build.ghost.erase(it);
+ auto ghost = build.ghost.at(a);
+ assert(contains(build.ghost, b) && ghost == build.ghost.at(b));
+ build.ghost.erase(a);
+ rai.rev_ghost[ghost].erase(a);
}
- // Ghost values. FIXME: this will be slow at scale.
- vector<RoseVertex> ghost_refs;
- for (const auto &e : build.ghost) {
- if (e.second == a) {
- ghost_refs.push_back(e.first);
+ if (contains(rai.rev_ghost, a)) {
+ for (const auto &v : rai.rev_ghost[a]) {
+ build.ghost[v] = b;
+ rai.rev_ghost[b].insert(v);
}
- }
- for (const auto &v : ghost_refs) {
- build.ghost.erase(v);
- build.ghost.emplace(v, b);
+ rai.rev_ghost.erase(a);
}
}
// Merge role 'a' into 'b'.
static
void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
- revRoseMap &rrm) {
+ RoseAliasingInfo &rai) {
RoseGraph &g = tbi.g;
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
}
mergeEdges(a, b, g);
-
- updateGhostMap(tbi, a, b);
-
- removeVertexFromMaps(a, tbi, rrm);
+ updateGhostMap(tbi, rai, a, b);
+ removeVertexFromMaps(a, tbi, rai);
}
/**
*/
static
void mergeVerticesDiamond(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
- revRoseMap &rrm) {
+ RoseAliasingInfo &rai) {
RoseGraph &g = tbi.g;
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
g[b].max_offset = max(g[a].max_offset, g[b].max_offset);
mergeLiteralSets(a, b, tbi);
- removeVertexFromMaps(a, tbi, rrm);
+ removeVertexFromMaps(a, tbi, rai);
}
static never_inline
static
bool mergeSameCastle(RoseBuildImpl &tbi, RoseVertex a, RoseVertex b,
- revRoseMap &rrm) {
+ RoseAliasingInfo &rai) {
RoseGraph &g = tbi.g;
LeftEngInfo &a_left = g[a].left;
LeftEngInfo &b_left = g[b].left;
}
}
- assert(contains(rrm[b_left], b));
- rrm[b_left].erase(b);
- rrm[a_left].insert(b);
+ assert(contains(rai.rev_leftfix[b_left], b));
+ rai.rev_leftfix[b_left].erase(b);
+ rai.rev_leftfix[a_left].insert(b);
a_left.leftfix_report = new_report;
b_left.leftfix_report = new_report;
updateEdgeTops(g, a, a_top_map);
updateEdgeTops(g, b, b_top_map);
- pruneUnusedTops(castle, g, rrm[a_left]);
+ pruneUnusedTops(castle, g, rai.rev_leftfix[a_left]);
return true;
}
static
bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
RoseVertex b, bool trivialCasesOnly,
- revRoseMap &rrm) {
+ RoseAliasingInfo &rai) {
RoseGraph &g = tbi.g;
LeftEngInfo &a_left = g[a].left;
LeftEngInfo &b_left = g[b].left;
if (&a_castle == &b_castle) {
DEBUG_PRINTF("castles are the same\n");
- return mergeSameCastle(tbi, a, b, rrm);
+ return mergeSameCastle(tbi, a, b, rai);
}
if (is_equal(a_castle, a_left.leftfix_report, b_castle,
b_left.leftfix_report)) {
DEBUG_PRINTF("castles are equiv with respect to reports\n");
- if (rrm[a_left_id].size() == 1) {
+ if (rai.rev_leftfix[a_left_id].size() == 1) {
/* nobody else is using a_castle */
- rrm[b_left_id].erase(b);
- rrm[a_left_id].insert(b);
- pruneUnusedTops(b_castle, g, rrm[b_left_id]);
+ rai.rev_leftfix[b_left_id].erase(b);
+ rai.rev_leftfix[a_left_id].insert(b);
+ pruneUnusedTops(b_castle, g, rai.rev_leftfix[b_left_id]);
b_left.castle = a_left.castle;
b_left.leftfix_report = a_left.leftfix_report;
DEBUG_PRINTF("OK -> only user of a_castle\n");
return true;
}
- if (rrm[b_left_id].size() == 1) {
+ if (rai.rev_leftfix[b_left_id].size() == 1) {
/* nobody else is using b_castle */
- rrm[a_left_id].erase(a);
- rrm[b_left_id].insert(a);
- pruneUnusedTops(a_castle, g, rrm[a_left_id]);
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].insert(a);
+ pruneUnusedTops(a_castle, g, rai.rev_leftfix[a_left_id]);
a_left.castle = b_left.castle;
a_left.leftfix_report = b_left.leftfix_report;
DEBUG_PRINTF("OK -> only user of b_castle\n");
if (preds_same) {
/* preds are the same anyway in diamond/left merges just need to
- * check that all the literals in rrm[b_h] can handle a_h */
- for (auto v : rrm[b_left_id]) {
+ * check that all the literals in rev_leftfix[b_h] can handle a_h */
+ for (auto v : rai.rev_leftfix[b_left_id]) {
if (!mergeableRoseVertices(tbi, a, v)) {
goto literal_mismatch_1;
}
}
- rrm[a_left_id].erase(a);
- rrm[b_left_id].insert(a);
- pruneUnusedTops(a_castle, g, rrm[a_left_id]);
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].insert(a);
+ pruneUnusedTops(a_castle, g, rai.rev_leftfix[a_left_id]);
a_left.castle = b_left.castle;
a_left.leftfix_report = b_left.leftfix_report;
DEBUG_PRINTF("OK -> same preds ???\n");
return true;
literal_mismatch_1:
/* preds are the same anyway in diamond/left merges just need to
- * check that all the literals in rrm[a_h] can handle b_h */
- for (auto v : rrm[a_left_id]) {
+ * check that all the literals in rev_leftfix[a_h] can handle b_h */
+ for (auto v : rai.rev_leftfix[a_left_id]) {
if (!mergeableRoseVertices(tbi, v, b)) {
goto literal_mismatch_2;
}
}
- rrm[b_left_id].erase(b);
- rrm[a_left_id].insert(b);
- pruneUnusedTops(b_castle, g, rrm[b_left_id]);
+ rai.rev_leftfix[b_left_id].erase(b);
+ rai.rev_leftfix[a_left_id].insert(b);
+ pruneUnusedTops(b_castle, g, rai.rev_leftfix[b_left_id]);
b_left.castle = a_left.castle;
b_left.leftfix_report = a_left.leftfix_report;
DEBUG_PRINTF("OK -> same preds ???\n");
pruneCastle(*new_castle, a_left.leftfix_report);
setReports(*new_castle, new_report);
- rrm[a_left_id].erase(a);
- rrm[b_left_id].erase(b);
- pruneUnusedTops(*a_left.castle, g, rrm[a_left_id]);
- pruneUnusedTops(*b_left.castle, g, rrm[b_left_id]);
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].erase(b);
+ pruneUnusedTops(*a_left.castle, g, rai.rev_leftfix[a_left_id]);
+ pruneUnusedTops(*b_left.castle, g, rai.rev_leftfix[b_left_id]);
a_left.leftfix_report = new_report;
b_left.leftfix_report = new_report;
b_left.castle = new_castle;
assert(a_left == b_left);
- rrm[a_left].insert(a);
- rrm[a_left].insert(b);
- pruneUnusedTops(*new_castle, g, rrm[a_left]);
+ rai.rev_leftfix[a_left].insert(a);
+ rai.rev_leftfix[a_left].insert(b);
+ pruneUnusedTops(*new_castle, g, rai.rev_leftfix[a_left]);
return true;
}
return false;
}
- set<RoseVertex> &b_verts = rrm[b_left_id];
+ set<RoseVertex> &b_verts = rai.rev_leftfix[b_left_id];
set<RoseVertex> aa;
aa.insert(a);
DEBUG_PRINTF("merged into castle containing %zu repeats\n",
m_castle->repeats.size());
- rrm[a_left_id].erase(a);
- rrm[b_left_id].erase(b);
- pruneUnusedTops(*a_left.castle, g, rrm[a_left_id]);
- pruneUnusedTops(*b_left.castle, g, rrm[b_left_id]);
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].erase(b);
+ pruneUnusedTops(*a_left.castle, g, rai.rev_leftfix[a_left_id]);
+ pruneUnusedTops(*b_left.castle, g, rai.rev_leftfix[b_left_id]);
a_left.castle = m_castle;
a_left.leftfix_report = new_report;
b_left.leftfix_report = new_report;
assert(a_left == b_left);
- rrm[a_left].insert(a);
- rrm[a_left].insert(b);
- pruneUnusedTops(*m_castle, g, rrm[a_left]);
+ rai.rev_leftfix[a_left].insert(a);
+ rai.rev_leftfix[a_left].insert(b);
+ pruneUnusedTops(*m_castle, g, rai.rev_leftfix[a_left]);
return true;
}
static
bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
RoseVertex b, bool trivialCasesOnly,
- revRoseMap &rrm) {
+ RoseAliasingInfo &rai) {
RoseGraph &g = tbi.g;
LeftEngInfo &a_left = g[a].left;
LeftEngInfo &b_left = g[b].left;
duplicateReport(*b_h, b_left.leftfix_report, new_report);
a_left.leftfix_report = new_report;
b_left.leftfix_report = new_report;
- pruneReportIfUnused(tbi, b_h, rrm[b_left_id], a_oldreport);
- pruneReportIfUnused(tbi, b_h, rrm[b_left_id], b_oldreport);
- pruneUnusedTops(*b_h, g, rrm[b_left_id]);
+ pruneReportIfUnused(tbi, b_h, rai.rev_leftfix[b_left_id], a_oldreport);
+ pruneReportIfUnused(tbi, b_h, rai.rev_leftfix[b_left_id], b_oldreport);
+ pruneUnusedTops(*b_h, g, rai.rev_leftfix[b_left_id]);
assert(a_left == b_left);
return true;
}
/* if it is the same graph, it is also fairly easy */
if (is_equal(*a_h, a_left.leftfix_report, *b_h, b_left.leftfix_report)) {
- if (rrm[a_left_id].size() == 1) {
+ if (rai.rev_leftfix[a_left_id].size() == 1) {
/* nobody else is using a_h */
- rrm[b_left_id].erase(b);
- rrm[a_left_id].insert(b);
+ rai.rev_leftfix[b_left_id].erase(b);
+ rai.rev_leftfix[a_left_id].insert(b);
b_left.graph = a_h;
b_left.leftfix_report = a_left.leftfix_report;
- pruneUnusedTops(*b_h, g, rrm[b_left_id]);
+ pruneUnusedTops(*b_h, g, rai.rev_leftfix[b_left_id]);
DEBUG_PRINTF("OK -> only user of a_h\n");
return true;
}
- if (rrm[b_left_id].size() == 1) {
+ if (rai.rev_leftfix[b_left_id].size() == 1) {
/* nobody else is using b_h */
- rrm[a_left_id].erase(a);
- rrm[b_left_id].insert(a);
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].insert(a);
a_left.graph = b_h;
a_left.leftfix_report = b_left.leftfix_report;
- pruneUnusedTops(*a_h, g, rrm[a_left_id]);
+ pruneUnusedTops(*a_h, g, rai.rev_leftfix[a_left_id]);
DEBUG_PRINTF("OK -> only user of b_h\n");
return true;
}
if (preds_same) {
/* preds are the same anyway in diamond/left merges just need to
- * check that all the literals in rrm[b_h] can handle a_h */
- for (auto v : rrm[b_left_id]) {
+ * check that all the literals in rev_leftfix[b_h] can handle a_h */
+ for (auto v : rai.rev_leftfix[b_left_id]) {
if (!mergeableRoseVertices(tbi, a, v)) {
goto literal_mismatch_1;
}
}
- rrm[a_left_id].erase(a);
- rrm[b_left_id].insert(a);
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].insert(a);
a_left.graph = b_h;
a_left.leftfix_report = b_left.leftfix_report;
- pruneUnusedTops(*a_h, g, rrm[a_left_id]);
+ pruneUnusedTops(*a_h, g, rai.rev_leftfix[a_left_id]);
DEBUG_PRINTF("OK -> same preds ???\n");
return true;
literal_mismatch_1:
/* preds are the same anyway in diamond/left merges just need to
- * check that all the literals in rrm[a_h] can handle b_h */
- for (auto v : rrm[a_left_id]) {
+ * check that all the literals in rev_leftfix[a_h] can handle b_h */
+ for (auto v : rai.rev_leftfix[a_left_id]) {
if (!mergeableRoseVertices(tbi, v, b)) {
goto literal_mismatch_2;
}
}
- rrm[b_left_id].erase(b);
- rrm[a_left_id].insert(b);
+ rai.rev_leftfix[b_left_id].erase(b);
+ rai.rev_leftfix[a_left_id].insert(b);
b_left.graph = a_h;
b_left.leftfix_report = a_left.leftfix_report;
- pruneUnusedTops(*b_h, g, rrm[b_left_id]);
+ pruneUnusedTops(*b_h, g, rai.rev_leftfix[b_left_id]);
DEBUG_PRINTF("OK -> same preds ???\n");
return true;
literal_mismatch_2:;
duplicateReport(*new_graph, b_left.leftfix_report, new_report);
pruneReportIfUnused(tbi, new_graph, {}, b_left.leftfix_report);
- rrm[a_left_id].erase(a);
- rrm[b_left_id].erase(b);
- pruneUnusedTops(*a_h, g, rrm[a_left_id]);
- pruneUnusedTops(*b_h, g, rrm[b_left_id]);
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].erase(b);
+ pruneUnusedTops(*a_h, g, rai.rev_leftfix[a_left_id]);
+ pruneUnusedTops(*b_h, g, rai.rev_leftfix[b_left_id]);
a_left.leftfix_report = new_report;
b_left.leftfix_report = new_report;
a_left.graph = new_graph;
b_left.graph = new_graph;
- rrm[a_left].insert(a);
- rrm[a_left].insert(b);
- pruneUnusedTops(*new_graph, g, rrm[a_left]);
+ rai.rev_leftfix[a_left].insert(a);
+ rai.rev_leftfix[a_left].insert(b);
+ pruneUnusedTops(*new_graph, g, rai.rev_leftfix[a_left]);
return true;
}
DEBUG_PRINTF("attempting merge of roses on vertices %zu and %zu\n",
g[a].idx, g[b].idx);
- set<RoseVertex> &b_verts = rrm[b_left];
+ set<RoseVertex> &b_verts = rai.rev_leftfix[b_left];
set<RoseVertex> aa;
aa.insert(a);
ReportID new_report = tbi.getNewNfaReport();
duplicateReport(*b_h, b_left.leftfix_report, new_report);
b_left.leftfix_report = new_report;
- pruneReportIfUnused(tbi, b_h, rrm[b_left_id], b_oldreport);
+ pruneReportIfUnused(tbi, b_h, rai.rev_leftfix[b_left_id], b_oldreport);
NGHolder victim;
cloneHolder(victim, *a_h);
a_left.graph = b_h;
a_left.leftfix_report = new_report;
- assert(contains(rrm[a_left_id], a));
- assert(contains(rrm[b_left_id], b));
- rrm[a_left_id].erase(a);
- rrm[b_left_id].insert(a);
+ assert(contains(rai.rev_leftfix[a_left_id], a));
+ assert(contains(rai.rev_leftfix[b_left_id], b));
+ rai.rev_leftfix[a_left_id].erase(a);
+ rai.rev_leftfix[b_left_id].insert(a);
- pruneUnusedTops(*a_h, g, rrm[a_left_id]);
- pruneUnusedTops(*b_h, g, rrm[b_left_id]);
+ pruneUnusedTops(*a_h, g, rai.rev_leftfix[a_left_id]);
+ pruneUnusedTops(*b_h, g, rai.rev_leftfix[b_left_id]);
// Prune A's report from its old prefix if it was only used by A.
- pruneReportIfUnused(tbi, a_h, rrm[a_left_id], a_oldreport);
+ pruneReportIfUnused(tbi, a_h, rai.rev_leftfix[a_left_id], a_oldreport);
reduceImplementableGraph(*b_h, SOM_NONE, nullptr, tbi.cc);
// is not possible.
static
bool attemptRoseMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
- RoseVertex b, bool trivialCasesOnly, revRoseMap &rrm) {
+ RoseVertex b, bool trivialCasesOnly,
+ RoseAliasingInfo &rai) {
DEBUG_PRINTF("attempting rose merge, vertices a=%zu, b=%zu\n",
tbi.g[a].idx, tbi.g[b].idx);
assert(a != b);
if (a_left_id.graph() && b_left_id.graph()) {
return attemptRoseGraphMerge(tbi, preds_same, a, b, trivialCasesOnly,
- rrm);
+ rai);
}
if (a_left_id.castle() && b_left_id.castle()) {
return attemptRoseCastleMerge(tbi, preds_same, a, b, trivialCasesOnly,
- rrm);
+ rai);
}
return false;
static never_inline
void diamondMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
vector<RoseVertex> *dead, bool mergeRoses,
- revRoseMap &rrm) {
+ RoseAliasingInfo &rai) {
DEBUG_PRINTF("begin\n");
RoseGraph &g = tbi.g;
RoseVertex b = *jt;
assert(contains(candidates, b));
- if (!sameRoleProperties(tbi, a, b)) {
+ if (!sameRoleProperties(tbi, rai, a, b)) {
DEBUG_PRINTF("diff role prop\n");
continue;
}
continue;
}
- if (!attemptRoseMerge(tbi, true, a, b, !mergeRoses, rrm)) {
+ if (!attemptRoseMerge(tbi, true, a, b, !mergeRoses, rai)) {
DEBUG_PRINTF("rose fail\n");
continue;
}
- mergeVerticesDiamond(a, b, tbi, rrm);
+ mergeVerticesDiamond(a, b, tbi, rai);
dead->push_back(a);
candidates.erase(a);
break; // next a
vector<RoseVertex>::iterator it,
const vector<RoseVertex>::iterator &end,
const RoseVertex a, const RoseBuildImpl &build,
+ const RoseAliasingInfo &rai,
const CandidateSet &candidates) {
const RoseGraph &g = build.g;
continue;
}
- if (!sameRoleProperties(build, a, b)) {
+ if (!sameRoleProperties(build, rai, a, b)) {
continue;
}
static never_inline
void leftMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
- vector<RoseVertex> *dead, revRoseMap &rrm) {
+ vector<RoseVertex> *dead, RoseAliasingInfo &rai) {
DEBUG_PRINTF("begin (%zu)\n", candidates.size());
RoseGraph &g = tbi.g;
vector<RoseVertex> siblings;
sort(siblings.begin(), siblings.end(), VertexIndexComp(g));
auto jt = findLeftMergeSibling(siblings.begin(), siblings.end(), a, tbi,
- candidates);
+ rai, candidates);
if (jt == siblings.end()) {
continue;
}
RoseVertex b = *jt;
- if (!attemptRoseMerge(tbi, true, a, b, 0, rrm)) {
+ if (!attemptRoseMerge(tbi, true, a, b, 0, rai)) {
DEBUG_PRINTF("rose fail\n");
continue;
}
- mergeVertices(a, b, tbi, rrm);
+ mergeVertices(a, b, tbi, rai);
dead->push_back(a);
candidates.erase(ait);
}
vector<RoseVertex>::const_iterator it,
const vector<RoseVertex>::const_iterator &end,
const RoseVertex a, const RoseBuildImpl &build,
+ const RoseAliasingInfo &rai,
const CandidateSet &candidates) {
const RoseGraph &g = build.g;
continue;
}
- if (!sameRoleProperties(build, a, b)) {
+ if (!sameRoleProperties(build, rai, a, b)) {
continue;
}
static never_inline
void rightMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
vector<RoseVertex> *dead, bool mergeRoses,
- revRoseMap &rrm) {
+ RoseAliasingInfo &rai) {
DEBUG_PRINTF("begin\n");
map<size_t, vector<RoseVertex> > sibling_cache;
auto jt = siblings.begin();
while (jt != siblings.end()) {
- jt = findRightMergeSibling(jt, siblings.end(), a, tbi, candidates);
+ jt = findRightMergeSibling(jt, siblings.end(), a, tbi, rai,
+ candidates);
if (jt == siblings.end()) {
break;
}
- if (attemptRoseMerge(tbi, false, a, *jt, !mergeRoses, rrm)) {
+ if (attemptRoseMerge(tbi, false, a, *jt, !mergeRoses, rai)) {
break;
}
++jt;
}
RoseVertex b = *jt;
- mergeVertices(a, b, tbi, rrm);
+ mergeVertices(a, b, tbi, rai);
dead->push_back(a);
candidates.erase(ait);
}
return;
}
- revRoseMap rrm;
-
DEBUG_PRINTF("doing role aliasing mr=%d\n", (int)mergeRoses);
- populateRevRoseMap(g, &rrm);
+
+ RoseAliasingInfo rai(build);
mergeRoses &= cc.grey.mergeRose & cc.grey.roseMergeRosesDuringAliasing;
size_t old_dead_size = 0;
do {
old_dead_size = dead.size();
- leftMergePass(candidates, build, &dead, rrm);
- rightMergePass(candidates, build, &dead, mergeRoses, rrm);
+ leftMergePass(candidates, build, &dead, rai);
+ rightMergePass(candidates, build, &dead, mergeRoses, rai);
} while (old_dead_size != dead.size());
/* Diamond merge passes cannot create extra merges as they require the same
* to a merge to different pred/succ before a diamond merge, it will still
* be afterwards. */
filterDiamondCandidates(g, candidates);
- diamondMergePass(candidates, build, &dead, mergeRoses, rrm);
+ diamondMergePass(candidates, build, &dead, mergeRoses, rai);
DEBUG_PRINTF("killed %zu vertices\n", dead.size());
build.removeVertices(dead);