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);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -380,6 +417,10 @@ bool sameRoleProperties(const RoseBuildImpl &build, RoseVertex a, RoseVertex b)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sameGhostProperties(build, a, b)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* "roses are mergeable" check are handled elsewhere */
|
/* "roses are mergeable" check are handled elsewhere */
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -536,6 +577,28 @@ void mergeLiteralSets(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi) {
|
|||||||
insert(&g[b].literals, a_literals);
|
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'.
|
// Merge role 'a' into 'b'.
|
||||||
static
|
static
|
||||||
void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
||||||
@ -566,6 +629,9 @@ void mergeVertices(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mergeEdges(a, b, g);
|
mergeEdges(a, b, g);
|
||||||
|
|
||||||
|
updateGhostMap(tbi, a, b);
|
||||||
|
|
||||||
removeVertexFromMaps(a, tbi, rrm);
|
removeVertexFromMaps(a, tbi, rrm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,21 +666,7 @@ void mergeVerticesDiamond(RoseVertex a, RoseVertex b, RoseBuildImpl &tbi,
|
|||||||
|
|
||||||
static never_inline
|
static never_inline
|
||||||
void findCandidates(const RoseBuildImpl &tbi, CandidateSet *candidates) {
|
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)) {
|
for (auto v : vertices_range(tbi.g)) {
|
||||||
// Ignore ghost relationships.
|
|
||||||
if (contains(disallowed, v)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAliasingCandidate(v, tbi)) {
|
if (isAliasingCandidate(v, tbi)) {
|
||||||
DEBUG_PRINTF("candidate %zu\n", tbi.g[v].idx);
|
DEBUG_PRINTF("candidate %zu\n", tbi.g[v].idx);
|
||||||
DEBUG_PRINTF("lits: %u\n", *tbi.g[v].literals.begin());
|
DEBUG_PRINTF("lits: %u\n", *tbi.g[v].literals.begin());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user