OSDN Git Service

[Dominators] Move SemiNCAInfo and helper functions out of DominatorTreeBase
authorJakub Kuderski <kubakuderski@gmail.com>
Wed, 28 Jun 2017 18:00:36 +0000 (18:00 +0000)
committerJakub Kuderski <kubakuderski@gmail.com>
Wed, 28 Jun 2017 18:00:36 +0000 (18:00 +0000)
Summary:
This moves SemiNCAInfo from DeminatorTreeBase to GenericDomTreeConstruction. It also put helper functions used during tree constructions in the same file.

The point of this change is to further clean up DominatorTreeBase and make it easier to construct and verify (in future patches).

Reviewers: dberlin, sanjoy, chandlerc

Reviewed By: dberlin

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D34420

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306576 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/GenericDomTree.h
include/llvm/Support/GenericDomTreeConstruction.h

index 49fcd9e..47575d9 100644 (file)
@@ -201,6 +201,11 @@ void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &O,
     PrintDomTree<NodeT>(*I, O, Lev + 1);
 }
 
+namespace DomTreeBuilder {
+template <class NodeT>
+struct SemiNCAInfo;
+}  // namespace DomTreeBuilder
+
 // The calculate routine is provided in a separate header but referenced here.
 template <class FuncT, class N>
 void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT, FuncT &F);
@@ -648,69 +653,14 @@ public:
   }
 
 protected:
-  // Information record used by Semi-NCA during tree construction.
-  struct SemiNCAInfo {
-    using NodePtr = NodeT *;
-    struct InfoRec {
-      unsigned DFSNum = 0;
-      unsigned Parent = 0;
-      unsigned Semi = 0;
-      NodePtr Label = nullptr;
-      NodePtr IDom = nullptr;
-    };
-
-    std::vector<NodePtr> NumToNode;
-    DenseMap<NodePtr, InfoRec> NodeToInfo;
-
-    NodeT *getIDom(NodeT *BB) const {
-      auto InfoIt = NodeToInfo.find(BB);
-      if (InfoIt == NodeToInfo.end()) return nullptr;
-
-      return InfoIt->second.IDom;
-    }
-  };
-
-  template <class GraphT>
-  friend typename GraphT::NodeRef Eval(
-      DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
-      typename DominatorTreeBaseByGraphTraits<GraphT>::SemiNCAInfo &Info,
-      unsigned LastLinked);
-
-  template <class GraphT>
-  friend unsigned ReverseDFSPass(
-      DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
-      typename DominatorTreeBaseByGraphTraits<GraphT>::SemiNCAInfo &Info,
-      unsigned N);
-
-  template <class GraphT>
-  friend unsigned DFSPass(
-      DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
-      typename DominatorTreeBaseByGraphTraits<GraphT>::SemiNCAInfo &Info,
-      unsigned N);
-
-  template <class FuncT, class N>
-  friend void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT,
-  FuncT &F);
-
-  DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB,
-                                          const SemiNCAInfo& SNCAInfo) {
-    if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
-      return Node;
-
-    // Haven't calculated this node yet?  Get or calculate the node for the
-    // immediate dominator.
-    NodeT *IDom = SNCAInfo.getIDom(BB);
-
-    assert(IDom || DomTreeNodes[nullptr]);
-    DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom, SNCAInfo);
-
-    // Add a new tree node for this NodeT, and link it as a child of
-    // IDomNode
-    return (DomTreeNodes[BB] = IDomNode->addChild(
-                llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
-  }
+ friend struct DomTreeBuilder::SemiNCAInfo<NodeT>;
+ using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo<NodeT>;
+
+ template <class FuncT, class NodeTy>
+ friend void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeTy>> &DT,
+                       FuncT &F);
 
 void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
+ void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
 
 public:
   /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
index 9fe07e0..aa42b9e 100644 (file)
 
 namespace llvm {
 
+namespace DomTreeBuilder {
+// Information record used by Semi-NCA during tree construction.
+template <typename NodeT>
+struct SemiNCAInfo {
+  using NodePtr = NodeT *;
+  using DomTreeT = DominatorTreeBase<NodeT>;
+  using TreeNodePtr = DomTreeNodeBase<NodeT> *;
+
+  struct InfoRec {
+    unsigned DFSNum = 0;
+    unsigned Parent = 0;
+    unsigned Semi = 0;
+    NodePtr Label = nullptr;
+    NodePtr IDom = nullptr;
+  };
+
+  DomTreeT &DT;
+  std::vector<NodePtr> NumToNode;
+  DenseMap<NodePtr, InfoRec> NodeToInfo;
+
+  SemiNCAInfo(DomTreeT &DT) : DT(DT) {}
+
+  NodePtr getIDom(NodePtr BB) const {
+    auto InfoIt = NodeToInfo.find(BB);
+    if (InfoIt == NodeToInfo.end()) return nullptr;
+
+    return InfoIt->second.IDom;
+  }
+
+  TreeNodePtr getNodeForBlock(NodePtr BB) {
+    if (TreeNodePtr Node = DT.getNode(BB)) return Node;
+
+    // Haven't calculated this node yet?  Get or calculate the node for the
+    // immediate dominator.
+    NodePtr IDom = getIDom(BB);
+
+    assert(IDom || DT.DomTreeNodes[nullptr]);
+    TreeNodePtr IDomNode = getNodeForBlock(IDom);
+
+    // Add a new tree node for this NodeT, and link it as a child of
+    // IDomNode
+    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
+                llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
+        .get();
+  }
+};
+}  // namespace DomTreeBuilder
+
 // External storage for depth first iterator that reuses the info lookup map
 // domtree already has.  We don't have a set, but a map instead, so we are
 // converting the one argument insert calls.
@@ -49,20 +97,18 @@ private:
   BaseSet &Storage;
 };
 
-template <class GraphT>
-unsigned ReverseDFSPass(
-    DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
-    typename DominatorTreeBaseByGraphTraits<GraphT>::SemiNCAInfo &SNCA,
-    unsigned N) {
-  using SNCAInfoTy = typename std::remove_reference<decltype(SNCA)>::type;
-  df_iterator_dom_storage<typename SNCAInfoTy::NodePtr,
-      typename SNCAInfoTy::InfoRec>
-      DFStorage(SNCA.NodeToInfo);
+template <class NodePtr,
+          class NodeT = typename std::remove_pointer<NodePtr>::type>
+unsigned ReverseDFSPass(NodePtr V, DomTreeBuilder::SemiNCAInfo<NodeT> &SNCA,
+                        unsigned N) {
+  using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo<NodeT>;
+  df_iterator_dom_storage<NodePtr, typename SNCAInfoTy::InfoRec> DFStorage(
+      SNCA.NodeToInfo);
 
   bool IsChildOfArtificialExit = (N != 0);
   for (auto I = idf_ext_begin(V, DFStorage), E = idf_ext_end(V, DFStorage);
        I != E; ++I) {
-    typename GraphT::NodeRef BB = *I;
+    NodePtr BB = *I;
     auto &BBInfo = SNCA.NodeToInfo[BB];
     BBInfo.DFSNum = BBInfo.Semi = ++N;
     BBInfo.Label = BB;
@@ -79,18 +125,17 @@ unsigned ReverseDFSPass(
   }
   return N;
 }
-template <class GraphT>
-unsigned DFSPass(
-    DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
-    typename DominatorTreeBaseByGraphTraits<GraphT>::SemiNCAInfo &SNCA,
-    unsigned N) {
-  using SNCAInfoTy = typename std::remove_reference<decltype(SNCA)>::type;
-  df_iterator_dom_storage<typename SNCAInfoTy::NodePtr,
-      typename SNCAInfoTy::InfoRec>
-      DFStorage(SNCA.NodeToInfo);
+
+template <class NodePtr,
+          class NodeT = typename std::remove_pointer<NodePtr>::type>
+unsigned DFSPass(NodePtr V, DomTreeBuilder::SemiNCAInfo<NodeT> &SNCA, unsigned N) {
+  using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo<NodeT>;
+  df_iterator_dom_storage<NodePtr, typename SNCAInfoTy::InfoRec> DFStorage(
+      SNCA.NodeToInfo);
+
   for (auto I = df_ext_begin(V, DFStorage), E = df_ext_end(V, DFStorage);
        I != E; ++I) {
-    typename GraphT::NodeRef BB = *I;
+    NodePtr BB = *I;
     auto &BBInfo = SNCA.NodeToInfo[BB];
     BBInfo.DFSNum = BBInfo.Semi = ++N;
     BBInfo.Label = BB;
@@ -103,13 +148,10 @@ unsigned DFSPass(
   return N;
 }
 
-template <class GraphT>
-typename GraphT::NodeRef Eval(
-    DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef VIn,
-    typename DominatorTreeBaseByGraphTraits<GraphT>::SemiNCAInfo &SNCA,
-    unsigned LastLinked) {
-  using NodePtr = typename GraphT::NodeRef;
-
+template <class NodePtr,
+          class NodeT = typename std::remove_pointer<NodePtr>::type>
+NodePtr Eval(NodePtr VIn, DomTreeBuilder::SemiNCAInfo<NodeT> &SNCA,
+             unsigned LastLinked) {
   auto &VInInfo = SNCA.NodeToInfo[VIn];
   if (VInInfo.DFSNum < LastLinked)
     return VIn;
@@ -153,11 +195,11 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
   using GraphT = GraphTraits<NodeT>;
   using NodePtr = typename GraphT::NodeRef;
   static_assert(std::is_pointer<NodePtr>::value,
-                "NodeRef should be pointer type");
+                "NodePtr should be a pointer type");
   using NodeType = typename std::remove_pointer<NodePtr>::type;
 
   unsigned N = 0;
-  typename DominatorTreeBaseByGraphTraits<GraphT>::SemiNCAInfo SNCA;
+  DomTreeBuilder::SemiNCAInfo<NodeType> SNCA(DT);
   SNCA.NumToNode.push_back(nullptr);
 
   bool MultipleRoots = (DT.Roots.size() > 1);
@@ -174,9 +216,9 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
   if (DT.isPostDominator()){
     for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
          i != e; ++i)
-      N = ReverseDFSPass<GraphT>(DT, DT.Roots[i], SNCA, N);
+      N = ReverseDFSPass<NodePtr>(DT.Roots[i], SNCA, N);
   } else {
-    N = DFSPass<GraphT>(DT, DT.Roots[0], SNCA, N);
+    N = DFSPass<NodePtr>(DT.Roots[0], SNCA, N);
   }
 
   // It might be that some blocks did not get a DFS number (e.g., blocks of
@@ -199,7 +241,7 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
     WInfo.Semi = WInfo.Parent;
     for (const auto &N : inverse_children<NodeT>(W))
       if (SNCA.NodeToInfo.count(N)) {  // Only if this predecessor is reachable!
-        unsigned SemiU = SNCA.NodeToInfo[Eval<GraphT>(DT, N, SNCA, i + 1)].Semi;
+        unsigned SemiU = SNCA.NodeToInfo[Eval<NodePtr>(N, SNCA, i + 1)].Semi;
         if (SemiU < WInfo.Semi)
           WInfo.Semi = SemiU;
       }
@@ -247,7 +289,7 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
     assert(ImmDom || DT.DomTreeNodes[nullptr]);
 
     // Get or calculate the node for the immediate dominator
-    DomTreeNodeBase<NodeType> *IDomNode = DT.getNodeForBlock(ImmDom, SNCA);
+    DomTreeNodeBase<NodeType> *IDomNode = SNCA.getNodeForBlock(ImmDom);
 
     // Add a new tree node for this BasicBlock, and link it as a child of
     // IDomNode
@@ -257,6 +299,6 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
 
   DT.updateDFSNumbers();
 }
-}
+} // namespace DomTreeBuilder
 
 #endif