DepthFirstIterator.h revision a2769a33c94f021a609a462b28ebea069eba6f74
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
29769ab22265b313171d201b5928688524a01bd87Misha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
79769ab22265b313171d201b5928688524a01bd87Misha Brukman//
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//===----------------------------------------------------------------------===//
97461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner//
10551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer// This file builds on the ADT/GraphTraits.h file to build generic depth
114846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner// first graph iterator.  This file exposes the following functions/types:
124846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner//
134846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner// df_begin/df_end/df_iterator
144846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner//   * Normal depth-first iteration - visit a node and then all of its children.
154846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner//
164846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner// idf_begin/idf_end/idf_iterator
174846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner//   * Depth-first iteration on the 'inverse' graph.
187461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner//
199061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// df_ext_begin/df_ext_end/df_ext_iterator
209061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//   * Normal depth-first iteration - visit a node and then all of its children.
219061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//     This iterator stores the 'visited' set in an external set, which allows
229061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//     it to be more efficient, and allows external clients to use the set for
239061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//     other purposes.
249061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//
259061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// idf_ext_begin/idf_ext_end/idf_ext_iterator
269061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//   * Depth-first iteration on the 'inverse' graph.
279061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//     This iterator stores the 'visited' set in an external set, which allows
289061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//     it to be more efficient, and allows external clients to use the set for
299061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//     other purposes.
309061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner//
317461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner//===----------------------------------------------------------------------===//
327461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
33551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H
34551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#define LLVM_ADT_DEPTHFIRSTITERATOR_H
357461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
36551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/GraphTraits.h"
3743d1fd449f1a0ac9d9dafa0b9569bb6b2e976198Anton Korobeynikov#include "llvm/ADT/iterator.h"
38d3fb6714802d8e44b34980af8772cc3ed398e71aOwen Anderson#include "llvm/ADT/SmallPtrSet.h"
397461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner#include <set>
40a2769a33c94f021a609a462b28ebea069eba6f74Misha Brukman#include <vector>
417461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
42d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
43d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
449061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// df_iterator_storage - A private class which is used to figure out where to
459061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// store the visited set.
469061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate<class SetType, bool External>   // Non-external set
479061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerclass df_iterator_storage {
489061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerpublic:
499061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  SetType Visited;
509061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
519061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
529061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate<class SetType>
539061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerclass df_iterator_storage<SetType, true> {
549061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerpublic:
559061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  df_iterator_storage(SetType &VSet) : Visited(VSet) {}
569061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
579061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  SetType &Visited;
589061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
599061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
609061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
617461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner// Generic Depth First Iterator
62d3fb6714802d8e44b34980af8772cc3ed398e71aOwen Andersontemplate<class GraphT,
63d3fb6714802d8e44b34980af8772cc3ed398e71aOwen Andersonclass SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
649061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner         bool ExtStorage = false, class GT = GraphTraits<GraphT> >
659061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerclass df_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
669061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner                    public df_iterator_storage<SetType, ExtStorage> {
677f4dd472e35569efefbeffef096c490075e3e824Chris Lattner  typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
687f4dd472e35569efefbeffef096c490075e3e824Chris Lattner
697461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  typedef typename GT::NodeType          NodeType;
707461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  typedef typename GT::ChildIteratorType ChildItTy;
717461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
727461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // VisitStack - Used to maintain the ordering.  Top = current block
737461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // First element is node pointer, second is the 'next child' to visit
744846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
757461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnerprivate:
764846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  inline df_iterator(NodeType *Node) {
779061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    this->Visited.insert(Node);
784846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
797461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
807461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline df_iterator() { /* End is when stack is empty */ }
817461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
829061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  inline df_iterator(NodeType *Node, SetType &S)
839061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator_storage<SetType, ExtStorage>(S) {
849061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    if (!S.count(Node)) {
859061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner      this->Visited.insert(Node);
869061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner      VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
879061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    }
889061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  }
899769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline df_iterator(SetType &S)
909061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator_storage<SetType, ExtStorage>(S) {
919061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    // End is when stack is empty
929061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  }
939061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
947461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnerpublic:
9502a31a5af68aaca1b54c7121f04cb56828ccefc2Chris Lattner  typedef typename super::pointer pointer;
969061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self;
977461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
987461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // Provide static begin and end methods as our public "constructors"
99ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  static inline _Self begin(const GraphT& G) {
1004846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    return _Self(GT::getEntryNode(G));
1017461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
102ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  static inline _Self end(const GraphT& G) { return _Self(); }
1037461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1049061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  // Static begin and end methods as our public ctors for external iterators
105ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  static inline _Self begin(const GraphT& G, SetType &S) {
1069061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    return _Self(GT::getEntryNode(G), S);
1079061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  }
108ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); }
1097461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1109769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline bool operator==(const _Self& x) const {
1114846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    return VisitStack.size() == x.VisitStack.size() &&
1124846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner           VisitStack == x.VisitStack;
1137461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1147461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline bool operator!=(const _Self& x) const { return !operator==(x); }
1157461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1169769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline pointer operator*() const {
1174846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    return VisitStack.back().first;
1187461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1197461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1207461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // This is a nonstandard operator-> that dereferences the pointer an extra
1217461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // time... so that you can actually call methods ON the Node, because
1227461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // the contained type is a pointer.  This allows BBIt->getTerminator() f.e.
1237461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  //
1247461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline NodeType *operator->() const { return operator*(); }
1257461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1267461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline _Self& operator++() {   // Preincrement
1274846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    do {
1284846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      std::pair<NodeType *, ChildItTy> &Top = VisitStack.back();
1294846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      NodeType *Node = Top.first;
1304846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      ChildItTy &It  = Top.second;
1319769ab22265b313171d201b5928688524a01bd87Misha Brukman
1324846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      while (It != GT::child_end(Node)) {
1334846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner        NodeType *Next = *It++;
1349061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner        if (!this->Visited.count(Next)) {  // Has our next sibling been visited?
1354846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner          // No, do it now.
1369061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner          this->Visited.insert(Next);
1374846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner          VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
1384846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner          return *this;
1394846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner        }
1404846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      }
1419769ab22265b313171d201b5928688524a01bd87Misha Brukman
1424846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      // Oops, ran out of successors... go up a level on the stack.
1434846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      VisitStack.pop_back();
1444846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    } while (!VisitStack.empty());
1459769ab22265b313171d201b5928688524a01bd87Misha Brukman    return *this;
1467461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1477461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1487461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline _Self operator++(int) { // Postincrement
1499769ab22265b313171d201b5928688524a01bd87Misha Brukman    _Self tmp = *this; ++*this; return tmp;
1507461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1517461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1527461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // nodeVisited - return true if this iterator has already visited the
1537461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // specified node.  This is public, and will probably be used to iterate over
1547461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // nodes that a depth first iteration did not find: ie unreachable nodes.
1557461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  //
1569769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline bool nodeVisited(NodeType *Node) const {
1579061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    return this->Visited.count(Node) != 0;
1587461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1597461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner};
1607461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1617461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1627461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner// Provide global constructors that automatically figure out correct types...
1637461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner//
1647461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
165ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovdf_iterator<T> df_begin(const T& G) {
1664846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  return df_iterator<T>::begin(G);
1677461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
1687461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1697461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
170ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovdf_iterator<T> df_end(const T& G) {
1717461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  return df_iterator<T>::end(G);
1727461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
1737461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1749061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// Provide global definitions of external depth first iterators...
1751e79609e304a24e0cad68534ddf3371479d33b86Chris Lattnertemplate <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
1769061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerstruct df_ext_iterator : public df_iterator<T, SetTy, true> {
1779061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  df_ext_iterator(const df_iterator<T, SetTy, true> &V)
1789061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator<T, SetTy, true>(V) {}
1799061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
1809061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1819061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
182ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovdf_ext_iterator<T, SetTy> df_ext_begin(const T& G, SetTy &S) {
1839061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  return df_ext_iterator<T, SetTy>::begin(G, S);
1849061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
1859061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1869061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
187ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovdf_ext_iterator<T, SetTy> df_ext_end(const T& G, SetTy &S) {
1889061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  return df_ext_iterator<T, SetTy>::end(G, S);
1899061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
1909061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1919061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1927461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner// Provide global definitions of inverse depth first iterators...
193d3fb6714802d8e44b34980af8772cc3ed398e71aOwen Andersontemplate <class T,
194d3fb6714802d8e44b34980af8772cc3ed398e71aOwen Anderson  class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
1959061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner          bool External = false>
1969061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerstruct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
1979061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
1989061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator<Inverse<T>, SetTy, External>(V) {}
1997461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner};
2007461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
2017461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
202ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovidf_iterator<T> idf_begin(const T& G) {
203ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  Inverse<T> DummyG;
204ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  return idf_iterator<T>::begin(DummyG);
2057461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
2067461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
2077461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
208ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovidf_iterator<T> idf_end(const T& G){
209ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  Inverse<T> DummyG;
210ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  return idf_iterator<T>::end(DummyG);
2117461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
2127461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
2139061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// Provide global definitions of external inverse depth first iterators...
2149061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
2159061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerstruct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
2169061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
2179061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : idf_iterator<T, SetTy, true>(V) {}
2189061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
2199061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : idf_iterator<T, SetTy, true>(V) {}
2209061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
2219061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
2229061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
223ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovidf_ext_iterator<T, SetTy> idf_ext_begin(const T& G, SetTy &S) {
224ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  Inverse<T> DummyG(G);
225ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  return idf_ext_iterator<T, SetTy>::begin(DummyG, S);
2269061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
2279061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
2289061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
229ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikovidf_ext_iterator<T, SetTy> idf_ext_end(const T& G, SetTy &S) {
230ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  Inverse<T> DummyG(G);
231ffe9e63c4a11352fd6437588fad516efdb46aa40Anton Korobeynikov  return idf_ext_iterator<T, SetTy>::end(DummyG, S);
2329061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
2339061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
234d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
2359061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
2367461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner#endif
237