[llvm] r207217 - [LCG] During the incremental update of an SCC, switch to using the

Chandler Carruth chandlerc at gmail.com
Fri Apr 25 02:52:44 PDT 2014


Author: chandlerc
Date: Fri Apr 25 04:52:44 2014
New Revision: 207217

URL: http://llvm.org/viewvc/llvm-project?rev=207217&view=rev
Log:
[LCG] During the incremental update of an SCC, switch to using the
SCCMap to test for nodes that have been re-added to the root SCC rather
than a set vector. We already have done the SCCMap lookup, we juts need
to test it in two different ways. In turn, do most of the processing of
these nodes as they go into the root SCC rather than lazily. This
simplifies the final loop to just stitch the root SCC into its
children's parent sets. No functionlatiy changed.

However, this makes a few things painfully obvious, which was my intent.
=] There is tons of repeated code introduced here and elsewhere. I'm
splitting the refactoring of that code into helpers from this change so
its clear that this is the change which switches the datastructures used
around, and the other is a pure factoring & deduplication of code
change.

Modified:
    llvm/trunk/lib/Analysis/LazyCallGraph.cpp

Modified: llvm/trunk/lib/Analysis/LazyCallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyCallGraph.cpp?rev=207217&r1=207216&r2=207217&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LazyCallGraph.cpp (original)
+++ llvm/trunk/lib/Analysis/LazyCallGraph.cpp Fri Apr 25 04:52:44 2014
@@ -203,8 +203,9 @@ LazyCallGraph::SCC::removeInternalEdge(L
   // incrementally add any chain of nodes which reaches something in the new
   // node set to the new node set. This short circuits one side of the Tarjan's
   // walk.
-  SmallSetVector<Node *, 1> NewNodes;
-  NewNodes.insert(&Callee);
+  Nodes.push_back(&Callee);
+  G.SCCMap.insert(std::make_pair(&Callee, this));
+  Callee.DFSNumber = Callee.LowLink = -1;
 
   for (;;) {
     if (DFSStack.empty()) {
@@ -229,24 +230,31 @@ LazyCallGraph::SCC::removeInternalEdge(L
     bool Recurse = false;
     for (auto I = DFSStack.back().second, E = N->end(); I != E; ++I) {
       Node &ChildN = *I;
-      // If this child isn't currently in this SCC, no need to process it.
-      // However, we do need to remove this SCC from its SCC's parent set.
       if (SCC *ChildSCC = G.SCCMap.lookup(&ChildN)) {
+        // Check if we have reached a node in the new (known connected) set of
+        // this SCC. If so, the entire stack is necessarily in that set and we
+        // can re-start.
+        if (ChildSCC == this) {
+          while (!PendingSCCStack.empty()) {
+            Nodes.push_back(PendingSCCStack.pop_back_val());
+            G.SCCMap.insert(std::make_pair(Nodes.back(), this));
+            Nodes.back()->DFSNumber = Nodes.back()->LowLink = -1;
+          }
+          while (!DFSStack.empty()) {
+            Nodes.push_back(DFSStack.pop_back_val().first);
+            G.SCCMap.insert(std::make_pair(Nodes.back(), this));
+            Nodes.back()->DFSNumber = Nodes.back()->LowLink = -1;
+          }
+          Recurse = true;
+          break;
+        }
+
+        // If this child isn't currently in this SCC, no need to process it.
+        // However, we do need to remove this SCC from its SCC's parent set.
         ChildSCC->ParentSCCs.erase(this);
         continue;
       }
 
-      // Check if we have reached a node in the new (known connected) set. If
-      // so, the entire stack is necessarily in that set and we can re-start.
-      if (NewNodes.count(&ChildN)) {
-        while (!PendingSCCStack.empty())
-          NewNodes.insert(PendingSCCStack.pop_back_val());
-        while (!DFSStack.empty())
-          NewNodes.insert(DFSStack.pop_back_val().first);
-        Recurse = true;
-        break;
-      }
-
       if (ChildN.DFSNumber == 0) {
         // Mark that we should start at this child when next this node is the
         // top of the stack. We don't start at the next child to ensure this
@@ -288,21 +296,13 @@ LazyCallGraph::SCC::removeInternalEdge(L
     PendingSCCStack.push_back(N);
   }
 
-  // Replace this SCC with the NewNodes we collected above.
-  // FIXME: Simplify this when the SCC's datastructure is just a list.
-  Nodes.clear();
-
   // Now we need to reconnect the current SCC to the graph.
   bool IsLeafSCC = true;
-  for (Node *N : NewNodes) {
-    N->DFSNumber = -1;
-    N->LowLink = -1;
-    Nodes.push_back(N);
-    G.SCCMap.insert(std::make_pair(N, this));
+  for (Node *N : Nodes) {
     for (Node &ChildN : *N) {
-      if (NewNodes.count(&ChildN))
-        continue;
       SCC &ChildSCC = *G.SCCMap.lookup(&ChildN);
+      if (&ChildSCC == this)
+        continue;
       ChildSCC.ParentSCCs.insert(this);
       IsLeafSCC = false;
     }





More information about the llvm-commits mailing list