diff --git a/llvm/include/llvm/Support/GenericDomTree.h b/llvm/include/llvm/Support/GenericDomTree.h --- a/llvm/include/llvm/Support/GenericDomTree.h +++ b/llvm/include/llvm/Support/GenericDomTree.h @@ -14,7 +14,9 @@ /// /// Unlike ADT/* graph algorithms, generic dominator tree has more requirements /// on the graph's NodeRef. The NodeRef should be a pointer and, -/// NodeRef->getParent() must return the parent node that is also a pointer. +/// either NodeRef->getParent() must return the parent node that is also a +/// pointer or DomTreeBase::getParent needs to be specialized to return the +/// parent for NodeRef. /// /// FIXME: Maybe GenericDomTree needs a TreeTraits, instead of GraphTraits. /// @@ -220,6 +222,21 @@ bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL); } // namespace DomTreeBuilder +namespace detail { +/// Helper trait to use custom GraphTraits::ParentPtrTy if it exists or +/// T::getParent's return type otherwise. +template struct dt_get_parent_ptr_ty { + using type = decltype(std::declval()->getParent()); +}; + +template +struct dt_get_parent_ptr_ty::ParentPtrTy>> { + using type = typename GraphTraits::ParentPtrTy; +}; + +} // namespace detail + /// Core dominator tree base class. /// /// This class is a generic template over graph nodes. It is instantiated for @@ -231,7 +248,7 @@ "Currently DominatorTreeBase supports only pointer nodes"); using NodeType = NodeT; using NodePtr = NodeT *; - using ParentPtr = decltype(std::declval()->getParent()); + using ParentPtr = typename detail::dt_get_parent_ptr_ty::type; static_assert(std::is_pointer::value, "Currently NodeT's parent must be a pointer type"); using ParentType = std::remove_pointer_t; @@ -463,11 +480,13 @@ return this->Roots[0]; } + ParentPtr getParent(NodeT *B) const { return B->getParent(); } + /// Find nearest common dominator basic block for basic block A and B. A and B /// must have tree nodes. NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const { assert(A && B && "Pointers are not valid"); - assert(A->getParent() == B->getParent() && + assert(getParent(A) == getParent(B) && "Two blocks are not in same function"); // If either A or B is a entry block then it is nearest common dominator @@ -584,8 +603,8 @@ void insertEdge(NodeT *From, NodeT *To) { assert(From); assert(To); - assert(From->getParent() == Parent); - assert(To->getParent() == Parent); + assert(getParent(From) == Parent); + assert(getParent(To) == Parent); DomTreeBuilder::InsertEdge(*this, From, To); } @@ -602,8 +621,8 @@ void deleteEdge(NodeT *From, NodeT *To) { assert(From); assert(To); - assert(From->getParent() == Parent); - assert(To->getParent() == Parent); + assert(getParent(From) == Parent); + assert(getParent(To) == Parent); DomTreeBuilder::DeleteEdge(*this, From, To); }