X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FADT%2FPostOrderIterator.h;h=bf7ce9d0bb6aa0feb522605613bc9d7fe511e286;hb=a7425d7fde61c2207a4467464df90b5e3e58a769;hp=d66c4b84c40240467f9d2c1439f770d1d4c773d5;hpb=d0fde30ce850b78371fd1386338350591f9ff494;p=oota-llvm.git diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h index d66c4b84c40..bf7ce9d0bb6 100644 --- a/include/llvm/ADT/PostOrderIterator.h +++ b/include/llvm/ADT/PostOrderIterator.h @@ -1,35 +1,53 @@ -//===- Support/PostOrderIterator.h - Generic PostOrder iterator -*- C++ -*-===// -// +//===- llvm/ADT/PostOrderIterator.h - 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 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 +// 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 SUPPORT_POSTORDERITERATOR_H -#define SUPPORT_POSTORDERITERATOR_H +#ifndef LLVM_ADT_POSTORDERITERATOR_H +#define LLVM_ADT_POSTORDERITERATOR_H -#include "Support/GraphTraits.h" -#include "Support/iterator" -#include +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/iterator.h" #include +#include +#include namespace llvm { -template > -class po_iterator : public forward_iterator { +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*>, + bool ExtStorage = false, + class GT = GraphTraits > +class po_iterator : public forward_iterator, + public po_iterator_storage { typedef forward_iterator super; 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; @@ -37,33 +55,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 typename super::pointer pointer; - typedef po_iterator _Self; + 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; } @@ -77,11 +113,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; } }; @@ -92,10 +128,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 @@ -108,14 +164,33 @@ 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 necessary.