[ADT] Change PostOrderIterator to use NodeRef. NFC.

Reviewers: dblaikie

Subscribers: mzolotukhin, llvm-commits

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

llvm-svn: 278752
This commit is contained in:
Tim Shen 2016-08-15 21:52:54 +00:00
parent 41520e1712
commit e0793db41d
5 changed files with 45 additions and 46 deletions

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/Optional.h"
#include <set>
#include <vector>
@ -56,14 +57,13 @@ class po_iterator_storage {
SetType Visited;
public:
// Return true if edge destination should be visited.
template<typename NodeType>
bool insertEdge(NodeType *From, NodeType *To) {
template <typename NodeRef>
bool insertEdge(Optional<NodeRef> From, NodeRef To) {
return Visited.insert(To).second;
}
// Called after all children of BB have been visited.
template<typename NodeType>
void finishPostorder(NodeType *BB) {}
template <typename NodeRef> void finishPostorder(NodeRef BB) {}
};
/// Specialization of po_iterator_storage that references an external set.
@ -77,51 +77,49 @@ public:
// Return true if edge destination should be visited, called with From = 0 for
// the root node.
// Graph edges can be pruned by specializing this function.
template <class NodeType> bool insertEdge(NodeType *From, NodeType *To) {
template <class NodeRef> bool insertEdge(Optional<NodeRef> From, NodeRef To) {
return Visited.insert(To).second;
}
// Called after all children of BB have been visited.
template<class NodeType>
void finishPostorder(NodeType *BB) {}
template <class NodeRef> void finishPostorder(NodeRef BB) {}
};
template<class GraphT,
class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
bool ExtStorage = false,
class GT = GraphTraits<GraphT> >
class po_iterator : public std::iterator<std::forward_iterator_tag,
typename GT::NodeType, ptrdiff_t>,
public po_iterator_storage<SetType, ExtStorage> {
typedef std::iterator<std::forward_iterator_tag,
typename GT::NodeType, ptrdiff_t> super;
typedef typename GT::NodeType NodeType;
template <class GraphT,
class SetType =
llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeRef, 8>,
bool ExtStorage = false, class GT = GraphTraits<GraphT>>
class po_iterator
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
public po_iterator_storage<SetType, ExtStorage> {
typedef std::iterator<std::forward_iterator_tag, typename GT::NodeRef> super;
typedef typename GT::NodeRef NodeRef;
typedef typename GT::ChildIteratorType ChildItTy;
// VisitStack - Used to maintain the ordering. Top = current block
// First element is basic block pointer, second is the 'next child' to visit
std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
std::vector<std::pair<NodeRef, ChildItTy>> VisitStack;
void traverseChild() {
while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
NodeType *BB = *VisitStack.back().second++;
if (this->insertEdge(VisitStack.back().first, BB)) {
NodeRef BB = *VisitStack.back().second++;
if (this->insertEdge(Optional<NodeRef>(VisitStack.back().first), BB)) {
// If the block is not visited...
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
}
}
}
po_iterator(NodeType *BB) {
this->insertEdge((NodeType*)nullptr, BB);
po_iterator(NodeRef BB) {
this->insertEdge(Optional<NodeRef>(), BB);
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
traverseChild();
}
po_iterator() {} // End is when stack is empty.
po_iterator(NodeType *BB, SetType &S)
po_iterator(NodeRef BB, SetType &S)
: po_iterator_storage<SetType, ExtStorage>(S) {
if (this->insertEdge((NodeType*)nullptr, BB)) {
if (this->insertEdge(Optional<NodeRef>(), BB)) {
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
traverseChild();
}
@ -149,13 +147,13 @@ public:
}
bool operator!=(const po_iterator &x) const { return !(*this == x); }
pointer operator*() const { return VisitStack.back().first; }
const NodeRef &operator*() const { return VisitStack.back().first; }
// This is a nonstandard operator-> that dereferences the pointer an extra
// time... so that you can actually call methods ON the BasicBlock, because
// the contained type is a pointer. This allows BBIt->getTerminator() f.e.
//
NodeType *operator->() const { return **this; }
NodeRef operator->() const { return **this; }
po_iterator &operator++() { // Preincrement
this->finishPostorder(VisitStack.back().first);
@ -184,7 +182,7 @@ template <class T> iterator_range<po_iterator<T>> post_order(const T &G) {
}
// Provide global definitions of external postorder iterators...
template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
template <class T, class SetType = std::set<typename GraphTraits<T>::NodeRef>>
struct po_ext_iterator : public po_iterator<T, SetType, true> {
po_ext_iterator(const po_iterator<T, SetType, true> &V) :
po_iterator<T, SetType, true>(V) {}
@ -206,10 +204,9 @@ iterator_range<po_ext_iterator<T, SetType>> post_order_ext(const T &G, SetType &
}
// Provide global definitions of inverse post order iterators...
template <class T,
class SetType = std::set<typename GraphTraits<T>::NodeType*>,
template <class T, class SetType = std::set<typename GraphTraits<T>::NodeRef>,
bool External = false>
struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External> {
ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) :
po_iterator<Inverse<T>, SetType, External> (V) {}
};
@ -230,8 +227,7 @@ iterator_range<ipo_iterator<T>> inverse_post_order(const T &G) {
}
// Provide global definitions of external inverse postorder iterators...
template <class T,
class SetType = std::set<typename GraphTraits<T>::NodeType*> >
template <class T, class SetType = std::set<typename GraphTraits<T>::NodeRef>>
struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
ipo_iterator<T, SetType, true>(V) {}
@ -280,13 +276,13 @@ inverse_post_order_ext(const T &G, SetType &S) {
template<class GraphT, class GT = GraphTraits<GraphT> >
class ReversePostOrderTraversal {
typedef typename GT::NodeType NodeType;
std::vector<NodeType*> Blocks; // Block list in normal PO order
void Initialize(NodeType *BB) {
typedef typename GT::NodeRef NodeRef;
std::vector<NodeRef> Blocks; // Block list in normal PO order
void Initialize(NodeRef BB) {
std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks));
}
public:
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
typedef typename std::vector<NodeRef>::reverse_iterator rpo_iterator;
ReversePostOrderTraversal(GraphT G) { Initialize(GT::getEntryNode(G)); }

View File

@ -114,7 +114,7 @@ template<> class po_iterator_storage<LoopBlocksTraversal, true> {
public:
po_iterator_storage(LoopBlocksTraversal &lbs) : LBT(lbs) {}
// These functions are defined below.
bool insertEdge(BasicBlock *From, BasicBlock *To);
bool insertEdge(Optional<BasicBlock *> From, BasicBlock *To);
void finishPostorder(BasicBlock *BB);
};
@ -166,8 +166,8 @@ public:
}
};
inline bool po_iterator_storage<LoopBlocksTraversal, true>::
insertEdge(BasicBlock *From, BasicBlock *To) {
inline bool po_iterator_storage<LoopBlocksTraversal, true>::insertEdge(
Optional<BasicBlock *> From, BasicBlock *To) {
return LBT.visitPreorder(To);
}

View File

@ -430,6 +430,7 @@ template <> struct isa_impl<PointerType, Type> {
template <> struct GraphTraits<Type *> {
typedef Type NodeType;
typedef Type *NodeRef;
typedef Type::subtype_iterator ChildIteratorType;
static inline NodeType *getEntryNode(Type *T) { return T; }
@ -443,6 +444,7 @@ template <> struct GraphTraits<Type *> {
template <> struct GraphTraits<const Type*> {
typedef const Type NodeType;
typedef const Type *NodeRef;
typedef Type::subtype_iterator ChildIteratorType;
static inline NodeType *getEntryNode(NodeType *T) { return T; }

View File

@ -430,16 +430,17 @@ public:
po_iterator_storage(LoopBounds &lb) : LB(lb) {}
void finishPostorder(const MachineBasicBlock*) {}
bool insertEdge(const MachineBasicBlock *From, const MachineBasicBlock *To) {
bool insertEdge(Optional<const MachineBasicBlock *> From,
const MachineBasicBlock *To) {
// Skip already visited To blocks.
MachineTraceMetrics::TraceBlockInfo &TBI = LB.Blocks[To->getNumber()];
if (LB.Downward ? TBI.hasValidHeight() : TBI.hasValidDepth())
return false;
// From is null once when To is the trace center block.
if (From) {
if (const MachineLoop *FromLoop = LB.Loops->getLoopFor(From)) {
if (const MachineLoop *FromLoop = LB.Loops->getLoopFor(*From)) {
// Don't follow backedges, don't leave FromLoop when going upwards.
if ((LB.Downward ? To : From) == FromLoop->getHeader())
if ((LB.Downward ? To : *From) == FromLoop->getHeader())
return false;
// Don't leave FromLoop.
if (isExitingLoop(FromLoop, LB.Loops->getLoopFor(To)))

View File

@ -21,17 +21,17 @@ TEST(PostOrderIteratorTest, Compiles) {
// Tests that template specializations are kept up to date
void *Null = nullptr;
po_iterator_storage<std::set<void *>, false> PIS;
PIS.insertEdge(Null, Null);
PIS.insertEdge(Optional<void *>(), Null);
ExtSetTy Ext;
po_iterator_storage<ExtSetTy, true> PISExt(Ext);
PIS.insertEdge(Null, Null);
PIS.insertEdge(Optional<void *>(), Null);
// Test above, but going through po_iterator (which inherits from template
// base)
BasicBlock *NullBB = nullptr;
auto PI = po_end(NullBB);
PI.insertEdge(NullBB, NullBB);
PI.insertEdge(Optional<BasicBlock *>(), NullBB);
auto PIExt = po_ext_end(NullBB, Ext);
PIExt.insertEdge(NullBB, NullBB);
PIExt.insertEdge(Optional<BasicBlock *>(), NullBB);
}
}