mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
rose: allow ghosts to be aliased
This commit is contained in:
parent
e915ca21c5
commit
0749f7c06d
@ -348,8 +348,45 @@ bool isAliasingCandidate(RoseVertex v, const RoseBuildImpl &tbi) {
|
||||
}
|
||||
|
||||
assert(*props.literals.begin() != MO_INVALID_IDX);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Any vertex involved in a "ghost" relationship has already been disallowed
|
||||
static
|
||||
bool sameGhostProperties(const RoseBuildImpl &build, 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)) {
|
||||
DEBUG_PRINTF("checking ghost key compat\n");
|
||||
if (!contains(build.ghost, a) || !contains(build.ghost, b)) {
|
||||
DEBUG_PRINTF("missing ghost mapping\n");
|
||||
return false;
|
||||
}
|
||||
if (build.ghost.at(a) != build.ghost.at(b)) {
|
||||
DEBUG_PRINTF("diff ghost mapping\n");
|
||||
return false;
|
||||
}
|
||||
DEBUG_PRINTF("ghost mappings ok\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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 (!ghost_a.empty() || !ghost_a.empty()) {
|
||||
DEBUG_PRINTF("ghost map targets\n");
|
||||
if (build.g[a].literals != build.g[b].literals) {
|
||||
DEBUG_PRINTF("diff literals\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -380,6 +417,10 @@ bool sameRoleProperties(const RoseBuildImpl &build, RoseVertex a, RoseVertex b)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameGhostProperties(build, a, b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* "roses are mergeable" check are handled elsewhere */
|
||||
|
||||
return true;
|
||||
@ -536,6 +577,28 @@ void mergeLiteralSets(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi) {
|
||||
insert(&g[b].literals, a_literals);
|
||||
}
|
||||
|
||||
static
|
||||
void updateGhostMap(RoseBuildImpl &build, RoseVertex a, RoseVertex b) {
|
||||
// Ghost keys.
|
||||
if (contains(build.ghost, a)) {
|
||||
auto it = build.ghost.find(a);
|
||||
assert(it->second == build.ghost[b]);
|
||||
build.ghost.erase(it);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
for (const auto &v : ghost_refs) {
|
||||
build.ghost.erase(v);
|
||||
build.ghost.emplace(v, b);
|
||||
}
|
||||
}
|
||||
|
||||
// Merge role 'a' into 'b'.
|
||||
static
|
||||
void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
||||
@ -566,6 +629,9 @@ void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
||||
}
|
||||
|
||||
mergeEdges(a, b, g);
|
||||
|
||||
updateGhostMap(tbi, a, b);
|
||||
|
||||
removeVertexFromMaps(a, tbi, rrm);
|
||||
}
|
||||
|
||||
@ -600,21 +666,7 @@ void mergeVerticesDiamond(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
||||
|
||||
static never_inline
|
||||
void findCandidates(const RoseBuildImpl &tbi, CandidateSet *candidates) {
|
||||
ue2::unordered_set<RoseVertex> disallowed;
|
||||
|
||||
// We currently deny candidature to any vertex involved in a "ghost"
|
||||
// relationship.
|
||||
for (const auto &m : tbi.ghost) {
|
||||
disallowed.insert(m.first);
|
||||
disallowed.insert(m.second);
|
||||
}
|
||||
|
||||
for (auto v : vertices_range(tbi.g)) {
|
||||
// Ignore ghost relationships.
|
||||
if (contains(disallowed, v)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isAliasingCandidate(v, tbi)) {
|
||||
DEBUG_PRINTF("candidate %zu\n", tbi.g[v].idx);
|
||||
DEBUG_PRINTF("lits: %u\n", *tbi.g[v].literals.begin());
|
||||
|
Loading…
x
Reference in New Issue
Block a user