X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FPostOrderIterator.h;h=227472b2dd74274826eda7950ed7750960821fd9;hb=aafa94260d5b1b6422258ed3db7244fe4449f217;hp=4f94141b5c4406d21f7400a6f5c560b67d036f2d;hpb=8dc67168ccbd09821ff6d963b26461e9b47028e7;p=oota-llvm.git diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h index 4f94141b5c4..227472b2dd7 100644 --- a/include/llvm/ADT/PostOrderIterator.h +++ b/include/llvm/ADT/PostOrderIterator.h @@ -1,27 +1,54 @@ -//===-- Support/PostOrderIterator.h - Generic PostOrder iterator -*- C++ -*--=// +//===- llvm/ADT/PostOrderIterator.h - PostOrder iterator --------*- C++ -*-===// // -// This file builds on the Support/GraphTraits.h file to build a generic graph +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file builds on the ADT/GraphTraits.h file to build a generic graph // post order iterator. This should work over any graph type that has a // GraphTraits specialization. // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_POSTORDER_ITERATOR_H -#define LLVM_SUPPORT_POSTORDER_ITERATOR_H +#ifndef LLVM_ADT_POSTORDERITERATOR_H +#define LLVM_ADT_POSTORDERITERATOR_H -#include "Support/GraphTraits.h" -#include -#include +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/SmallPtrSet.h" #include +#include +#include -template > -class po_iterator : public forward_iterator { +namespace llvm { + +template // Non-external set +class po_iterator_storage { +public: + SetType Visited; +}; + +template +class po_iterator_storage { +public: + po_iterator_storage(SetType &VSet) : Visited(VSet) {} + po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {} + SetType &Visited; +}; + +template::NodeType*, 8>, + bool ExtStorage = false, + class GT = GraphTraits > +class po_iterator : public forward_iterator, + public po_iterator_storage { typedef forward_iterator super; - typedef typename super::pointer pointer; typedef typename GT::NodeType NodeType; typedef typename GT::ChildIteratorType ChildItTy; - std::set 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 std::stack > VisitStack; @@ -29,32 +56,51 @@ class po_iterator : public forward_iterator { void traverseChild() { while (VisitStack.top().second != GT::child_end(VisitStack.top().first)) { NodeType *BB = *VisitStack.top().second++; - if (!Visited.count(BB)) { // If the block is not visited... - Visited.insert(BB); - VisitStack.push(make_pair(BB, GT::child_begin(BB))); + if (!this->Visited.count(BB)) { // If the block is not visited... + this->Visited.insert(BB); + VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); } } } inline po_iterator(NodeType *BB) { - Visited.insert(BB); - VisitStack.push(make_pair(BB, GT::child_begin(BB))); + this->Visited.insert(BB); + VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); traverseChild(); } - inline po_iterator() { /* End is when stack is empty */ } + inline po_iterator() {} // End is when stack is empty. + + inline po_iterator(NodeType *BB, SetType &S) : + po_iterator_storage(S) { + if(!S.count(BB)) { + this->Visited.insert(BB); + VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); + traverseChild(); + } + } + + inline po_iterator(SetType &S) : + po_iterator_storage(S) { + } // End is when stack is empty. public: - typedef po_iterator _Self; + typedef typename super::pointer pointer; + typedef po_iterator _Self; // Provide static "constructors"... static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); } static inline _Self end (GraphT G) { return _Self(); } - inline bool operator==(const _Self& x) const { + static inline _Self begin(GraphT G, SetType &S) { + return _Self(GT::getEntryNode(G), S); + } + static inline _Self end (GraphT G, SetType &S) { return _Self(S); } + + inline bool operator==(const _Self& x) const { return VisitStack == x.VisitStack; } inline bool operator!=(const _Self& x) const { return !operator==(x); } - inline pointer operator*() const { + inline pointer operator*() const { return VisitStack.top().first; } @@ -68,11 +114,11 @@ public: VisitStack.pop(); if (!VisitStack.empty()) traverseChild(); - return *this; + return *this; } inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + _Self tmp = *this; ++*this; return tmp; } }; @@ -83,10 +129,30 @@ po_iterator po_begin(T G) { return po_iterator::begin(G); } template po_iterator po_end (T G) { return po_iterator::end(G); } +// Provide global definitions of external postorder iterators... +template::NodeType*> > +struct po_ext_iterator : public po_iterator { + po_ext_iterator(const po_iterator &V) : + po_iterator(V) {} +}; + +template +po_ext_iterator po_ext_begin(T G, SetType &S) { + return po_ext_iterator::begin(G, S); +} + +template +po_ext_iterator po_ext_end(T G, SetType &S) { + return po_ext_iterator::end(G, S); +} + // Provide global definitions of inverse post order iterators... -template -struct ipo_iterator : public po_iterator > { - ipo_iterator(const po_iterator > &V) :po_iterator >(V){} +template ::NodeType*>, + bool External = false> +struct ipo_iterator : public po_iterator, SetType, External > { + ipo_iterator(const po_iterator, SetType, External> &V) : + po_iterator, SetType, External> (V) {} }; template @@ -99,21 +165,40 @@ ipo_iterator ipo_end(T G){ return ipo_iterator::end(G); } +//Provide global definitions of external inverse postorder iterators... +template ::NodeType*> > +struct ipo_ext_iterator : public ipo_iterator { + ipo_ext_iterator(const ipo_iterator &V) : + ipo_iterator(&V) {} + ipo_ext_iterator(const po_iterator, SetType, true> &V) : + ipo_iterator(&V) {} +}; + +template +ipo_ext_iterator ipo_ext_begin(T G, SetType &S) { + return ipo_ext_iterator::begin(G, S); +} + +template +ipo_ext_iterator ipo_ext_end(T G, SetType &S) { + return ipo_ext_iterator::end(G, S); +} //===--------------------------------------------------------------------===// // Reverse Post Order CFG iterator code //===--------------------------------------------------------------------===// -// +// // This is used to visit basic blocks in a method in reverse post order. This // class is awkward to use because I don't know a good incremental algorithm to -// computer RPO from a graph. Because of this, the construction of the +// 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: // { -// ReversePostOrderTraversal RPOT(MethodPtr); // Expensive to create +// ReversePostOrderTraversal RPOT(FuncPtr); // Expensive to create // for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) { // ... // } @@ -131,7 +216,7 @@ class ReversePostOrderTraversal { copy(po_begin(BB), po_end(BB), back_inserter(Blocks)); } public: - typedef std::vector::reverse_iterator rpo_iterator; + typedef typename std::vector::reverse_iterator rpo_iterator; inline ReversePostOrderTraversal(GraphT G) { Initialize(GT::getEntryNode(G)); @@ -142,4 +227,6 @@ public: inline rpo_iterator end() { return Blocks.rend(); } }; +} // End llvm namespace + #endif