Index: llvm/trunk/include/llvm/ADT/GraphTraits.h =================================================================== --- llvm/trunk/include/llvm/ADT/GraphTraits.h +++ llvm/trunk/include/llvm/ADT/GraphTraits.h @@ -88,23 +88,7 @@ // Provide a partial specialization of GraphTraits so that the inverse of an // inverse falls back to the original graph. -template -struct GraphTraits > > { - typedef typename GraphTraits::NodeType NodeType; - typedef typename GraphTraits::ChildIteratorType ChildIteratorType; - - static NodeType *getEntryNode(Inverse > *G) { - return GraphTraits::getEntryNode(G->Graph.Graph); - } - - static ChildIteratorType child_begin(NodeType* N) { - return GraphTraits::child_begin(N); - } - - static ChildIteratorType child_end(NodeType* N) { - return GraphTraits::child_end(N); - } -}; +template struct GraphTraits>> : GraphTraits {}; } // End llvm namespace Index: llvm/trunk/include/llvm/IR/Dominators.h =================================================================== --- llvm/trunk/include/llvm/IR/Dominators.h +++ llvm/trunk/include/llvm/IR/Dominators.h @@ -33,9 +33,9 @@ extern template class DominatorTreeBase; extern template void Calculate( - DominatorTreeBase::NodeType> &DT, Function &F); + DominatorTreeBaseByGraphTraits> &DT, Function &F); extern template void Calculate>( - DominatorTreeBase>::NodeType> &DT, + DominatorTreeBaseByGraphTraits>> &DT, Function &F); typedef DomTreeNodeBase DomTreeNode; Index: llvm/trunk/include/llvm/Support/GenericDomTree.h =================================================================== --- llvm/trunk/include/llvm/Support/GenericDomTree.h +++ llvm/trunk/include/llvm/Support/GenericDomTree.h @@ -13,6 +13,12 @@ /// dominance queries on the CFG, but is fully generic w.r.t. the underlying /// graph types. /// +/// Unlike ADT/* graph algorithms, generic dominator tree has more reuiqrement +/// on the graph's NodeRef. The NodeRef should be a pointer and, depending on +/// the implementation, e.g. NodeRef->getParent() return the parent node. +/// +/// FIXME: Maybe GenericDomTree needs a TreeTraits, instead of GraphTraits. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_GENERICDOMTREE_H @@ -30,6 +36,23 @@ namespace llvm { +template class DominatorTreeBase; + +namespace detail { + +template struct DominatorTreeBaseTraits { + static_assert(std::is_pointer::value, + "Currently NodeRef must be a pointer type."); + using type = DominatorTreeBase< + typename std::remove_pointer::type>; +}; + +} // End namespace detail + +template +using DominatorTreeBaseByGraphTraits = + typename detail::DominatorTreeBaseTraits::type; + /// \brief Base class that other, more interesting dominator analyses /// inherit from. template class DominatorBase { @@ -62,7 +85,6 @@ bool isPostDominator() const { return IsPostDominators; } }; -template class DominatorTreeBase; struct PostDominatorTree; /// \brief Base class for the actual dominator tree node. @@ -177,8 +199,7 @@ // The calculate routine is provided in a separate header but referenced here. template -void Calculate(DominatorTreeBase::NodeType> &DT, - FuncT &F); +void Calculate(DominatorTreeBaseByGraphTraits> &DT, FuncT &F); /// \brief Core dominator tree base class. /// @@ -251,14 +272,14 @@ // NewBB is split and now it has one successor. Update dominator tree to // reflect this change. template - void Split(DominatorTreeBase &DT, - typename GraphT::NodeType *NewBB) { + void Split(DominatorTreeBaseByGraphTraits &DT, + typename GraphT::NodeRef NewBB) { assert(std::distance(GraphT::child_begin(NewBB), GraphT::child_end(NewBB)) == 1 && "NewBB should have a single successor!"); - typename GraphT::NodeType *NewBBSucc = *GraphT::child_begin(NewBB); + typename GraphT::NodeRef NewBBSucc = *GraphT::child_begin(NewBB); - std::vector PredBlocks; + std::vector PredBlocks; typedef GraphTraits> InvTraits; for (typename InvTraits::ChildIteratorType PI = InvTraits::child_begin(NewBB), @@ -273,7 +294,7 @@ PI = InvTraits::child_begin(NewBBSucc), E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) { - typename InvTraits::NodeType *ND = *PI; + typename InvTraits::NodeRef ND = *PI; if (ND != NewBB && !DT.dominates(NewBBSucc, ND) && DT.isReachableFromEntry(ND)) { NewBBDominatesNewBBSucc = false; @@ -627,18 +648,17 @@ protected: template - friend typename GraphT::NodeType * - Eval(DominatorTreeBase &DT, - typename GraphT::NodeType *V, unsigned LastLinked); + friend typename GraphT::NodeRef + Eval(DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, + unsigned LastLinked); template - friend unsigned DFSPass(DominatorTreeBase &DT, - typename GraphT::NodeType *V, unsigned N); + friend unsigned DFSPass(DominatorTreeBaseByGraphTraits &DT, + typename GraphT::NodeRef V, unsigned N); template - friend void - Calculate(DominatorTreeBase::NodeType> &DT, FuncT &F); - + friend void Calculate(DominatorTreeBaseByGraphTraits> &DT, + FuncT &F); DomTreeNodeBase *getNodeForBlock(NodeT *BB) { if (DomTreeNodeBase *Node = getNode(BB)) Index: llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h =================================================================== --- llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h +++ llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h @@ -29,9 +29,9 @@ namespace llvm { -template -unsigned DFSPass(DominatorTreeBase& DT, - typename GraphT::NodeType* V, unsigned N) { +template +unsigned DFSPass(DominatorTreeBaseByGraphTraits &DT, + typename GraphT::NodeRef V, unsigned N) { // This is more understandable as a recursive algorithm, but we can't use the // recursive algorithm due to stack depth issues. Keep it here for // documentation purposes. @@ -52,15 +52,16 @@ #else bool IsChildOfArtificialExit = (N != 0); - SmallVector, 32> Worklist; + SmallVector< + std::pair, + 32> + Worklist; Worklist.push_back(std::make_pair(V, GraphT::child_begin(V))); while (!Worklist.empty()) { - typename GraphT::NodeType* BB = Worklist.back().first; + typename GraphT::NodeRef BB = Worklist.back().first; typename GraphT::ChildIteratorType NextSucc = Worklist.back().second; - typename DominatorTreeBase::InfoRec &BBInfo = - DT.Info[BB]; + auto &BBInfo = DT.Info[BB]; // First time we visited this BB? if (NextSucc == GraphT::child_begin(BB)) { @@ -89,10 +90,9 @@ ++Worklist.back().second; // Visit the successor next, if it isn't already visited. - typename GraphT::NodeType* Succ = *NextSucc; + typename GraphT::NodeRef Succ = *NextSucc; - typename DominatorTreeBase::InfoRec &SuccVInfo = - DT.Info[Succ]; + auto &SuccVInfo = DT.Info[Succ]; if (SuccVInfo.Semi == 0) { SuccVInfo.Parent = BBDFSNum; Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ))); @@ -103,25 +103,23 @@ } template -typename GraphT::NodeType * -Eval(DominatorTreeBase &DT, - typename GraphT::NodeType *VIn, unsigned LastLinked) { - typename DominatorTreeBase::InfoRec &VInInfo = - DT.Info[VIn]; +typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits &DT, + typename GraphT::NodeRef VIn, + unsigned LastLinked) { + auto &VInInfo = DT.Info[VIn]; if (VInInfo.DFSNum < LastLinked) return VIn; - SmallVector Work; - SmallPtrSet Visited; + SmallVector Work; + SmallPtrSet Visited; if (VInInfo.Parent >= LastLinked) Work.push_back(VIn); while (!Work.empty()) { - typename GraphT::NodeType* V = Work.back(); - typename DominatorTreeBase::InfoRec &VInfo = - DT.Info[V]; - typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent]; + typename GraphT::NodeRef V = Work.back(); + auto &VInfo = DT.Info[V]; + typename GraphT::NodeRef VAncestor = DT.Vertex[VInfo.Parent]; // Process Ancestor first if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) { @@ -134,10 +132,9 @@ if (VInfo.Parent < LastLinked) continue; - typename DominatorTreeBase::InfoRec &VAInfo = - DT.Info[VAncestor]; - typename GraphT::NodeType* VAncestorLabel = VAInfo.Label; - typename GraphT::NodeType* VLabel = VInfo.Label; + auto &VAInfo = DT.Info[VAncestor]; + typename GraphT::NodeRef VAncestorLabel = VAInfo.Label; + typename GraphT::NodeRef VLabel = VInfo.Label; if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) VInfo.Label = VAncestorLabel; VInfo.Parent = VAInfo.Parent; @@ -146,16 +143,18 @@ return VInInfo.Label; } -template -void Calculate(DominatorTreeBase::NodeType>& DT, - FuncT& F) { +template +void Calculate(DominatorTreeBaseByGraphTraits> &DT, + FuncT &F) { typedef GraphTraits GraphT; + static_assert(std::is_pointer::value, + "NodeRef should be pointer type"); + typedef typename std::remove_pointer::type NodeType; unsigned N = 0; bool MultipleRoots = (DT.Roots.size() > 1); if (MultipleRoots) { - typename DominatorTreeBase::InfoRec &BBInfo = - DT.Info[nullptr]; + auto &BBInfo = DT.Info[nullptr]; BBInfo.DFSNum = BBInfo.Semi = ++N; BBInfo.Label = nullptr; @@ -188,14 +187,13 @@ Buckets[i] = i; for (unsigned i = N; i >= 2; --i) { - typename GraphT::NodeType* W = DT.Vertex[i]; - typename DominatorTreeBase::InfoRec &WInfo = - DT.Info[W]; + typename GraphT::NodeRef W = DT.Vertex[i]; + auto &WInfo = DT.Info[W]; // Step #2: Implicitly define the immediate dominator of vertices for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) { - typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; - typename GraphT::NodeType* U = Eval(DT, V, i + 1); + typename GraphT::NodeRef V = DT.Vertex[Buckets[j]]; + typename GraphT::NodeRef U = Eval(DT, V, i + 1); DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; } @@ -207,7 +205,7 @@ for (typename InvTraits::ChildIteratorType CI = InvTraits::child_begin(W), E = InvTraits::child_end(W); CI != E; ++CI) { - typename InvTraits::NodeType *N = *CI; + typename InvTraits::NodeRef N = *CI; if (DT.Info.count(N)) { // Only if this predecessor is reachable! unsigned SemiU = DT.Info[Eval(DT, N, i + 1)].Semi; if (SemiU < WInfo.Semi) @@ -227,17 +225,17 @@ } if (N >= 1) { - typename GraphT::NodeType* Root = DT.Vertex[1]; + typename GraphT::NodeRef Root = DT.Vertex[1]; for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) { - typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; + typename GraphT::NodeRef V = DT.Vertex[Buckets[j]]; DT.IDoms[V] = Root; } } // Step #4: Explicitly define the immediate dominator of each vertex for (unsigned i = 2; i <= N; ++i) { - typename GraphT::NodeType* W = DT.Vertex[i]; - typename GraphT::NodeType*& WIDom = DT.IDoms[W]; + typename GraphT::NodeRef W = DT.Vertex[i]; + typename GraphT::NodeRef &WIDom = DT.IDoms[W]; if (WIDom != DT.Vertex[DT.Info[W].Semi]) WIDom = DT.IDoms[WIDom]; } @@ -248,34 +246,32 @@ // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) // which postdominates all real exits if there are multiple exit blocks, or // an infinite loop. - typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : nullptr; + typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] : nullptr; DT.RootNode = (DT.DomTreeNodes[Root] = - llvm::make_unique>( - Root, nullptr)).get(); + llvm::make_unique>(Root, nullptr)) + .get(); // Loop over all of the reachable blocks in the function... for (unsigned i = 2; i <= N; ++i) { - typename GraphT::NodeType* W = DT.Vertex[i]; + typename GraphT::NodeRef W = DT.Vertex[i]; // Don't replace this with 'count', the insertion side effect is important if (DT.DomTreeNodes[W]) continue; // Haven't calculated this node yet? - typename GraphT::NodeType* ImmDom = DT.getIDom(W); + typename GraphT::NodeRef ImmDom = DT.getIDom(W); assert(ImmDom || DT.DomTreeNodes[nullptr]); // Get or calculate the node for the immediate dominator - DomTreeNodeBase *IDomNode = - DT.getNodeForBlock(ImmDom); + DomTreeNodeBase *IDomNode = DT.getNodeForBlock(ImmDom); // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode DT.DomTreeNodes[W] = IDomNode->addChild( - llvm::make_unique>( - W, IDomNode)); + llvm::make_unique>(W, IDomNode)); } // Free temporary memory used to construct idom's Index: llvm/trunk/lib/IR/Dominators.cpp =================================================================== --- llvm/trunk/lib/IR/Dominators.cpp +++ llvm/trunk/lib/IR/Dominators.cpp @@ -64,9 +64,13 @@ template class llvm::DominatorTreeBase; template void llvm::Calculate( - DominatorTreeBase::NodeType> &DT, Function &F); + DominatorTreeBase< + typename std::remove_pointer::NodeRef>::type> + &DT, + Function &F); template void llvm::Calculate>( - DominatorTreeBase>::NodeType> &DT, + DominatorTreeBase>::NodeRef>::type> &DT, Function &F); // dominates - Return true if Def dominates a use in User. This performs