[llvm-commits] [llvm] r122680 - in /llvm/trunk/include/llvm/Analysis: DominatorInternals.h Dominators.h

Cameron Zwarich zwarich at apple.com
Sat Jan 1 23:03:00 PST 2011


Author: zwarich
Date: Sun Jan  2 01:03:00 2011
New Revision: 122680

URL: http://llvm.org/viewvc/llvm-project?rev=122680&view=rev
Log:
Speed up dominator computation some more by optimizing bucket processing. When
naively implemented, the Lengauer-Tarjan algorithm requires a separate bucket
for each vertex. However, this is unnecessary, because each vertex is only
placed into a single bucket (that of its semidominator), and each vertex's
bucket is processed before it is added to any bucket itself.

Instead of using a bucket per vertex, we use a single array Buckets that has two
purposes. Before the vertex V with DFS number i is processed, Buckets[i] stores
the index of the first element in V's bucket. After V's bucket is processed,
Buckets[i] stores the index of the next element in the bucket to which V now
belongs, if any.

Reading from the buckets can also be optimized. Instead of processing the bucket
of V's parent at the end of processing V, we process the bucket of V itself at
the beginning of processing V. This means that the case of the root vertex can
be simplified somewhat. It also means that we don't need to look up the DFS
number of the semidominator of every node in the bucket we are processing,
since we know it is the current index being processed.

This is a 6.5% speedup running -domtree on test-suite + SPEC2000/2006, with
larger speedups of around 12% on the larger benchmarks like GCC.

Modified:
    llvm/trunk/include/llvm/Analysis/DominatorInternals.h
    llvm/trunk/include/llvm/Analysis/Dominators.h

Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=122680&r1=122679&r2=122680&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original)
+++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan  2 01:03:00 2011
@@ -257,12 +257,24 @@
   // infinite loops). In these cases an artificial exit node is required.
   MultipleRoots |= (DT.isPostDominator() && N != F.size());
 
+  std::vector<unsigned> Buckets;
+  Buckets.reserve(N + 1);
+  for (unsigned i = 1; i <= N; ++i)
+    Buckets[i] = i;
+
   for (unsigned i = N; i >= 2; --i) {
     typename GraphT::NodeType* W = DT.Vertex[i];
     typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
                                                                      DT.Info[W];
 
-    // Step #2: Calculate the semidominators of all vertices
+    // Step #2: Implicitly define the immediate dominator of vertices
+    for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
+       typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+       typename GraphT::NodeType* U = Eval<GraphT>(DT, V);
+       DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
+    }
+
+    // Step #3: Calculate the semidominators of all vertices
 
     // initialize the semi dominator to point to the parent node
     WInfo.Semi = WInfo.Parent;
@@ -283,21 +295,21 @@
     // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
     // necessarily parent(V). In this case, set idom(V) here and avoid placing
     // V into a bucket.
-    if (WInfo.Semi == WInfo.Parent)
+    if (WInfo.Semi == WInfo.Parent) {
       DT.IDoms[W] = WParent;
-    else
-      DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W);
+    } else {
+      Buckets[i] = Buckets[WInfo.Semi];
+      Buckets[WInfo.Semi] = i;
+    }
 
     Link<GraphT>(DT, WInfo.Parent, W, WInfo);
+  }
 
-    // Step #3: Implicitly define the immediate dominator of vertices
-    std::vector<typename GraphT::NodeType*> &WParentBucket =
-                                                        DT.Info[WParent].Bucket;
-    while (!WParentBucket.empty()) {
-      typename GraphT::NodeType* V = WParentBucket.back();
-      WParentBucket.pop_back();
-      typename GraphT::NodeType* U = Eval<GraphT>(DT, V);
-      DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent;
+  if (N >= 1) {
+    typename GraphT::NodeType* Root = DT.Vertex[1];
+    for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
+       typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+       DT.IDoms[V] = Root;
     }
   }
 

Modified: llvm/trunk/include/llvm/Analysis/Dominators.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=122680&r1=122679&r2=122680&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/Dominators.h (original)
+++ llvm/trunk/include/llvm/Analysis/Dominators.h Sun Jan  2 01:03:00 2011
@@ -210,8 +210,6 @@
     NodeT *Label, *Child;
     unsigned Parent, Ancestor;
 
-    std::vector<NodeT*> Bucket;
-
     InfoRec() : DFSNum(0), Semi(0), Size(0), Label(0), Child(0), Parent(0),
                 Ancestor(0) {}
   };





More information about the llvm-commits mailing list