>From c79c6ecc9b1028cab4e062ba46fb8b0242f6053f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?=
 <rafael.espindola@gmail.com>
Date: Mon, 20 Feb 2012 23:34:48 -0500
Subject: [PATCH 2/3] Fix the implementation.

---
 include/llvm/Analysis/Dominators.h |   12 +++-
 lib/VMCore/Dominators.cpp          |  112 +++++++++++++++++++++++++++++------
 2 files changed, 100 insertions(+), 24 deletions(-)

diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index 6a06b1b..a26946d 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -749,14 +749,18 @@ public:
     return DT->dominates(A, B);
   }
 
-  // dominatesUse - Return true if A dominates a use in B. This performs the
-  // special checks necessary if A and B are in the same basic block.
-  bool dominatesUse(const Instruction *A, const Instruction *B) const;
+  // dominatesUse - Return true if Def dominates a use in User. This performs
+  // the special checks necessary if Def and User are in the same basic block.
+  // Note that Def doesn't dominate a use in Def itself!
+  bool dominatesUse(const Instruction *Def, const Instruction *User) const;
+  bool dominatesUse(const Instruction *Def, const BasicBlock *BB) const;
 
   /// properlyDominates - Use this instead of dominates() to determine whether a
   /// user of A can be hoisted above B.
   bool properlyDominates(const Instruction *A, const Instruction *B) const {
-    return A != B && dominatesUse(A, B);
+    // Since A doesn't dominate a use in A, we don't need the extra A != B
+    // check.
+    return dominatesUse(A, B);
   }
 
   bool properlyDominates(const DomTreeNode *A, const DomTreeNode *B) const {
diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp
index 3dd192f..1c9fee9 100644
--- a/lib/VMCore/Dominators.cpp
+++ b/lib/VMCore/Dominators.cpp
@@ -80,28 +80,100 @@ void DominatorTree::print(raw_ostream &OS, const Module *) const {
   DT->print(OS);
 }
 
-// dominatesUse - Return true if A dominates a use in B. This performs the
-// special checks necessary if A and B are in the same basic block.
-bool DominatorTree::dominatesUse(const Instruction *A,
-                                 const Instruction *B) const {
-  const BasicBlock *BBA = A->getParent(), *BBB = B->getParent();
-
-  // If A is an invoke instruction, its value is only available in this normal
-  // successor block.
-  if (const InvokeInst *II = dyn_cast<InvokeInst>(A))
-    BBA = II->getNormalDest();
-
-  if (BBA != BBB) return dominates(BBA, BBB);
-
-  // It is not possible to determine dominance between two PHI nodes
-  // based on their ordering.
-  if (isa<PHINode>(A) && isa<PHINode>(B))
+// dominatesUse - Return true if Def dominates a use in User. This performs
+// the special checks necessary if Def and User are in the same basic block.
+// Note that Def doesn't dominate a use in Def itself!
+bool DominatorTree::dominatesUse(const Instruction *Def,
+                                 const Instruction *User) const {
+  const BasicBlock *DefBB = Def->getParent();
+  const BasicBlock *UseBB = User->getParent();
+
+  const InvokeInst *II = dyn_cast<InvokeInst>(Def);
+
+  const PHINode *PN = dyn_cast<PHINode>(User);
+  if (PN) {
+    // PHI nodes are more difficult than other nodes because they actually
+    // "use" the value in the predecessor basic blocks they correspond to.
+    // Since this interface doesn't know which use to check, we conservatively
+    // check all.
+    for (const_pred_iterator PI = pred_begin(UseBB), E = pred_end(UseBB);
+         PI != E; ++PI) {
+      // An invoke instruction dominates the use in a phi in the normal
+      // destination block.
+      if (*PI == DefBB && II)
+        continue;
+      if (!dominatesUse(Def, *PI))
+        return false;
+    }
+    return true;
+  }
+
+  // An instruction doesn't dominate a use in itself.
+  if (Def == User)
     return false;
 
-  // Loop through the basic block until we find A or B.
-  BasicBlock::const_iterator I = BBA->begin();
-  for (; &*I != A && &*I != B; ++I)
+  if (II)
+    return dominatesUse(II, UseBB);
+
+  if (DefBB != UseBB)
+    return dominates(DefBB, UseBB);
+
+  // Loop through the basic block until we find Def or User.
+  BasicBlock::const_iterator I = DefBB->begin();
+  for (; &*I != Def && &*I != User; ++I)
     /*empty*/;
 
-  return &*I == A;
+  return &*I == Def;
+}
+
+// true if Def would dominate a use *at the end* of UseBB.
+// note that dominatesUse(Def, Def->getParent()) is true for non-invoke.
+bool DominatorTree::dominatesUse(const Instruction *Def,
+                                 const BasicBlock *UseBB) const {
+  const BasicBlock *DefBB = Def->getParent();
+  if (const InvokeInst *II = dyn_cast<InvokeInst>(Def)) {
+    // Invoke results are only usable in the normal destination, not in the
+    // exceptional destination.
+    BasicBlock *NormalDest = II->getNormalDest();
+    // FIXME: the verifier has an extra  "!DT->isReachableFromEntry(UseBlock)",
+    // but everything dominates an unreachable block!
+    if (!dominates(NormalDest, UseBB))
+      return false;
+
+    // Simple case: if the normal destination has a single predecessor, the
+    // fact that it dominates the use block implies that we also do.
+    if (NormalDest->getSinglePredecessor())
+      return true;
+
+    // The normal edge from the invoke is critical. Conceptually, what we would
+    // like to do is split it and check if the new block dominates the use.
+    // With X being the new block, the graph would look like:
+    //
+    //        DefBB
+    //          /\      .  .
+    //         /  \     .  .
+    //        /    \    .  .
+    //       /      \   |  |
+    //      A        X  B  C
+    //      |         \ | /
+    //      .          \|/
+    //      .      NormalDest
+    //      .
+    //
+    // Given the definition of dominance, NormalDest is dominated by X iff X
+    // dominates all of NormalDest's predecessors (X, B, C in the example). X
+    // trivially dominates itself, so we only have to find if it dominates the
+    // other predecessors. Since the only way out of X is via NormalDest, X can
+    // only properly dominate a node if NormalDest dominates that node too.
+    for (pred_iterator PI = pred_begin(NormalDest),
+           E = pred_end(NormalDest); PI != E; ++PI) {
+      if (*PI != DefBB)
+        continue;
+      if (!dominates(NormalDest, *PI))
+        return false;
+    }
+    return true;
+  }
+
+  return dominates(DefBB, UseBB);
 }
-- 
1.7.7.6

