Index: llvm/trunk/include/llvm/Support/GenericDomTree.h =================================================================== --- llvm/trunk/include/llvm/Support/GenericDomTree.h +++ llvm/trunk/include/llvm/Support/GenericDomTree.h @@ -201,6 +201,11 @@ PrintDomTree(*I, O, Lev + 1); } +namespace DomTreeBuilder { +template +struct SemiNCAInfo; +} // namespace DomTreeBuilder + // The calculate routine is provided in a separate header but referenced here. template void Calculate(DominatorTreeBaseByGraphTraits> &DT, FuncT &F); @@ -648,69 +653,14 @@ } 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 NumToNode; - DenseMap NodeToInfo; - - NodeT *getIDom(NodeT *BB) const { - auto InfoIt = NodeToInfo.find(BB); - if (InfoIt == NodeToInfo.end()) return nullptr; - - return InfoIt->second.IDom; - } - }; - - template - friend typename GraphT::NodeRef Eval( - DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, - typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info, - unsigned LastLinked); - - template - friend unsigned ReverseDFSPass( - DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, - typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info, - unsigned N); - - template - friend unsigned DFSPass( - DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, - typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info, - unsigned N); - - template - friend void Calculate(DominatorTreeBaseByGraphTraits> &DT, - FuncT &F); - - DomTreeNodeBase *getNodeForBlock(NodeT *BB, - const SemiNCAInfo& SNCAInfo) { - if (DomTreeNodeBase *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 *IDomNode = getNodeForBlock(IDom, SNCAInfo); + friend struct DomTreeBuilder::SemiNCAInfo; + using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo; - // Add a new tree node for this NodeT, and link it as a child of - // IDomNode - return (DomTreeNodes[BB] = IDomNode->addChild( - llvm::make_unique>(BB, IDomNode))).get(); - } + template + friend void Calculate(DominatorTreeBaseByGraphTraits> &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: llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h =================================================================== --- llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h +++ llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h @@ -31,6 +31,54 @@ namespace llvm { +namespace DomTreeBuilder { +// Information record used by Semi-NCA during tree construction. +template +struct SemiNCAInfo { + using NodePtr = NodeT *; + using DomTreeT = DominatorTreeBase; + using TreeNodePtr = DomTreeNodeBase *; + + struct InfoRec { + unsigned DFSNum = 0; + unsigned Parent = 0; + unsigned Semi = 0; + NodePtr Label = nullptr; + NodePtr IDom = nullptr; + }; + + DomTreeT &DT; + std::vector NumToNode; + DenseMap 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>(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 @@ BaseSet &Storage; }; -template -unsigned ReverseDFSPass( - DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, - typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA, - unsigned N) { - using SNCAInfoTy = typename std::remove_reference::type; - df_iterator_dom_storage - DFStorage(SNCA.NodeToInfo); +template ::type> +unsigned ReverseDFSPass(NodePtr V, DomTreeBuilder::SemiNCAInfo &SNCA, + unsigned N) { + using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo; + df_iterator_dom_storage 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 @@ } return N; } -template -unsigned DFSPass( - DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, - typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA, - unsigned N) { - using SNCAInfoTy = typename std::remove_reference::type; - df_iterator_dom_storage - DFStorage(SNCA.NodeToInfo); + +template ::type> +unsigned DFSPass(NodePtr V, DomTreeBuilder::SemiNCAInfo &SNCA, unsigned N) { + using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo; + df_iterator_dom_storage 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 @@ return N; } -template -typename GraphT::NodeRef Eval( - DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef VIn, - typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA, - unsigned LastLinked) { - using NodePtr = typename GraphT::NodeRef; - +template ::type> +NodePtr Eval(NodePtr VIn, DomTreeBuilder::SemiNCAInfo &SNCA, + unsigned LastLinked) { auto &VInInfo = SNCA.NodeToInfo[VIn]; if (VInInfo.DFSNum < LastLinked) return VIn; @@ -153,11 +195,11 @@ using GraphT = GraphTraits; using NodePtr = typename GraphT::NodeRef; static_assert(std::is_pointer::value, - "NodeRef should be pointer type"); + "NodePtr should be a pointer type"); using NodeType = typename std::remove_pointer::type; unsigned N = 0; - typename DominatorTreeBaseByGraphTraits::SemiNCAInfo SNCA; + DomTreeBuilder::SemiNCAInfo SNCA(DT); SNCA.NumToNode.push_back(nullptr); bool MultipleRoots = (DT.Roots.size() > 1); @@ -174,9 +216,9 @@ if (DT.isPostDominator()){ for (unsigned i = 0, e = static_cast(DT.Roots.size()); i != e; ++i) - N = ReverseDFSPass(DT, DT.Roots[i], SNCA, N); + N = ReverseDFSPass(DT.Roots[i], SNCA, N); } else { - N = DFSPass(DT, DT.Roots[0], SNCA, N); + N = DFSPass(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 @@ WInfo.Semi = WInfo.Parent; for (const auto &N : inverse_children(W)) if (SNCA.NodeToInfo.count(N)) { // Only if this predecessor is reachable! - unsigned SemiU = SNCA.NodeToInfo[Eval(DT, N, SNCA, i + 1)].Semi; + unsigned SemiU = SNCA.NodeToInfo[Eval(N, SNCA, i + 1)].Semi; if (SemiU < WInfo.Semi) WInfo.Semi = SemiU; } @@ -247,7 +289,7 @@ assert(ImmDom || DT.DomTreeNodes[nullptr]); // Get or calculate the node for the immediate dominator - DomTreeNodeBase *IDomNode = DT.getNodeForBlock(ImmDom, SNCA); + DomTreeNodeBase *IDomNode = SNCA.getNodeForBlock(ImmDom); // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode @@ -257,6 +299,6 @@ DT.updateDFSNumbers(); } -} +} // namespace DomTreeBuilder #endif