[ADT] NFC: Generalize GraphTraits requirement of "NodeType *" in interfaces to "NodeRef", and migrate SCCIterator.h to use NodeRef

Summary: By generalize the interface, users are able to inject more flexible Node token into the algorithm, for example, a pair of vector<Node>* and index integer. Currently I only migrated SCCIterator to use NodeRef, but more is coming. It's a NFC.

Reviewers: dblaikie, chandlerc

Subscribers: llvm-commits

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

llvm-svn: 277399
This commit is contained in:
Tim Shen 2016-08-01 22:32:20 +00:00
parent c64d7655b2
commit b44909eccb
8 changed files with 41 additions and 24 deletions

View File

@ -27,19 +27,24 @@ template<class GraphType>
struct GraphTraits { struct GraphTraits {
// Elements to provide: // Elements to provide:
// NOTICE: We are in a transition from migration interfaces that require
// NodeType *, to NodeRef. NodeRef is required to be cheap to copy, but does
// not have to be a raw pointer. In the transition, user should define
// NodeType, and NodeRef = NodeType *.
//
// typedef NodeType - Type of Node in the graph // typedef NodeType - Type of Node in the graph
// typedef NodeRef - NodeType *
// typedef ChildIteratorType - Type used to iterate over children in graph // typedef ChildIteratorType - Type used to iterate over children in graph
// static NodeType *getEntryNode(const GraphType &) // static NodeRef getEntryNode(const GraphType &)
// Return the entry node of the graph // Return the entry node of the graph
// static ChildIteratorType child_begin(NodeType *) // static ChildIteratorType child_begin(NodeRef)
// static ChildIteratorType child_end (NodeType *) // static ChildIteratorType child_end (NodeRef)
// Return iterators that point to the beginning and ending of the child // Return iterators that point to the beginning and ending of the child
// node list for the specified node. // node list for the specified node.
// //
// typedef ...iterator nodes_iterator; // typedef ...iterator nodes_iterator;
// static nodes_iterator nodes_begin(GraphType *G) // static nodes_iterator nodes_begin(GraphType *G)
// static nodes_iterator nodes_end (GraphType *G) // static nodes_iterator nodes_end (GraphType *G)
@ -57,7 +62,7 @@ struct GraphTraits {
// your argument to XXX_begin(...) is unknown or needs to have the proper .h // your argument to XXX_begin(...) is unknown or needs to have the proper .h
// file #include'd. // file #include'd.
// //
typedef typename GraphType::UnknownGraphTypeError NodeType; typedef typename GraphType::UnknownGraphTypeError NodeRef;
}; };

View File

@ -37,23 +37,22 @@ namespace llvm {
/// build up a vector of nodes in a particular SCC. Note that it is a forward /// build up a vector of nodes in a particular SCC. Note that it is a forward
/// iterator and thus you cannot backtrack or re-visit nodes. /// iterator and thus you cannot backtrack or re-visit nodes.
template <class GraphT, class GT = GraphTraits<GraphT>> template <class GraphT, class GT = GraphTraits<GraphT>>
class scc_iterator class scc_iterator : public iterator_facade_base<
: public iterator_facade_base< scc_iterator<GraphT, GT>, std::forward_iterator_tag,
scc_iterator<GraphT, GT>, std::forward_iterator_tag, const std::vector<typename GT::NodeRef>, ptrdiff_t> {
const std::vector<typename GT::NodeType *>, ptrdiff_t> { typedef typename GT::NodeRef NodeRef;
typedef typename GT::NodeType NodeType;
typedef typename GT::ChildIteratorType ChildItTy; typedef typename GT::ChildIteratorType ChildItTy;
typedef std::vector<NodeType *> SccTy; typedef std::vector<NodeRef> SccTy;
typedef typename scc_iterator::reference reference; typedef typename scc_iterator::reference reference;
/// Element of VisitStack during DFS. /// Element of VisitStack during DFS.
struct StackElement { struct StackElement {
NodeType *Node; ///< The current node pointer. NodeRef Node; ///< The current node pointer.
ChildItTy NextChild; ///< The next child, modified inplace during DFS. ChildItTy NextChild; ///< The next child, modified inplace during DFS.
unsigned MinVisited; ///< Minimum uplink value of all children of Node. unsigned MinVisited; ///< Minimum uplink value of all children of Node.
StackElement(NodeType *Node, const ChildItTy &Child, unsigned Min) StackElement(NodeRef Node, const ChildItTy &Child, unsigned Min)
: Node(Node), NextChild(Child), MinVisited(Min) {} : Node(Node), NextChild(Child), MinVisited(Min) {}
bool operator==(const StackElement &Other) const { bool operator==(const StackElement &Other) const {
return Node == Other.Node && return Node == Other.Node &&
@ -67,10 +66,10 @@ class scc_iterator
/// ///
/// nodeVisitNumbers are per-node visit numbers, also used as DFS flags. /// nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
unsigned visitNum; unsigned visitNum;
DenseMap<NodeType *, unsigned> nodeVisitNumbers; DenseMap<NodeRef, unsigned> nodeVisitNumbers;
/// Stack holding nodes of the SCC. /// Stack holding nodes of the SCC.
std::vector<NodeType *> SCCNodeStack; std::vector<NodeRef> SCCNodeStack;
/// The current SCC, retrieved using operator*(). /// The current SCC, retrieved using operator*().
SccTy CurrentSCC; SccTy CurrentSCC;
@ -80,7 +79,7 @@ class scc_iterator
std::vector<StackElement> VisitStack; std::vector<StackElement> VisitStack;
/// A single "visit" within the non-recursive DFS traversal. /// A single "visit" within the non-recursive DFS traversal.
void DFSVisitOne(NodeType *N); void DFSVisitOne(NodeRef N);
/// The stack-based DFS traversal; defined below. /// The stack-based DFS traversal; defined below.
void DFSVisitChildren(); void DFSVisitChildren();
@ -88,7 +87,7 @@ class scc_iterator
/// Compute the next SCC using the DFS traversal. /// Compute the next SCC using the DFS traversal.
void GetNextSCC(); void GetNextSCC();
scc_iterator(NodeType *entryN) : visitNum(0) { scc_iterator(NodeRef entryN) : visitNum(0) {
DFSVisitOne(entryN); DFSVisitOne(entryN);
GetNextSCC(); GetNextSCC();
} }
@ -131,7 +130,7 @@ public:
/// This informs the \c scc_iterator that the specified \c Old node /// This informs the \c scc_iterator that the specified \c Old node
/// has been deleted, and \c New is to be used in its place. /// has been deleted, and \c New is to be used in its place.
void ReplaceNode(NodeType *Old, NodeType *New) { void ReplaceNode(NodeRef Old, NodeRef New) {
assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?"); assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?");
nodeVisitNumbers[New] = nodeVisitNumbers[Old]; nodeVisitNumbers[New] = nodeVisitNumbers[Old];
nodeVisitNumbers.erase(Old); nodeVisitNumbers.erase(Old);
@ -139,7 +138,7 @@ public:
}; };
template <class GraphT, class GT> template <class GraphT, class GT>
void scc_iterator<GraphT, GT>::DFSVisitOne(NodeType *N) { void scc_iterator<GraphT, GT>::DFSVisitOne(NodeRef N) {
++visitNum; ++visitNum;
nodeVisitNumbers[N] = visitNum; nodeVisitNumbers[N] = visitNum;
SCCNodeStack.push_back(N); SCCNodeStack.push_back(N);
@ -155,8 +154,8 @@ void scc_iterator<GraphT, GT>::DFSVisitChildren() {
assert(!VisitStack.empty()); assert(!VisitStack.empty());
while (VisitStack.back().NextChild != GT::child_end(VisitStack.back().Node)) { while (VisitStack.back().NextChild != GT::child_end(VisitStack.back().Node)) {
// TOS has at least one more child so continue DFS // TOS has at least one more child so continue DFS
NodeType *childN = *VisitStack.back().NextChild++; NodeRef childN = *VisitStack.back().NextChild++;
typename DenseMap<NodeType *, unsigned>::iterator Visited = typename DenseMap<NodeRef, unsigned>::iterator Visited =
nodeVisitNumbers.find(childN); nodeVisitNumbers.find(childN);
if (Visited == nodeVisitNumbers.end()) { if (Visited == nodeVisitNumbers.end()) {
// this node has never been seen. // this node has never been seen.
@ -176,7 +175,7 @@ template <class GraphT, class GT> void scc_iterator<GraphT, GT>::GetNextSCC() {
DFSVisitChildren(); DFSVisitChildren();
// Pop the leaf on top of the VisitStack. // Pop the leaf on top of the VisitStack.
NodeType *visitingN = VisitStack.back().Node; NodeRef visitingN = VisitStack.back().Node;
unsigned minVisitNum = VisitStack.back().MinVisited; unsigned minVisitNum = VisitStack.back().MinVisited;
assert(VisitStack.back().NextChild == GT::child_end(visitingN)); assert(VisitStack.back().NextChild == GT::child_end(visitingN));
VisitStack.pop_back(); VisitStack.pop_back();
@ -212,7 +211,7 @@ bool scc_iterator<GraphT, GT>::hasLoop() const {
assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
if (CurrentSCC.size() > 1) if (CurrentSCC.size() > 1)
return true; return true;
NodeType *N = CurrentSCC.front(); NodeRef N = CurrentSCC.front();
for (ChildItTy CI = GT::child_begin(N), CE = GT::child_end(N); CI != CE; for (ChildItTy CI = GT::child_begin(N), CE = GT::child_end(N); CI != CE;
++CI) ++CI)
if (*CI == N) if (*CI == N)

View File

@ -410,6 +410,7 @@ public:
// traversals. // traversals.
template <> struct GraphTraits<CallGraphNode *> { template <> struct GraphTraits<CallGraphNode *> {
typedef CallGraphNode NodeType; typedef CallGraphNode NodeType;
typedef CallGraphNode *NodeRef;
typedef CallGraphNode::CallRecord CGNPairTy; typedef CallGraphNode::CallRecord CGNPairTy;
typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode *> typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode *>
@ -431,6 +432,7 @@ template <> struct GraphTraits<CallGraphNode *> {
template <> struct GraphTraits<const CallGraphNode *> { template <> struct GraphTraits<const CallGraphNode *> {
typedef const CallGraphNode NodeType; typedef const CallGraphNode NodeType;
typedef const CallGraphNode *NodeRef;
typedef CallGraphNode::CallRecord CGNPairTy; typedef CallGraphNode::CallRecord CGNPairTy;
typedef std::pointer_to_unary_function<CGNPairTy, const CallGraphNode *> typedef std::pointer_to_unary_function<CGNPairTy, const CallGraphNode *>

View File

@ -740,6 +740,7 @@ struct MBB2NumberFunctor :
template <> struct GraphTraits<MachineBasicBlock *> { template <> struct GraphTraits<MachineBasicBlock *> {
typedef MachineBasicBlock NodeType; typedef MachineBasicBlock NodeType;
typedef MachineBasicBlock *NodeRef;
typedef MachineBasicBlock::succ_iterator ChildIteratorType; typedef MachineBasicBlock::succ_iterator ChildIteratorType;
static NodeType *getEntryNode(MachineBasicBlock *BB) { return BB; } static NodeType *getEntryNode(MachineBasicBlock *BB) { return BB; }
@ -753,6 +754,7 @@ template <> struct GraphTraits<MachineBasicBlock *> {
template <> struct GraphTraits<const MachineBasicBlock *> { template <> struct GraphTraits<const MachineBasicBlock *> {
typedef const MachineBasicBlock NodeType; typedef const MachineBasicBlock NodeType;
typedef const MachineBasicBlock *NodeRef;
typedef MachineBasicBlock::const_succ_iterator ChildIteratorType; typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
static NodeType *getEntryNode(const MachineBasicBlock *BB) { return BB; } static NodeType *getEntryNode(const MachineBasicBlock *BB) { return BB; }
@ -772,6 +774,7 @@ template <> struct GraphTraits<const MachineBasicBlock *> {
// //
template <> struct GraphTraits<Inverse<MachineBasicBlock*> > { template <> struct GraphTraits<Inverse<MachineBasicBlock*> > {
typedef MachineBasicBlock NodeType; typedef MachineBasicBlock NodeType;
typedef MachineBasicBlock *NodeRef;
typedef MachineBasicBlock::pred_iterator ChildIteratorType; typedef MachineBasicBlock::pred_iterator ChildIteratorType;
static NodeType *getEntryNode(Inverse<MachineBasicBlock *> G) { static NodeType *getEntryNode(Inverse<MachineBasicBlock *> G) {
return G.Graph; return G.Graph;
@ -786,6 +789,7 @@ template <> struct GraphTraits<Inverse<MachineBasicBlock*> > {
template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > { template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > {
typedef const MachineBasicBlock NodeType; typedef const MachineBasicBlock NodeType;
typedef const MachineBasicBlock *NodeRef;
typedef MachineBasicBlock::const_pred_iterator ChildIteratorType; typedef MachineBasicBlock::const_pred_iterator ChildIteratorType;
static NodeType *getEntryNode(Inverse<const MachineBasicBlock*> G) { static NodeType *getEntryNode(Inverse<const MachineBasicBlock*> G) {
return G.Graph; return G.Graph;

View File

@ -155,6 +155,7 @@ struct isPodLike<TerminatorInst::SuccIterator<T, U>> {
template <> struct GraphTraits<BasicBlock*> { template <> struct GraphTraits<BasicBlock*> {
typedef BasicBlock NodeType; typedef BasicBlock NodeType;
typedef BasicBlock *NodeRef;
typedef succ_iterator ChildIteratorType; typedef succ_iterator ChildIteratorType;
static NodeType *getEntryNode(BasicBlock *BB) { return BB; } static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
@ -168,6 +169,7 @@ template <> struct GraphTraits<BasicBlock*> {
template <> struct GraphTraits<const BasicBlock*> { template <> struct GraphTraits<const BasicBlock*> {
typedef const BasicBlock NodeType; typedef const BasicBlock NodeType;
typedef const BasicBlock *NodeRef;
typedef succ_const_iterator ChildIteratorType; typedef succ_const_iterator ChildIteratorType;
static NodeType *getEntryNode(const BasicBlock *BB) { return BB; } static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
@ -187,6 +189,7 @@ template <> struct GraphTraits<const BasicBlock*> {
// //
template <> struct GraphTraits<Inverse<BasicBlock*> > { template <> struct GraphTraits<Inverse<BasicBlock*> > {
typedef BasicBlock NodeType; typedef BasicBlock NodeType;
typedef BasicBlock *NodeRef;
typedef pred_iterator ChildIteratorType; typedef pred_iterator ChildIteratorType;
static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; } static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
static inline ChildIteratorType child_begin(NodeType *N) { static inline ChildIteratorType child_begin(NodeType *N) {
@ -199,6 +202,7 @@ template <> struct GraphTraits<Inverse<BasicBlock*> > {
template <> struct GraphTraits<Inverse<const BasicBlock*> > { template <> struct GraphTraits<Inverse<const BasicBlock*> > {
typedef const BasicBlock NodeType; typedef const BasicBlock NodeType;
typedef const BasicBlock *NodeRef;
typedef const_pred_iterator ChildIteratorType; typedef const_pred_iterator ChildIteratorType;
static NodeType *getEntryNode(Inverse<const BasicBlock*> G) { static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
return G.Graph; return G.Graph;

View File

@ -623,6 +623,7 @@ template <> struct GraphTraits<IrreducibleGraph> {
typedef bfi_detail::IrreducibleGraph GraphT; typedef bfi_detail::IrreducibleGraph GraphT;
typedef const GraphT::IrrNode NodeType; typedef const GraphT::IrrNode NodeType;
typedef const GraphT::IrrNode *NodeRef;
typedef GraphT::IrrNode::iterator ChildIteratorType; typedef GraphT::IrrNode::iterator ChildIteratorType;
static const NodeType *getEntryNode(const GraphT &G) { static const NodeType *getEntryNode(const GraphT &G) {

View File

@ -333,6 +333,7 @@ struct ArgumentUsesTracker : public CaptureTracker {
namespace llvm { namespace llvm {
template <> struct GraphTraits<ArgumentGraphNode *> { template <> struct GraphTraits<ArgumentGraphNode *> {
typedef ArgumentGraphNode NodeType; typedef ArgumentGraphNode NodeType;
typedef ArgumentGraphNode *NodeRef;
typedef SmallVectorImpl<ArgumentGraphNode *>::iterator ChildIteratorType; typedef SmallVectorImpl<ArgumentGraphNode *>::iterator ChildIteratorType;
static inline NodeType *getEntryNode(NodeType *A) { return A; } static inline NodeType *getEntryNode(NodeType *A) { return A; }

View File

@ -230,6 +230,7 @@ public:
template <unsigned N> template <unsigned N>
struct GraphTraits<Graph<N> > { struct GraphTraits<Graph<N> > {
typedef typename Graph<N>::NodeType NodeType; typedef typename Graph<N>::NodeType NodeType;
typedef typename Graph<N>::NodeType *NodeRef;
typedef typename Graph<N>::ChildIterator ChildIteratorType; typedef typename Graph<N>::ChildIterator ChildIteratorType;
static inline NodeType *getEntryNode(const Graph<N> &G) { return G.AccessNode(0); } static inline NodeType *getEntryNode(const Graph<N> &G) { return G.AccessNode(0); }