forked from OSchip/llvm-project
[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:
parent
c64d7655b2
commit
b44909eccb
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 *>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
Loading…
Reference in New Issue