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