Insert loop into LQ before visiting children.
[oota-llvm.git] / lib / Analysis / PostDominators.cpp
index b0b2374317dbd2716890fc2a8d570329ab2ba1aa..d1fe9dd7f6614ef8e8e4be6eca4db92437922d73 100644 (file)
@@ -16,7 +16,6 @@
 #include "llvm/Support/CFG.h"
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/SetOperations.h"
-#include <iostream>
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -28,36 +27,49 @@ D("postidom", "Immediate Post-Dominators Construction", true);
 
 unsigned ImmediatePostDominators::DFSPass(BasicBlock *V, InfoRec &VInfo,
                                           unsigned N) {
-
   std::vector<std::pair<BasicBlock *, InfoRec *> > workStack;
+  std::set<BasicBlock *> visited;
   workStack.push_back(std::make_pair(V, &VInfo));
 
   do {
     BasicBlock *currentBB = workStack.back().first; 
     InfoRec *currentVInfo = workStack.back().second;
-    workStack.pop_back();
-
-    currentVInfo->Semi = ++N;
-    currentVInfo->Label = currentBB;
 
-    Vertex.push_back(currentBB);  // Vertex[n] = current;
-                                  // Info[currentBB].Ancestor = 0;     
-                                  // Ancestor[n] = 0
-                                  // Child[currentBB] = 0;
-    currentVInfo->Size = 1;       // Size[currentBB] = 1
+    // Visit each block only once.
+    if (visited.count(currentBB) == 0) {
+
+      visited.insert(currentBB);
+      currentVInfo->Semi = ++N;
+      currentVInfo->Label = currentBB;
+      
+      Vertex.push_back(currentBB);  // Vertex[n] = current;
+      // Info[currentBB].Ancestor = 0;     
+      // Ancestor[n] = 0
+      // Child[currentBB] = 0;
+      currentVInfo->Size = 1;       // Size[currentBB] = 1
+    }
 
-    // For PostDominators, we want to walk predecessors rather than successors
-    // as we do in forward Dominators.
+    // Visit children
+    bool visitChild = false;
     for (pred_iterator PI = pred_begin(currentBB), PE = pred_end(currentBB); 
-        PI != PE; ++PI) {
+         PI != PE && !visitChild; ++PI) {
       InfoRec &SuccVInfo = Info[*PI];
       if (SuccVInfo.Semi == 0) {
-       SuccVInfo.Parent = currentBB;
-
-       workStack.push_back(std::make_pair(*PI, &SuccVInfo));   
+        SuccVInfo.Parent = currentBB;
+        if (visited.count (*PI) == 0) {
+          workStack.push_back(std::make_pair(*PI, &SuccVInfo));   
+          visitChild = true;
+        }
       }
     }
+
+    // If all children are visited or if this block has no child then pop this
+    // block out of workStack.
+    if (!visitChild)
+      workStack.pop_back();
+
   } while (!workStack.empty());
+
   return N;
 }