mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-07-13 14:04:44 +03:00
role aliasing: use a reverse ghost map
This commit is contained in:
parent
1e5fcd5e80
commit
679042779a
@ -156,22 +156,31 @@ private:
|
|||||||
ue2::unordered_set<RoseVertex> hash_cont; /* member checks */
|
ue2::unordered_set<RoseVertex> hash_cont; /* member checks */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
struct RoseAliasingInfo {
|
||||||
* \brief Mapping from a particular rose engine to a set of associated
|
RoseAliasingInfo(const RoseBuildImpl &build) {
|
||||||
* vertices.
|
const auto &g = build.g;
|
||||||
*/
|
|
||||||
typedef ue2::unordered_map<left_id, set<RoseVertex> > revRoseMap;
|
|
||||||
|
|
||||||
} // namespace
|
// Populate reverse leftfix map.
|
||||||
|
for (auto v : vertices_range(g)) {
|
||||||
|
if (g[v].left) {
|
||||||
|
rev_leftfix[g[v].left].insert(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static
|
// Populate reverse ghost vertex map.
|
||||||
void populateRevRoseMap(const RoseGraph &g, revRoseMap *out) {
|
for (const auto &m : build.ghost) {
|
||||||
for (auto v : vertices_range(g)) {
|
rev_ghost[m.second].insert(m.first);
|
||||||
if (g[v].left) {
|
|
||||||
(*out)[g[v].left].insert(v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/** \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
|
// Check successor set: must lead to the same vertices via edges with the
|
||||||
// same properties.
|
// same properties.
|
||||||
@ -352,7 +361,8 @@ bool isAliasingCandidate(RoseVertex v, const RoseBuildImpl &tbi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool sameGhostProperties(const RoseBuildImpl &build, RoseVertex a,
|
bool sameGhostProperties(const RoseBuildImpl &build,
|
||||||
|
const RoseAliasingInfo &rai, RoseVertex a,
|
||||||
RoseVertex b) {
|
RoseVertex b) {
|
||||||
// If these are ghost mapping keys, then they must map to the same vertex.
|
// If these are ghost mapping keys, then they must map to the same vertex.
|
||||||
if (contains(build.ghost, a) || contains(build.ghost, b)) {
|
if (contains(build.ghost, a) || contains(build.ghost, b)) {
|
||||||
@ -370,33 +380,20 @@ bool sameGhostProperties(const RoseBuildImpl &build, RoseVertex a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If they are ghost vertices, then they must have the same literals.
|
// If they are ghost vertices, then they must have the same literals.
|
||||||
// FIXME: get rid of linear scan
|
if (contains(rai.rev_ghost, a) || contains(rai.rev_ghost, b)) {
|
||||||
vector<RoseVertex> ghost_a, ghost_b;
|
if (!contains(rai.rev_ghost, a) || !contains(rai.rev_ghost, b)) {
|
||||||
for (const auto &e : build.ghost) {
|
DEBUG_PRINTF("missing ghost reverse mapping\n");
|
||||||
if (e.second == a) {
|
return false;
|
||||||
ghost_a.push_back(e.first);
|
|
||||||
}
|
|
||||||
if (e.second == b) {
|
|
||||||
ghost_b.push_back(e.first);
|
|
||||||
}
|
}
|
||||||
|
return build.g[a].literals == build.g[b].literals;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ghost_a.empty() && ghost_b.empty()) {
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
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 RoseGraph &g = build.g;
|
||||||
const RoseVertexProps &aprops = g[a], &bprops = g[b];
|
const RoseVertexProps &aprops = g[a], &bprops = g[b];
|
||||||
|
|
||||||
@ -421,7 +418,7 @@ bool sameRoleProperties(const RoseBuildImpl &build, RoseVertex a, RoseVertex b)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sameGhostProperties(build, a, b)) {
|
if (!sameGhostProperties(build, rai, a, b)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,11 +491,12 @@ size_t hashRightRoleProperties(RoseVertex v, const RoseGraph &g) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void removeVertexFromMaps(RoseVertex v, RoseBuildImpl &build, revRoseMap &rrm) {
|
void removeVertexFromMaps(RoseVertex v, RoseBuildImpl &build,
|
||||||
|
RoseAliasingInfo &rai) {
|
||||||
if (build.g[v].left) {
|
if (build.g[v].left) {
|
||||||
const left_id left(build.g[v].left);
|
const left_id left(build.g[v].left);
|
||||||
assert(contains(rrm[left], v));
|
assert(contains(rai.rev_leftfix[left], v));
|
||||||
rrm[left].erase(v);
|
rai.rev_leftfix[left].erase(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,31 +580,28 @@ void mergeLiteralSets(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void updateGhostMap(RoseBuildImpl &build, RoseVertex a, RoseVertex b) {
|
void updateGhostMap(RoseBuildImpl &build, RoseAliasingInfo &rai, RoseVertex a,
|
||||||
// Ghost keys.
|
RoseVertex b) {
|
||||||
if (contains(build.ghost, a)) {
|
if (contains(build.ghost, a)) {
|
||||||
auto it = build.ghost.find(a);
|
auto ghost = build.ghost.at(a);
|
||||||
assert(it->second == build.ghost[b]);
|
assert(contains(build.ghost, b) && ghost == build.ghost.at(b));
|
||||||
build.ghost.erase(it);
|
build.ghost.erase(a);
|
||||||
|
rai.rev_ghost[ghost].erase(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ghost values. FIXME: this will be slow at scale.
|
if (contains(rai.rev_ghost, a)) {
|
||||||
vector<RoseVertex> ghost_refs;
|
for (const auto &v : rai.rev_ghost[a]) {
|
||||||
for (const auto &e : build.ghost) {
|
build.ghost[v] = b;
|
||||||
if (e.second == a) {
|
rai.rev_ghost[b].insert(v);
|
||||||
ghost_refs.push_back(e.first);
|
|
||||||
}
|
}
|
||||||
}
|
rai.rev_ghost.erase(a);
|
||||||
for (const auto &v : ghost_refs) {
|
|
||||||
build.ghost.erase(v);
|
|
||||||
build.ghost.emplace(v, b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge role 'a' into 'b'.
|
// Merge role 'a' into 'b'.
|
||||||
static
|
static
|
||||||
void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
||||||
revRoseMap &rrm) {
|
RoseAliasingInfo &rai) {
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = tbi.g;
|
||||||
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
|
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
|
||||||
|
|
||||||
@ -633,10 +628,8 @@ void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mergeEdges(a, b, g);
|
mergeEdges(a, b, g);
|
||||||
|
updateGhostMap(tbi, rai, a, b);
|
||||||
updateGhostMap(tbi, a, b);
|
removeVertexFromMaps(a, tbi, rai);
|
||||||
|
|
||||||
removeVertexFromMaps(a, tbi, rrm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -645,7 +638,7 @@ void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
|||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
void mergeVerticesDiamond(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
void mergeVerticesDiamond(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
||||||
revRoseMap &rrm) {
|
RoseAliasingInfo &rai) {
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = tbi.g;
|
||||||
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
|
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
|
||||||
|
|
||||||
@ -665,7 +658,7 @@ void mergeVerticesDiamond(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
|||||||
g[b].max_offset = max(g[a].max_offset, g[b].max_offset);
|
g[b].max_offset = max(g[a].max_offset, g[b].max_offset);
|
||||||
|
|
||||||
mergeLiteralSets(a, b, tbi);
|
mergeLiteralSets(a, b, tbi);
|
||||||
removeVertexFromMaps(a, tbi, rrm);
|
removeVertexFromMaps(a, tbi, rai);
|
||||||
}
|
}
|
||||||
|
|
||||||
static never_inline
|
static never_inline
|
||||||
@ -885,7 +878,7 @@ void pruneUnusedTops(NGHolder &h, const RoseGraph &g,
|
|||||||
|
|
||||||
static
|
static
|
||||||
bool mergeSameCastle(RoseBuildImpl &tbi, RoseVertex a, RoseVertex b,
|
bool mergeSameCastle(RoseBuildImpl &tbi, RoseVertex a, RoseVertex b,
|
||||||
revRoseMap &rrm) {
|
RoseAliasingInfo &rai) {
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = tbi.g;
|
||||||
LeftEngInfo &a_left = g[a].left;
|
LeftEngInfo &a_left = g[a].left;
|
||||||
LeftEngInfo &b_left = g[b].left;
|
LeftEngInfo &b_left = g[b].left;
|
||||||
@ -931,9 +924,9 @@ bool mergeSameCastle(RoseBuildImpl &tbi, RoseVertex a, RoseVertex b,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(contains(rrm[b_left], b));
|
assert(contains(rai.rev_leftfix[b_left], b));
|
||||||
rrm[b_left].erase(b);
|
rai.rev_leftfix[b_left].erase(b);
|
||||||
rrm[a_left].insert(b);
|
rai.rev_leftfix[a_left].insert(b);
|
||||||
|
|
||||||
a_left.leftfix_report = new_report;
|
a_left.leftfix_report = new_report;
|
||||||
b_left.leftfix_report = new_report;
|
b_left.leftfix_report = new_report;
|
||||||
@ -942,14 +935,14 @@ bool mergeSameCastle(RoseBuildImpl &tbi, RoseVertex a, RoseVertex b,
|
|||||||
updateEdgeTops(g, a, a_top_map);
|
updateEdgeTops(g, a, a_top_map);
|
||||||
updateEdgeTops(g, b, b_top_map);
|
updateEdgeTops(g, b, b_top_map);
|
||||||
|
|
||||||
pruneUnusedTops(castle, g, rrm[a_left]);
|
pruneUnusedTops(castle, g, rai.rev_leftfix[a_left]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
||||||
RoseVertex b, bool trivialCasesOnly,
|
RoseVertex b, bool trivialCasesOnly,
|
||||||
revRoseMap &rrm) {
|
RoseAliasingInfo &rai) {
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = tbi.g;
|
||||||
LeftEngInfo &a_left = g[a].left;
|
LeftEngInfo &a_left = g[a].left;
|
||||||
LeftEngInfo &b_left = g[b].left;
|
LeftEngInfo &b_left = g[b].left;
|
||||||
@ -968,28 +961,28 @@ bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
|
|
||||||
if (&a_castle == &b_castle) {
|
if (&a_castle == &b_castle) {
|
||||||
DEBUG_PRINTF("castles are the same\n");
|
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,
|
if (is_equal(a_castle, a_left.leftfix_report, b_castle,
|
||||||
b_left.leftfix_report)) {
|
b_left.leftfix_report)) {
|
||||||
DEBUG_PRINTF("castles are equiv with respect to reports\n");
|
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 */
|
/* nobody else is using a_castle */
|
||||||
rrm[b_left_id].erase(b);
|
rai.rev_leftfix[b_left_id].erase(b);
|
||||||
rrm[a_left_id].insert(b);
|
rai.rev_leftfix[a_left_id].insert(b);
|
||||||
pruneUnusedTops(b_castle, g, rrm[b_left_id]);
|
pruneUnusedTops(b_castle, g, rai.rev_leftfix[b_left_id]);
|
||||||
b_left.castle = a_left.castle;
|
b_left.castle = a_left.castle;
|
||||||
b_left.leftfix_report = a_left.leftfix_report;
|
b_left.leftfix_report = a_left.leftfix_report;
|
||||||
DEBUG_PRINTF("OK -> only user of a_castle\n");
|
DEBUG_PRINTF("OK -> only user of a_castle\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rrm[b_left_id].size() == 1) {
|
if (rai.rev_leftfix[b_left_id].size() == 1) {
|
||||||
/* nobody else is using b_castle */
|
/* nobody else is using b_castle */
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].insert(a);
|
rai.rev_leftfix[b_left_id].insert(a);
|
||||||
pruneUnusedTops(a_castle, g, rrm[a_left_id]);
|
pruneUnusedTops(a_castle, g, rai.rev_leftfix[a_left_id]);
|
||||||
a_left.castle = b_left.castle;
|
a_left.castle = b_left.castle;
|
||||||
a_left.leftfix_report = b_left.leftfix_report;
|
a_left.leftfix_report = b_left.leftfix_report;
|
||||||
DEBUG_PRINTF("OK -> only user of b_castle\n");
|
DEBUG_PRINTF("OK -> only user of b_castle\n");
|
||||||
@ -998,32 +991,32 @@ bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
|
|
||||||
if (preds_same) {
|
if (preds_same) {
|
||||||
/* preds are the same anyway in diamond/left merges just need to
|
/* 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 */
|
* check that all the literals in rev_leftfix[b_h] can handle a_h */
|
||||||
for (auto v : rrm[b_left_id]) {
|
for (auto v : rai.rev_leftfix[b_left_id]) {
|
||||||
if (!mergeableRoseVertices(tbi, a, v)) {
|
if (!mergeableRoseVertices(tbi, a, v)) {
|
||||||
goto literal_mismatch_1;
|
goto literal_mismatch_1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].insert(a);
|
rai.rev_leftfix[b_left_id].insert(a);
|
||||||
pruneUnusedTops(a_castle, g, rrm[a_left_id]);
|
pruneUnusedTops(a_castle, g, rai.rev_leftfix[a_left_id]);
|
||||||
a_left.castle = b_left.castle;
|
a_left.castle = b_left.castle;
|
||||||
a_left.leftfix_report = b_left.leftfix_report;
|
a_left.leftfix_report = b_left.leftfix_report;
|
||||||
DEBUG_PRINTF("OK -> same preds ???\n");
|
DEBUG_PRINTF("OK -> same preds ???\n");
|
||||||
return true;
|
return true;
|
||||||
literal_mismatch_1:
|
literal_mismatch_1:
|
||||||
/* preds are the same anyway in diamond/left merges just need to
|
/* 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 */
|
* check that all the literals in rev_leftfix[a_h] can handle b_h */
|
||||||
for (auto v : rrm[a_left_id]) {
|
for (auto v : rai.rev_leftfix[a_left_id]) {
|
||||||
if (!mergeableRoseVertices(tbi, v, b)) {
|
if (!mergeableRoseVertices(tbi, v, b)) {
|
||||||
goto literal_mismatch_2;
|
goto literal_mismatch_2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rrm[b_left_id].erase(b);
|
rai.rev_leftfix[b_left_id].erase(b);
|
||||||
rrm[a_left_id].insert(b);
|
rai.rev_leftfix[a_left_id].insert(b);
|
||||||
pruneUnusedTops(b_castle, g, rrm[b_left_id]);
|
pruneUnusedTops(b_castle, g, rai.rev_leftfix[b_left_id]);
|
||||||
b_left.castle = a_left.castle;
|
b_left.castle = a_left.castle;
|
||||||
b_left.leftfix_report = a_left.leftfix_report;
|
b_left.leftfix_report = a_left.leftfix_report;
|
||||||
DEBUG_PRINTF("OK -> same preds ???\n");
|
DEBUG_PRINTF("OK -> same preds ???\n");
|
||||||
@ -1039,10 +1032,10 @@ bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
pruneCastle(*new_castle, a_left.leftfix_report);
|
pruneCastle(*new_castle, a_left.leftfix_report);
|
||||||
setReports(*new_castle, new_report);
|
setReports(*new_castle, new_report);
|
||||||
|
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].erase(b);
|
rai.rev_leftfix[b_left_id].erase(b);
|
||||||
pruneUnusedTops(*a_left.castle, g, rrm[a_left_id]);
|
pruneUnusedTops(*a_left.castle, g, rai.rev_leftfix[a_left_id]);
|
||||||
pruneUnusedTops(*b_left.castle, g, rrm[b_left_id]);
|
pruneUnusedTops(*b_left.castle, g, rai.rev_leftfix[b_left_id]);
|
||||||
|
|
||||||
a_left.leftfix_report = new_report;
|
a_left.leftfix_report = new_report;
|
||||||
b_left.leftfix_report = new_report;
|
b_left.leftfix_report = new_report;
|
||||||
@ -1050,9 +1043,9 @@ bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
b_left.castle = new_castle;
|
b_left.castle = new_castle;
|
||||||
|
|
||||||
assert(a_left == b_left);
|
assert(a_left == b_left);
|
||||||
rrm[a_left].insert(a);
|
rai.rev_leftfix[a_left].insert(a);
|
||||||
rrm[a_left].insert(b);
|
rai.rev_leftfix[a_left].insert(b);
|
||||||
pruneUnusedTops(*new_castle, g, rrm[a_left]);
|
pruneUnusedTops(*new_castle, g, rai.rev_leftfix[a_left]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1068,7 +1061,7 @@ bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
set<RoseVertex> &b_verts = rrm[b_left_id];
|
set<RoseVertex> &b_verts = rai.rev_leftfix[b_left_id];
|
||||||
set<RoseVertex> aa;
|
set<RoseVertex> aa;
|
||||||
aa.insert(a);
|
aa.insert(a);
|
||||||
|
|
||||||
@ -1126,10 +1119,10 @@ bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
DEBUG_PRINTF("merged into castle containing %zu repeats\n",
|
DEBUG_PRINTF("merged into castle containing %zu repeats\n",
|
||||||
m_castle->repeats.size());
|
m_castle->repeats.size());
|
||||||
|
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].erase(b);
|
rai.rev_leftfix[b_left_id].erase(b);
|
||||||
pruneUnusedTops(*a_left.castle, g, rrm[a_left_id]);
|
pruneUnusedTops(*a_left.castle, g, rai.rev_leftfix[a_left_id]);
|
||||||
pruneUnusedTops(*b_left.castle, g, rrm[b_left_id]);
|
pruneUnusedTops(*b_left.castle, g, rai.rev_leftfix[b_left_id]);
|
||||||
|
|
||||||
a_left.castle = m_castle;
|
a_left.castle = m_castle;
|
||||||
a_left.leftfix_report = new_report;
|
a_left.leftfix_report = new_report;
|
||||||
@ -1137,16 +1130,16 @@ bool attemptRoseCastleMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
b_left.leftfix_report = new_report;
|
b_left.leftfix_report = new_report;
|
||||||
|
|
||||||
assert(a_left == b_left);
|
assert(a_left == b_left);
|
||||||
rrm[a_left].insert(a);
|
rai.rev_leftfix[a_left].insert(a);
|
||||||
rrm[a_left].insert(b);
|
rai.rev_leftfix[a_left].insert(b);
|
||||||
pruneUnusedTops(*m_castle, g, rrm[a_left]);
|
pruneUnusedTops(*m_castle, g, rai.rev_leftfix[a_left]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
||||||
RoseVertex b, bool trivialCasesOnly,
|
RoseVertex b, bool trivialCasesOnly,
|
||||||
revRoseMap &rrm) {
|
RoseAliasingInfo &rai) {
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = tbi.g;
|
||||||
LeftEngInfo &a_left = g[a].left;
|
LeftEngInfo &a_left = g[a].left;
|
||||||
LeftEngInfo &b_left = g[b].left;
|
LeftEngInfo &b_left = g[b].left;
|
||||||
@ -1169,67 +1162,67 @@ bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
duplicateReport(*b_h, b_left.leftfix_report, new_report);
|
duplicateReport(*b_h, b_left.leftfix_report, new_report);
|
||||||
a_left.leftfix_report = new_report;
|
a_left.leftfix_report = new_report;
|
||||||
b_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, rai.rev_leftfix[b_left_id], a_oldreport);
|
||||||
pruneReportIfUnused(tbi, b_h, rrm[b_left_id], b_oldreport);
|
pruneReportIfUnused(tbi, b_h, rai.rev_leftfix[b_left_id], b_oldreport);
|
||||||
pruneUnusedTops(*b_h, g, rrm[b_left_id]);
|
pruneUnusedTops(*b_h, g, rai.rev_leftfix[b_left_id]);
|
||||||
assert(a_left == b_left);
|
assert(a_left == b_left);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if it is the same graph, it is also fairly easy */
|
/* 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 (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 */
|
/* nobody else is using a_h */
|
||||||
rrm[b_left_id].erase(b);
|
rai.rev_leftfix[b_left_id].erase(b);
|
||||||
rrm[a_left_id].insert(b);
|
rai.rev_leftfix[a_left_id].insert(b);
|
||||||
b_left.graph = a_h;
|
b_left.graph = a_h;
|
||||||
b_left.leftfix_report = a_left.leftfix_report;
|
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");
|
DEBUG_PRINTF("OK -> only user of a_h\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rrm[b_left_id].size() == 1) {
|
if (rai.rev_leftfix[b_left_id].size() == 1) {
|
||||||
/* nobody else is using b_h */
|
/* nobody else is using b_h */
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].insert(a);
|
rai.rev_leftfix[b_left_id].insert(a);
|
||||||
a_left.graph = b_h;
|
a_left.graph = b_h;
|
||||||
a_left.leftfix_report = b_left.leftfix_report;
|
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");
|
DEBUG_PRINTF("OK -> only user of b_h\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preds_same) {
|
if (preds_same) {
|
||||||
/* preds are the same anyway in diamond/left merges just need to
|
/* 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 */
|
* check that all the literals in rev_leftfix[b_h] can handle a_h */
|
||||||
for (auto v : rrm[b_left_id]) {
|
for (auto v : rai.rev_leftfix[b_left_id]) {
|
||||||
if (!mergeableRoseVertices(tbi, a, v)) {
|
if (!mergeableRoseVertices(tbi, a, v)) {
|
||||||
goto literal_mismatch_1;
|
goto literal_mismatch_1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].insert(a);
|
rai.rev_leftfix[b_left_id].insert(a);
|
||||||
a_left.graph = b_h;
|
a_left.graph = b_h;
|
||||||
a_left.leftfix_report = b_left.leftfix_report;
|
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");
|
DEBUG_PRINTF("OK -> same preds ???\n");
|
||||||
return true;
|
return true;
|
||||||
literal_mismatch_1:
|
literal_mismatch_1:
|
||||||
/* preds are the same anyway in diamond/left merges just need to
|
/* 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 */
|
* check that all the literals in rev_leftfix[a_h] can handle b_h */
|
||||||
for (auto v : rrm[a_left_id]) {
|
for (auto v : rai.rev_leftfix[a_left_id]) {
|
||||||
if (!mergeableRoseVertices(tbi, v, b)) {
|
if (!mergeableRoseVertices(tbi, v, b)) {
|
||||||
goto literal_mismatch_2;
|
goto literal_mismatch_2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rrm[b_left_id].erase(b);
|
rai.rev_leftfix[b_left_id].erase(b);
|
||||||
rrm[a_left_id].insert(b);
|
rai.rev_leftfix[a_left_id].insert(b);
|
||||||
b_left.graph = a_h;
|
b_left.graph = a_h;
|
||||||
b_left.leftfix_report = a_left.leftfix_report;
|
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");
|
DEBUG_PRINTF("OK -> same preds ???\n");
|
||||||
return true;
|
return true;
|
||||||
literal_mismatch_2:;
|
literal_mismatch_2:;
|
||||||
@ -1243,19 +1236,19 @@ bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
duplicateReport(*new_graph, b_left.leftfix_report, new_report);
|
duplicateReport(*new_graph, b_left.leftfix_report, new_report);
|
||||||
pruneReportIfUnused(tbi, new_graph, {}, b_left.leftfix_report);
|
pruneReportIfUnused(tbi, new_graph, {}, b_left.leftfix_report);
|
||||||
|
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].erase(b);
|
rai.rev_leftfix[b_left_id].erase(b);
|
||||||
pruneUnusedTops(*a_h, g, rrm[a_left_id]);
|
pruneUnusedTops(*a_h, g, rai.rev_leftfix[a_left_id]);
|
||||||
pruneUnusedTops(*b_h, g, rrm[b_left_id]);
|
pruneUnusedTops(*b_h, g, rai.rev_leftfix[b_left_id]);
|
||||||
|
|
||||||
a_left.leftfix_report = new_report;
|
a_left.leftfix_report = new_report;
|
||||||
b_left.leftfix_report = new_report;
|
b_left.leftfix_report = new_report;
|
||||||
a_left.graph = new_graph;
|
a_left.graph = new_graph;
|
||||||
b_left.graph = new_graph;
|
b_left.graph = new_graph;
|
||||||
|
|
||||||
rrm[a_left].insert(a);
|
rai.rev_leftfix[a_left].insert(a);
|
||||||
rrm[a_left].insert(b);
|
rai.rev_leftfix[a_left].insert(b);
|
||||||
pruneUnusedTops(*new_graph, g, rrm[a_left]);
|
pruneUnusedTops(*new_graph, g, rai.rev_leftfix[a_left]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1274,7 +1267,7 @@ bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
DEBUG_PRINTF("attempting merge of roses on vertices %zu and %zu\n",
|
DEBUG_PRINTF("attempting merge of roses on vertices %zu and %zu\n",
|
||||||
g[a].idx, g[b].idx);
|
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;
|
set<RoseVertex> aa;
|
||||||
aa.insert(a);
|
aa.insert(a);
|
||||||
|
|
||||||
@ -1296,7 +1289,7 @@ bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
ReportID new_report = tbi.getNewNfaReport();
|
ReportID new_report = tbi.getNewNfaReport();
|
||||||
duplicateReport(*b_h, b_left.leftfix_report, new_report);
|
duplicateReport(*b_h, b_left.leftfix_report, new_report);
|
||||||
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;
|
NGHolder victim;
|
||||||
cloneHolder(victim, *a_h);
|
cloneHolder(victim, *a_h);
|
||||||
@ -1337,16 +1330,16 @@ bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
a_left.graph = b_h;
|
a_left.graph = b_h;
|
||||||
a_left.leftfix_report = new_report;
|
a_left.leftfix_report = new_report;
|
||||||
|
|
||||||
assert(contains(rrm[a_left_id], a));
|
assert(contains(rai.rev_leftfix[a_left_id], a));
|
||||||
assert(contains(rrm[b_left_id], b));
|
assert(contains(rai.rev_leftfix[b_left_id], b));
|
||||||
rrm[a_left_id].erase(a);
|
rai.rev_leftfix[a_left_id].erase(a);
|
||||||
rrm[b_left_id].insert(a);
|
rai.rev_leftfix[b_left_id].insert(a);
|
||||||
|
|
||||||
pruneUnusedTops(*a_h, g, rrm[a_left_id]);
|
pruneUnusedTops(*a_h, g, rai.rev_leftfix[a_left_id]);
|
||||||
pruneUnusedTops(*b_h, g, rrm[b_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.
|
// 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);
|
reduceImplementableGraph(*b_h, SOM_NONE, nullptr, tbi.cc);
|
||||||
|
|
||||||
@ -1361,7 +1354,8 @@ bool attemptRoseGraphMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
// is not possible.
|
// is not possible.
|
||||||
static
|
static
|
||||||
bool attemptRoseMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
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",
|
DEBUG_PRINTF("attempting rose merge, vertices a=%zu, b=%zu\n",
|
||||||
tbi.g[a].idx, tbi.g[b].idx);
|
tbi.g[a].idx, tbi.g[b].idx);
|
||||||
assert(a != b);
|
assert(a != b);
|
||||||
@ -1406,12 +1400,12 @@ bool attemptRoseMerge(RoseBuildImpl &tbi, bool preds_same, RoseVertex a,
|
|||||||
|
|
||||||
if (a_left_id.graph() && b_left_id.graph()) {
|
if (a_left_id.graph() && b_left_id.graph()) {
|
||||||
return attemptRoseGraphMerge(tbi, preds_same, a, b, trivialCasesOnly,
|
return attemptRoseGraphMerge(tbi, preds_same, a, b, trivialCasesOnly,
|
||||||
rrm);
|
rai);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_left_id.castle() && b_left_id.castle()) {
|
if (a_left_id.castle() && b_left_id.castle()) {
|
||||||
return attemptRoseCastleMerge(tbi, preds_same, a, b, trivialCasesOnly,
|
return attemptRoseCastleMerge(tbi, preds_same, a, b, trivialCasesOnly,
|
||||||
rrm);
|
rai);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1557,7 +1551,7 @@ vector<vector<RoseVertex>> splitDiamondMergeBuckets(CandidateSet &candidates,
|
|||||||
static never_inline
|
static never_inline
|
||||||
void diamondMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
void diamondMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
||||||
vector<RoseVertex> *dead, bool mergeRoses,
|
vector<RoseVertex> *dead, bool mergeRoses,
|
||||||
revRoseMap &rrm) {
|
RoseAliasingInfo &rai) {
|
||||||
DEBUG_PRINTF("begin\n");
|
DEBUG_PRINTF("begin\n");
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = tbi.g;
|
||||||
|
|
||||||
@ -1580,7 +1574,7 @@ void diamondMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
|||||||
RoseVertex b = *jt;
|
RoseVertex b = *jt;
|
||||||
assert(contains(candidates, b));
|
assert(contains(candidates, b));
|
||||||
|
|
||||||
if (!sameRoleProperties(tbi, a, b)) {
|
if (!sameRoleProperties(tbi, rai, a, b)) {
|
||||||
DEBUG_PRINTF("diff role prop\n");
|
DEBUG_PRINTF("diff role prop\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1602,12 +1596,12 @@ void diamondMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attemptRoseMerge(tbi, true, a, b, !mergeRoses, rrm)) {
|
if (!attemptRoseMerge(tbi, true, a, b, !mergeRoses, rai)) {
|
||||||
DEBUG_PRINTF("rose fail\n");
|
DEBUG_PRINTF("rose fail\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeVerticesDiamond(a, b, tbi, rrm);
|
mergeVerticesDiamond(a, b, tbi, rai);
|
||||||
dead->push_back(a);
|
dead->push_back(a);
|
||||||
candidates.erase(a);
|
candidates.erase(a);
|
||||||
break; // next a
|
break; // next a
|
||||||
@ -1623,6 +1617,7 @@ vector<RoseVertex>::iterator findLeftMergeSibling(
|
|||||||
vector<RoseVertex>::iterator it,
|
vector<RoseVertex>::iterator it,
|
||||||
const vector<RoseVertex>::iterator &end,
|
const vector<RoseVertex>::iterator &end,
|
||||||
const RoseVertex a, const RoseBuildImpl &build,
|
const RoseVertex a, const RoseBuildImpl &build,
|
||||||
|
const RoseAliasingInfo &rai,
|
||||||
const CandidateSet &candidates) {
|
const CandidateSet &candidates) {
|
||||||
const RoseGraph &g = build.g;
|
const RoseGraph &g = build.g;
|
||||||
|
|
||||||
@ -1636,7 +1631,7 @@ vector<RoseVertex>::iterator findLeftMergeSibling(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sameRoleProperties(build, a, b)) {
|
if (!sameRoleProperties(build, rai, a, b)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1667,7 +1662,7 @@ vector<RoseVertex>::iterator findLeftMergeSibling(
|
|||||||
|
|
||||||
static never_inline
|
static never_inline
|
||||||
void leftMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
void leftMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
||||||
vector<RoseVertex> *dead, revRoseMap &rrm) {
|
vector<RoseVertex> *dead, RoseAliasingInfo &rai) {
|
||||||
DEBUG_PRINTF("begin (%zu)\n", candidates.size());
|
DEBUG_PRINTF("begin (%zu)\n", candidates.size());
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = tbi.g;
|
||||||
vector<RoseVertex> siblings;
|
vector<RoseVertex> siblings;
|
||||||
@ -1701,19 +1696,19 @@ void leftMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
|||||||
sort(siblings.begin(), siblings.end(), VertexIndexComp(g));
|
sort(siblings.begin(), siblings.end(), VertexIndexComp(g));
|
||||||
|
|
||||||
auto jt = findLeftMergeSibling(siblings.begin(), siblings.end(), a, tbi,
|
auto jt = findLeftMergeSibling(siblings.begin(), siblings.end(), a, tbi,
|
||||||
candidates);
|
rai, candidates);
|
||||||
if (jt == siblings.end()) {
|
if (jt == siblings.end()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoseVertex b = *jt;
|
RoseVertex b = *jt;
|
||||||
|
|
||||||
if (!attemptRoseMerge(tbi, true, a, b, 0, rrm)) {
|
if (!attemptRoseMerge(tbi, true, a, b, 0, rai)) {
|
||||||
DEBUG_PRINTF("rose fail\n");
|
DEBUG_PRINTF("rose fail\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeVertices(a, b, tbi, rrm);
|
mergeVertices(a, b, tbi, rai);
|
||||||
dead->push_back(a);
|
dead->push_back(a);
|
||||||
candidates.erase(ait);
|
candidates.erase(ait);
|
||||||
}
|
}
|
||||||
@ -1748,6 +1743,7 @@ vector<RoseVertex>::const_iterator findRightMergeSibling(
|
|||||||
vector<RoseVertex>::const_iterator it,
|
vector<RoseVertex>::const_iterator it,
|
||||||
const vector<RoseVertex>::const_iterator &end,
|
const vector<RoseVertex>::const_iterator &end,
|
||||||
const RoseVertex a, const RoseBuildImpl &build,
|
const RoseVertex a, const RoseBuildImpl &build,
|
||||||
|
const RoseAliasingInfo &rai,
|
||||||
const CandidateSet &candidates) {
|
const CandidateSet &candidates) {
|
||||||
const RoseGraph &g = build.g;
|
const RoseGraph &g = build.g;
|
||||||
|
|
||||||
@ -1761,7 +1757,7 @@ vector<RoseVertex>::const_iterator findRightMergeSibling(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sameRoleProperties(build, a, b)) {
|
if (!sameRoleProperties(build, rai, a, b)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1888,7 +1884,7 @@ const vector<RoseVertex> &getCandidateRightSiblings(
|
|||||||
static never_inline
|
static never_inline
|
||||||
void rightMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
void rightMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
||||||
vector<RoseVertex> *dead, bool mergeRoses,
|
vector<RoseVertex> *dead, bool mergeRoses,
|
||||||
revRoseMap &rrm) {
|
RoseAliasingInfo &rai) {
|
||||||
DEBUG_PRINTF("begin\n");
|
DEBUG_PRINTF("begin\n");
|
||||||
|
|
||||||
map<size_t, vector<RoseVertex> > sibling_cache;
|
map<size_t, vector<RoseVertex> > sibling_cache;
|
||||||
@ -1911,11 +1907,12 @@ void rightMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
|||||||
|
|
||||||
auto jt = siblings.begin();
|
auto jt = siblings.begin();
|
||||||
while (jt != siblings.end()) {
|
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()) {
|
if (jt == siblings.end()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (attemptRoseMerge(tbi, false, a, *jt, !mergeRoses, rrm)) {
|
if (attemptRoseMerge(tbi, false, a, *jt, !mergeRoses, rai)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++jt;
|
++jt;
|
||||||
@ -1926,7 +1923,7 @@ void rightMergePass(CandidateSet &candidates, RoseBuildImpl &tbi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RoseVertex b = *jt;
|
RoseVertex b = *jt;
|
||||||
mergeVertices(a, b, tbi, rrm);
|
mergeVertices(a, b, tbi, rai);
|
||||||
dead->push_back(a);
|
dead->push_back(a);
|
||||||
candidates.erase(ait);
|
candidates.erase(ait);
|
||||||
}
|
}
|
||||||
@ -2002,10 +1999,9 @@ void aliasRoles(RoseBuildImpl &build, bool mergeRoses) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
revRoseMap rrm;
|
|
||||||
|
|
||||||
DEBUG_PRINTF("doing role aliasing mr=%d\n", (int)mergeRoses);
|
DEBUG_PRINTF("doing role aliasing mr=%d\n", (int)mergeRoses);
|
||||||
populateRevRoseMap(g, &rrm);
|
|
||||||
|
RoseAliasingInfo rai(build);
|
||||||
|
|
||||||
mergeRoses &= cc.grey.mergeRose & cc.grey.roseMergeRosesDuringAliasing;
|
mergeRoses &= cc.grey.mergeRose & cc.grey.roseMergeRosesDuringAliasing;
|
||||||
|
|
||||||
@ -2018,8 +2014,8 @@ void aliasRoles(RoseBuildImpl &build, bool mergeRoses) {
|
|||||||
size_t old_dead_size = 0;
|
size_t old_dead_size = 0;
|
||||||
do {
|
do {
|
||||||
old_dead_size = dead.size();
|
old_dead_size = dead.size();
|
||||||
leftMergePass(candidates, build, &dead, rrm);
|
leftMergePass(candidates, build, &dead, rai);
|
||||||
rightMergePass(candidates, build, &dead, mergeRoses, rrm);
|
rightMergePass(candidates, build, &dead, mergeRoses, rai);
|
||||||
} while (old_dead_size != dead.size());
|
} while (old_dead_size != dead.size());
|
||||||
|
|
||||||
/* Diamond merge passes cannot create extra merges as they require the same
|
/* Diamond merge passes cannot create extra merges as they require the same
|
||||||
@ -2027,7 +2023,7 @@ void aliasRoles(RoseBuildImpl &build, bool mergeRoses) {
|
|||||||
* to a merge to different pred/succ before a diamond merge, it will still
|
* to a merge to different pred/succ before a diamond merge, it will still
|
||||||
* be afterwards. */
|
* be afterwards. */
|
||||||
filterDiamondCandidates(g, candidates);
|
filterDiamondCandidates(g, candidates);
|
||||||
diamondMergePass(candidates, build, &dead, mergeRoses, rrm);
|
diamondMergePass(candidates, build, &dead, mergeRoses, rai);
|
||||||
|
|
||||||
DEBUG_PRINTF("killed %zu vertices\n", dead.size());
|
DEBUG_PRINTF("killed %zu vertices\n", dead.size());
|
||||||
build.removeVertices(dead);
|
build.removeVertices(dead);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user