-//===-- Support/PostOrderIterator.h - Generic PostOrder iterator -*- C++ -*--=//
+//===- Support/PostOrderIterator.h - Generic PostOrder iterator -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
//
// This file builds on the Support/GraphTraits.h file to build a generic graph
// post order iterator. This should work over any graph type that has a
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_POSTORDER_ITERATOR_H
-#define LLVM_SUPPORT_POSTORDER_ITERATOR_H
+#ifndef SUPPORT_POSTORDERITERATOR_H
+#define SUPPORT_POSTORDERITERATOR_H
#include "Support/GraphTraits.h"
-#include <iterator>
+#include "Support/iterator"
#include <stack>
#include <set>
template<class GraphT, class GT = GraphTraits<GraphT> >
-class po_iterator : public std::forward_iterator<typename GT::NodeType,
- ptrdiff_t> {
+class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t> {
+ typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
typedef typename GT::NodeType NodeType;
typedef typename GT::ChildIteratorType ChildItTy;
- set<NodeType *> Visited; // All of the blocks visited so far...
+ std::set<NodeType *> Visited; // All of the blocks visited so far...
// VisitStack - Used to maintain the ordering. Top = current block
// First element is basic block pointer, second is the 'next child' to visit
- stack<pair<NodeType *, ChildItTy> > VisitStack;
+ std::stack<std::pair<NodeType *, ChildItTy> > VisitStack;
void traverseChild() {
while (VisitStack.top().second != GT::child_end(VisitStack.top().first)) {
}
inline po_iterator() { /* End is when stack is empty */ }
public:
+ typedef typename super::pointer pointer;
typedef po_iterator<GraphT, GT> _Self;
// Provide static "constructors"...
// computer RPO from a graph. Because of this, the construction of the
// ReversePostOrderTraversal object is expensive (it must walk the entire graph
// with a postorder iterator to build the data structures). The moral of this
-// story is: Don't create more ReversePostOrderTraversal classes than neccesary.
+// story is: Don't create more ReversePostOrderTraversal classes than necessary.
//
// This class should be used like this:
// {
-// cfg::ReversePostOrderTraversal RPOT(MethodPtr); // Expensive to create
-// for (cfg::rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ReversePostOrderTraversal<Function*> RPOT(FuncPtr); // Expensive to create
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
// ...
// }
-// for (cfg::rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
// ...
// }
// }
//
-typedef reverse_iterator<vector<BasicBlock*>::iterator> rpo_iterator;
-// TODO: FIXME: ReversePostOrderTraversal is not generic!
+template<class GraphT, class GT = GraphTraits<GraphT> >
class ReversePostOrderTraversal {
- vector<BasicBlock*> Blocks; // Block list in normal PO order
- inline void Initialize(BasicBlock *BB) {
+ typedef typename GT::NodeType NodeType;
+ std::vector<NodeType*> Blocks; // Block list in normal PO order
+ inline void Initialize(NodeType *BB) {
copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
}
public:
- inline ReversePostOrderTraversal(Method *M) {
- Initialize(M->front());
- }
- inline ReversePostOrderTraversal(BasicBlock *BB) {
- Initialize(BB);
+ typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
+
+ inline ReversePostOrderTraversal(GraphT G) {
+ Initialize(GT::getEntryNode(G));
}
// Because we want a reverse post order, use reverse iterators from the vector