Index: include/llvm/ADT/PostOrderIterator.h =================================================================== --- include/llvm/ADT/PostOrderIterator.h +++ include/llvm/ADT/PostOrderIterator.h @@ -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 #include @@ -56,14 +57,13 @@ SetType Visited; public: // Return true if edge destination should be visited. - template - bool insertEdge(NodeType *From, NodeType *To) { + template + bool insertEdge(Optional From, NodeRef To) { return Visited.insert(To).second; } // Called after all children of BB have been visited. - template - void finishPostorder(NodeType *BB) {} + template void finishPostorder(NodeRef BB) {} }; /// Specialization of po_iterator_storage that references an external set. @@ -77,51 +77,53 @@ // 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 bool insertEdge(NodeType *From, NodeType *To) { + template bool insertEdge(Optional From, NodeRef To) { return Visited.insert(To).second; } // Called after all children of BB have been visited. - template - void finishPostorder(NodeType *BB) {} + template void finishPostorder(NodeRef BB) {} }; -template::NodeType*, 8>, - bool ExtStorage = false, - class GT = GraphTraits > -class po_iterator : public std::iterator, - public po_iterator_storage { - typedef std::iterator super; - typedef typename GT::NodeType NodeType; +template ::NodeRef, 8>, + bool ExtStorage = false, class GT = GraphTraits> +class po_iterator + : public std::iterator, + public po_iterator_storage { + typedef std::iterator + 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 > VisitStack; + std::vector> 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(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(), 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(S) { - if (this->insertEdge((NodeType*)nullptr, BB)) { + if (this->insertEdge(Optional(), BB)) { VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB))); traverseChild(); } @@ -155,7 +157,7 @@ // 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 +186,7 @@ } // Provide global definitions of external postorder iterators... -template::NodeType*> > +template ::NodeRef>> struct po_ext_iterator : public po_iterator { po_ext_iterator(const po_iterator &V) : po_iterator(V) {} @@ -206,10 +208,9 @@ } // Provide global definitions of inverse post order iterators... -template ::NodeType*>, +template ::NodeRef>, bool External = false> -struct ipo_iterator : public po_iterator, SetType, External > { +struct ipo_iterator : public po_iterator, SetType, External> { ipo_iterator(const po_iterator, SetType, External> &V) : po_iterator, SetType, External> (V) {} }; @@ -230,8 +231,7 @@ } // Provide global definitions of external inverse postorder iterators... -template ::NodeType*> > +template ::NodeRef>> struct ipo_ext_iterator : public ipo_iterator { ipo_ext_iterator(const ipo_iterator &V) : ipo_iterator(V) {} @@ -280,13 +280,13 @@ template > class ReversePostOrderTraversal { - typedef typename GT::NodeType NodeType; - std::vector Blocks; // Block list in normal PO order - void Initialize(NodeType *BB) { + typedef typename GT::NodeRef NodeRef; + std::vector 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::reverse_iterator rpo_iterator; + typedef typename std::vector::reverse_iterator rpo_iterator; ReversePostOrderTraversal(GraphT G) { Initialize(GT::getEntryNode(G)); } Index: include/llvm/Analysis/LoopIterator.h =================================================================== --- include/llvm/Analysis/LoopIterator.h +++ include/llvm/Analysis/LoopIterator.h @@ -114,7 +114,7 @@ public: po_iterator_storage(LoopBlocksTraversal &lbs) : LBT(lbs) {} // These functions are defined below. - bool insertEdge(BasicBlock *From, BasicBlock *To); + bool insertEdge(Optional From, BasicBlock *To); void finishPostorder(BasicBlock *BB); }; @@ -166,8 +166,8 @@ } }; -inline bool po_iterator_storage:: -insertEdge(BasicBlock *From, BasicBlock *To) { +inline bool po_iterator_storage::insertEdge( + Optional From, BasicBlock *To) { return LBT.visitPreorder(To); } Index: include/llvm/IR/Type.h =================================================================== --- include/llvm/IR/Type.h +++ include/llvm/IR/Type.h @@ -430,6 +430,7 @@ template <> struct GraphTraits { 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 { typedef const Type NodeType; + typedef const Type *NodeRef; typedef Type::subtype_iterator ChildIteratorType; static inline NodeType *getEntryNode(NodeType *T) { return T; } Index: lib/CodeGen/MachineTraceMetrics.cpp =================================================================== --- lib/CodeGen/MachineTraceMetrics.cpp +++ lib/CodeGen/MachineTraceMetrics.cpp @@ -430,16 +430,17 @@ po_iterator_storage(LoopBounds &lb) : LB(lb) {} void finishPostorder(const MachineBasicBlock*) {} - bool insertEdge(const MachineBasicBlock *From, const MachineBasicBlock *To) { + bool insertEdge(Optional 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))) Index: unittests/ADT/PostOrderIteratorTest.cpp =================================================================== --- unittests/ADT/PostOrderIteratorTest.cpp +++ unittests/ADT/PostOrderIteratorTest.cpp @@ -21,17 +21,17 @@ // Tests that template specializations are kept up to date void *Null = nullptr; po_iterator_storage, false> PIS; - PIS.insertEdge(Null, Null); + PIS.insertEdge(Optional(), Null); ExtSetTy Ext; po_iterator_storage PISExt(Ext); - PIS.insertEdge(Null, Null); + PIS.insertEdge(Optional(), 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(), NullBB); auto PIExt = po_ext_end(NullBB, Ext); - PIExt.insertEdge(NullBB, NullBB); + PIExt.insertEdge(Optional(), NullBB); } }