]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
rose: allow ghosts to be aliased
authorJustin Viiret <justin.viiret@intel.com>
Mon, 20 Jun 2016 00:17:38 +0000 (10:17 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Fri, 8 Jul 2016 00:59:40 +0000 (10:59 +1000)
src/rose/rose_build_role_aliasing.cpp

index 8e883ab914dc6ac5f7b4ddba768b6a33c1144b29..cbd56b9062b1cdabaf2a67b7b4a1919f76c02e0f 100644 (file)
@@ -348,8 +348,45 @@ bool isAliasingCandidate(RoseVertex v, const RoseBuildImpl &tbi) {
     }
 
     assert(*props.literals.begin() != MO_INVALID_IDX);
+    return true;
+}
+
+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;
+    }
 
-    // Any vertex involved in a "ghost" relationship has already been disallowed
+    // 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());