[ dwarfdump ] Add symbolic dump of known DWARF attribute values.
[oota-llvm.git] / include / llvm / Support / GenericDomTree.h
index 55dcb94635a6e0c352b837206207f75b2ab345c0..6bc4b4425e71a06348b4677d478518d99b677f49 100644 (file)
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_H
-#define LLVM_SUPPORT_GENERIC_DOM_TREE_H
+#ifndef LLVM_SUPPORT_GENERICDOMTREE_H
+#define LLVM_SUPPORT_GENERICDOMTREE_H
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/CFG.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -65,7 +64,7 @@ class DomTreeNodeBase {
   NodeT *TheBB;
   DomTreeNodeBase<NodeT> *IDom;
   std::vector<DomTreeNodeBase<NodeT> *> Children;
-  int DFSNumIn, DFSNumOut;
+  mutable int DFSNumIn, DFSNumOut;
 
   template<class N> friend class DominatorTreeBase;
   friend struct PostDominatorTree;
@@ -187,9 +186,9 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
     assert(isReachableFromEntry(A));
 
     const DomTreeNodeBase<NodeT> *IDom;
-    while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
+    while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B)
       B = IDom;   // Walk up the tree
-    return IDom != 0;
+    return IDom != nullptr;
   }
 
 protected:
@@ -197,8 +196,8 @@ protected:
   DomTreeNodeMapType DomTreeNodes;
   DomTreeNodeBase<NodeT> *RootNode;
 
-  bool DFSInfoValid;
-  unsigned int SlowQueries;
+  mutable bool DFSInfoValid;
+  mutable unsigned int SlowQueries;
   // Information record used during immediate dominators computation.
   struct InfoRec {
     unsigned DFSNum;
@@ -206,7 +205,7 @@ protected:
     unsigned Semi;
     NodeT *Label;
 
-    InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(0) {}
+    InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {}
   };
 
   DenseMap<NodeT*, NodeT*> IDoms;
@@ -225,7 +224,7 @@ protected:
     IDoms.clear();
     this->Roots.clear();
     Vertex.clear();
-    RootNode = 0;
+    RootNode = nullptr;
   }
 
   // NewBB is split and now it has one successor. Update dominator tree to
@@ -261,7 +260,7 @@ protected:
 
     // Find NewBB's immediate dominator and create new dominator tree node for
     // NewBB.
-    NodeT *NewBBIDom = 0;
+    NodeT *NewBBIDom = nullptr;
     unsigned i = 0;
     for (i = 0; i < PredBlocks.size(); ++i)
       if (DT.isReachableFromEntry(PredBlocks[i])) {
@@ -298,7 +297,7 @@ public:
 
   /// compare - Return false if the other dominator tree base matches this
   /// dominator tree base. Otherwise return true.
-  bool compare(DominatorTreeBase &Other) const {
+  bool compare(const DominatorTreeBase &Other) const {
 
     const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
     if (DomTreeNodes.size() != OtherDomTreeNodes.size())
@@ -331,6 +330,10 @@ public:
     return DomTreeNodes.lookup(BB);
   }
 
+  inline DomTreeNodeBase<NodeT> *operator[](NodeT *BB) const {
+    return getNode(BB);
+  }
+
   /// getRootNode - This returns the entry node for the CFG of the function.  If
   /// this tree represents the post-dominance relations for a function, however,
   /// this root may be a node with the block == NULL.  This is the case when
@@ -345,7 +348,7 @@ public:
   void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
     Result.clear();
     const DomTreeNodeBase<NodeT> *RN = getNode(R);
-    if (RN == NULL)
+    if (!RN)
       return; // If R is unreachable, it will not be present in the DOM tree.
     SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
     WL.push_back(RN);
@@ -361,15 +364,15 @@ public:
   /// Note that this is not a constant time operation!
   ///
   bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
-                         const DomTreeNodeBase<NodeT> *B) {
-    if (A == 0 || B == 0)
+                         const DomTreeNodeBase<NodeT> *B) const {
+    if (!A || !B)
       return false;
     if (A == B)
       return false;
     return dominates(A, B);
   }
 
-  bool properlyDominates(const NodeT *A, const NodeT *B);
+  bool properlyDominates(const NodeT *A, const NodeT *B) const;
 
   /// isReachableFromEntry - Return true if A is dominated by the entry
   /// block of the function containing it.
@@ -387,7 +390,7 @@ public:
   /// constant time operation!
   ///
   inline bool dominates(const DomTreeNodeBase<NodeT> *A,
-                        const DomTreeNodeBase<NodeT> *B) {
+                        const DomTreeNodeBase<NodeT> *B) const {
     // A node trivially dominates itself.
     if (B == A)
       return true;
@@ -422,7 +425,7 @@ public:
     return dominatedBySlowTreeWalk(A, B);
   }
 
-  bool dominates(const NodeT *A, const NodeT *B);
+  bool dominates(const NodeT *A, const NodeT *B) const;
 
   NodeT *getRoot() const {
     assert(this->Roots.size() == 1 && "Should always have entry node!");
@@ -454,6 +457,21 @@ public:
     DomTreeNodeBase<NodeT> *NodeA = getNode(A);
     DomTreeNodeBase<NodeT> *NodeB = getNode(B);
 
+    // If we have DFS info, then we can avoid all allocations by just querying
+    // it from each IDom. Note that because we call 'dominates' twice above, we
+    // expect to call through this code at most 16 times in a row without
+    // building valid DFS information. This is important as below is a *very*
+    // slow tree walk.
+    if (DFSInfoValid) {
+      DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
+      while (IDomA) {
+        if (NodeB->DominatedBy(IDomA))
+          return IDomA->getBlock();
+        IDomA = IDomA->getIDom();
+      }
+      return nullptr;
+    }
+
     // Collect NodeA dominators set.
     SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms;
     NodeADoms.insert(NodeA);
@@ -472,7 +490,7 @@ public:
       IDomB = IDomB->getIDom();
     }
 
-    return NULL;
+    return nullptr;
   }
 
   const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
@@ -490,7 +508,7 @@ public:
   /// creates a new node as a child of DomBB dominator node,linking it into
   /// the children list of the immediate dominator.
   DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
-    assert(getNode(BB) == 0 && "Block already in dominator tree!");
+    assert(getNode(BB) == nullptr && "Block already in dominator tree!");
     DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
     assert(IDomNode && "Not immediate dominator specified for block!");
     DFSInfoValid = false;
@@ -587,13 +605,13 @@ protected:
 
   /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
   /// dominator tree in dfs order.
-  void updateDFSNumbers() {
+  void updateDFSNumbers() const {
     unsigned DFSNum = 0;
 
-    SmallVector<std::pair<DomTreeNodeBase<NodeT>*,
-                typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;
+    SmallVector<std::pair<const DomTreeNodeBase<NodeT>*,
+                typename DomTreeNodeBase<NodeT>::const_iterator>, 32> WorkStack;
 
-    DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
+    const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
 
     if (!ThisRoot)
       return;
@@ -606,8 +624,8 @@ protected:
     ThisRoot->DFSNumIn = DFSNum++;
 
     while (!WorkStack.empty()) {
-      DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
-      typename DomTreeNodeBase<NodeT>::iterator ChildIt =
+      const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
+      typename DomTreeNodeBase<NodeT>::const_iterator ChildIt =
         WorkStack.back().second;
 
       // If we visited all of the children of this node, "recurse" back up the
@@ -617,7 +635,7 @@ protected:
         WorkStack.pop_back();
       } else {
         // Otherwise, recursively visit this child.
-        DomTreeNodeBase<NodeT> *Child = *ChildIt;
+        const DomTreeNodeBase<NodeT> *Child = *ChildIt;
         ++WorkStack.back().second;
 
         WorkStack.push_back(std::make_pair(Child, Child->begin()));
@@ -637,7 +655,7 @@ protected:
     // immediate dominator.
     NodeT *IDom = getIDom(BB);
 
-    assert(IDom || this->DomTreeNodes[NULL]);
+    assert(IDom || this->DomTreeNodes[nullptr]);
     DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
 
     // Add a new tree node for this NodeT, and link it as a child of
@@ -660,14 +678,14 @@ public:
   void recalculate(FT& F) {
     typedef GraphTraits<FT*> TraitsTy;
     reset();
-    this->Vertex.push_back(0);
+    this->Vertex.push_back(nullptr);
 
     if (!this->IsPostDominators) {
       // Initialize root
       NodeT *entry = TraitsTy::getEntryNode(&F);
       this->Roots.push_back(entry);
-      this->IDoms[entry] = 0;
-      this->DomTreeNodes[entry] = 0;
+      this->IDoms[entry] = nullptr;
+      this->DomTreeNodes[entry] = nullptr;
 
       Calculate<FT, NodeT*>(*this, F);
     } else {
@@ -678,8 +696,8 @@ public:
           addRoot(I);
 
         // Prepopulate maps so that we don't get iterator invalidation issues later.
-        this->IDoms[I] = 0;
-        this->DomTreeNodes[I] = 0;
+        this->IDoms[I] = nullptr;
+        this->DomTreeNodes[I] = nullptr;
       }
 
       Calculate<FT, Inverse<NodeT*> >(*this, F);
@@ -690,7 +708,7 @@ public:
 // These two functions are declared out of line as a workaround for building
 // with old (< r147295) versions of clang because of pr11642.
 template<class NodeT>
-bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) {
+bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
   if (A == B)
     return true;
 
@@ -702,7 +720,7 @@ bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) {
 }
 template<class NodeT>
 bool
-DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) {
+DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) const {
   if (A == B)
     return false;