Add and use DominatorTreeBase::findNearestCommonDominator().
authorDevang Patel <dpatel@apple.com>
Mon, 11 Jun 2007 23:31:22 +0000 (23:31 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 11 Jun 2007 23:31:22 +0000 (23:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37545 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/Dominators.h
lib/Transforms/Utils/LoopSimplify.cpp
lib/VMCore/Dominators.cpp

index f1d31eb87e6feaf82598e7bdb91c1ee8ba8d22f3..755407b40d964421d7e514dff93c5312bfb967d7 100644 (file)
@@ -234,6 +234,10 @@ protected:
     return dominates(getNode(A), getNode(B));
   }
 
+  /// findNearestCommonDominator - Find nearest common dominator basic block
+  /// for basic block A and B. If there is no such block then return NULL.
+  BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B);
+
   // dominates - Return true if A dominates B. This performs the
   // special checks necessary if A and B are in the same basic block.
   bool dominates(Instruction *A, Instruction *B);
index 98ec288e18acad4067a0410adc9ca854e99ba9e7..7e1281213b652c2ad86259c23df83f73bfe5bea5 100644 (file)
@@ -768,7 +768,7 @@ void LoopSimplify::UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB,
   assert(i != PredBlocks.size() && "No reachable preds?");
   for (i = i + 1; i < PredBlocks.size(); ++i) {
     if (DT.isReachableFromEntry(PredBlocks[i]))
-      NewBBIDom = DT.nearestCommonDominator(NewBBIDom, PredBlocks[i]);
+      NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
   }
   assert(NewBBIDom && "No immediate dominator found??");
   
index 32c435b2c6020cdc79a4b30af3c4a09ec95f2ac5..8b2c1a45e223a5c799003100a5348fe510ebfc7e 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/Instructions.h"
 #include "llvm/Support/Streams.h"
 #include <algorithm>
+#include <set>
 using namespace llvm;
 
 namespace llvm {
@@ -369,6 +370,50 @@ void DominatorTreeBase::reset() {
   RootNode = 0;
 }
 
+/// findNearestCommonDominator - Find nearest common dominator basic block
+/// for basic block A and B. If there is no such block then return NULL.
+BasicBlock *DominatorTreeBase::findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
+
+  assert (!isPostDominator()  && "This is not implemented for post dominators");
+  assert (A->getParent() == B->getParent()  && "Two blocks are not in same function");
+
+  // If either A or B is a entry block then it is nearest common dominator.
+  BasicBlock &Entry  = A->getParent()->getEntryBlock();
+  if (A == &Entry || B == &Entry)
+    return &Entry;
+
+  // If A and B are same then A is nearest common dominator.
+  DomTreeNode *NodeA = getNode(A);
+  if (A != 0 && A == B)
+    return A;
+
+  DomTreeNode *NodeB = getNode(B);
+
+  // Collect NodeA dominators set.
+  std::set<DomTreeNode *> NodeADoms;
+  NodeADoms.insert(NodeA);
+  DomTreeNode *IDomA = NodeA->getIDom();
+  while(IDomA) {
+    NodeADoms.insert(IDomA);
+    IDomA = IDomA->getIDom();
+  }
+
+  // If B dominates A then B is nearest common dominator.
+  if (NodeADoms.count(NodeB) != 0)
+    return B;
+
+  // Walk NodeB immediate dominators chain and find common dominator node.
+  DomTreeNode *IDomB = NodeB->getIDom();
+  while(IDomB) {
+    if (NodeADoms.count(IDomB) != 0)
+      return IDomB->getBlock();
+
+    IDomB = IDomB->getIDom();
+  }
+
+  return NULL;
+}
+
 void DomTreeNode::setIDom(DomTreeNode *NewIDom) {
   assert(IDom && "No immediate dominator?");
   if (IDom != NewIDom) {