DepthFirstIterator.h revision 9769ab22265b313171d201b5928688524a01bd87
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
29769ab22265b313171d201b5928688524a01bd87Misha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
5b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell// This file was developed by the LLVM research group and is distributed under
6b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell// the University of Illinois Open Source 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"
37551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/iterator"
384846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner#include <vector>
397461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner#include <set>
407461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
41d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
42d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
439061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// df_iterator_storage - A private class which is used to figure out where to
449061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// store the visited set.
459061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate<class SetType, bool External>   // Non-external set
469061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerclass df_iterator_storage {
479061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerpublic:
489061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  SetType Visited;
499061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
509061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
519061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate<class SetType>
529061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerclass df_iterator_storage<SetType, true> {
539061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerpublic:
549061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  df_iterator_storage(SetType &VSet) : Visited(VSet) {}
559061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
569061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  SetType &Visited;
579061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
589061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
599061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
607461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner// Generic Depth First Iterator
619769ab22265b313171d201b5928688524a01bd87Misha Brukmantemplate<class GraphT, class SetType =
629061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner                            std::set<typename GraphTraits<GraphT>::NodeType*>,
639061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner         bool ExtStorage = false, class GT = GraphTraits<GraphT> >
649061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerclass df_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
659061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner                    public df_iterator_storage<SetType, ExtStorage> {
667f4dd472e35569efefbeffef096c490075e3e824Chris Lattner  typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
677f4dd472e35569efefbeffef096c490075e3e824Chris Lattner
687461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  typedef typename GT::NodeType          NodeType;
697461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  typedef typename GT::ChildIteratorType ChildItTy;
707461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
717461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // VisitStack - Used to maintain the ordering.  Top = current block
727461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // First element is node pointer, second is the 'next child' to visit
734846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
747461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnerprivate:
754846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  inline df_iterator(NodeType *Node) {
769061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    this->Visited.insert(Node);
774846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
787461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
797461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline df_iterator() { /* End is when stack is empty */ }
807461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
819061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  inline df_iterator(NodeType *Node, SetType &S)
829061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator_storage<SetType, ExtStorage>(S) {
839061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    if (!S.count(Node)) {
849061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner      this->Visited.insert(Node);
859061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner      VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
869061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    }
879061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  }
889769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline df_iterator(SetType &S)
899061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator_storage<SetType, ExtStorage>(S) {
909061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    // End is when stack is empty
919061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  }
929061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
937461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnerpublic:
9402a31a5af68aaca1b54c7121f04cb56828ccefc2Chris Lattner  typedef typename super::pointer pointer;
959061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self;
967461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
977461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // Provide static begin and end methods as our public "constructors"
984846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  static inline _Self begin(GraphT G) {
994846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    return _Self(GT::getEntryNode(G));
1007461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1017461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  static inline _Self end(GraphT G) { return _Self(); }
1027461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1039061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  // Static begin and end methods as our public ctors for external iterators
1049061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  static inline _Self begin(GraphT G, SetType &S) {
1059061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    return _Self(GT::getEntryNode(G), S);
1069061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  }
1079061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  static inline _Self end(GraphT G, SetType &S) { return _Self(S); }
1087461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1099769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline bool operator==(const _Self& x) const {
1104846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    return VisitStack.size() == x.VisitStack.size() &&
1114846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner           VisitStack == x.VisitStack;
1127461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1137461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline bool operator!=(const _Self& x) const { return !operator==(x); }
1147461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1159769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline pointer operator*() const {
1164846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    return VisitStack.back().first;
1177461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1187461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1197461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // This is a nonstandard operator-> that dereferences the pointer an extra
1207461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // time... so that you can actually call methods ON the Node, because
1217461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // the contained type is a pointer.  This allows BBIt->getTerminator() f.e.
1227461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  //
1237461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline NodeType *operator->() const { return operator*(); }
1247461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1257461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline _Self& operator++() {   // Preincrement
1264846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    do {
1274846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      std::pair<NodeType *, ChildItTy> &Top = VisitStack.back();
1284846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      NodeType *Node = Top.first;
1294846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      ChildItTy &It  = Top.second;
1309769ab22265b313171d201b5928688524a01bd87Misha Brukman
1314846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      while (It != GT::child_end(Node)) {
1324846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner        NodeType *Next = *It++;
1339061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner        if (!this->Visited.count(Next)) {  // Has our next sibling been visited?
1344846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner          // No, do it now.
1359061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner          this->Visited.insert(Next);
1364846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner          VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
1374846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner          return *this;
1384846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner        }
1394846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      }
1409769ab22265b313171d201b5928688524a01bd87Misha Brukman
1414846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      // Oops, ran out of successors... go up a level on the stack.
1424846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner      VisitStack.pop_back();
1434846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner    } while (!VisitStack.empty());
1449769ab22265b313171d201b5928688524a01bd87Misha Brukman    return *this;
1457461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1467461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1477461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  inline _Self operator++(int) { // Postincrement
1489769ab22265b313171d201b5928688524a01bd87Misha Brukman    _Self tmp = *this; ++*this; return tmp;
1497461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1507461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1517461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // nodeVisited - return true if this iterator has already visited the
1527461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // specified node.  This is public, and will probably be used to iterate over
1537461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  // nodes that a depth first iteration did not find: ie unreachable nodes.
1547461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  //
1559769ab22265b313171d201b5928688524a01bd87Misha Brukman  inline bool nodeVisited(NodeType *Node) const {
1569061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    return this->Visited.count(Node) != 0;
1577461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  }
1587461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner};
1597461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1607461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1617461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner// Provide global constructors that automatically figure out correct types...
1627461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner//
1637461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
1644846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattnerdf_iterator<T> df_begin(T G) {
1654846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  return df_iterator<T>::begin(G);
1667461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
1677461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1687461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
1697461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnerdf_iterator<T> df_end(T G) {
1707461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  return df_iterator<T>::end(G);
1717461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
1727461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1739061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// Provide global definitions of external depth first iterators...
1741e79609e304a24e0cad68534ddf3371479d33b86Chris Lattnertemplate <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
1759061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerstruct df_ext_iterator : public df_iterator<T, SetTy, true> {
1769061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  df_ext_iterator(const df_iterator<T, SetTy, true> &V)
1779061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator<T, SetTy, true>(V) {}
1789061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
1799061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1809061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
1819061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerdf_ext_iterator<T, SetTy> df_ext_begin(T G, SetTy &S) {
1829061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  return df_ext_iterator<T, SetTy>::begin(G, S);
1839061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
1849061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1859061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
1869061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerdf_ext_iterator<T, SetTy> df_ext_end(T G, SetTy &S) {
1879061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  return df_ext_iterator<T, SetTy>::end(G, S);
1889061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
1899061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1909061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
1917461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner// Provide global definitions of inverse depth first iterators...
1929061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*>,
1939061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner          bool External = false>
1949061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerstruct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
1959061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
1969061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : df_iterator<Inverse<T>, SetTy, External>(V) {}
1977461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner};
1987461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
1997461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
2004846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattneridf_iterator<T> idf_begin(T G) {
2014846f4b87a31797ba0bc6c96862a1128acf16149Chris Lattner  return idf_iterator<T>::begin(G);
2027461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
2037461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
2047461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattnertemplate <class T>
2057461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattneridf_iterator<T> idf_end(T G){
2067461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner  return idf_iterator<T>::end(G);
2077461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner}
2087461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner
2099061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner// Provide global definitions of external inverse depth first iterators...
2109061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
2119061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnerstruct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
2129061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
2139061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : idf_iterator<T, SetTy, true>(V) {}
2149061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
2159061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner    : idf_iterator<T, SetTy, true>(V) {}
2169061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner};
2179061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
2189061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
2199061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattneridf_ext_iterator<T, SetTy> idf_ext_begin(T G, SetTy &S) {
2209061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  return idf_ext_iterator<T, SetTy>::begin(G, S);
2219061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
2229061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
2239061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattnertemplate <class T, class SetTy>
2249061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattneridf_ext_iterator<T, SetTy> idf_ext_end(T G, SetTy &S) {
2259061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner  return idf_ext_iterator<T, SetTy>::end(G, S);
2269061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner}
2279061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
228d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
2299061e992d5ee0c59c89ae7812c551bafd680a59cChris Lattner
2307461bf5f8e1e9be67f4ce19f35a32a88668934c7Chris Lattner#endif
231