xref: /aosp_15_r20/external/llvm/include/llvm/ADT/DepthFirstIterator.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file builds on the ADT/GraphTraits.h file to build generic depth
11*9880d681SAndroid Build Coastguard Worker // first graph iterator.  This file exposes the following functions/types:
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker // df_begin/df_end/df_iterator
14*9880d681SAndroid Build Coastguard Worker //   * Normal depth-first iteration - visit a node and then all of its children.
15*9880d681SAndroid Build Coastguard Worker //
16*9880d681SAndroid Build Coastguard Worker // idf_begin/idf_end/idf_iterator
17*9880d681SAndroid Build Coastguard Worker //   * Depth-first iteration on the 'inverse' graph.
18*9880d681SAndroid Build Coastguard Worker //
19*9880d681SAndroid Build Coastguard Worker // df_ext_begin/df_ext_end/df_ext_iterator
20*9880d681SAndroid Build Coastguard Worker //   * Normal depth-first iteration - visit a node and then all of its children.
21*9880d681SAndroid Build Coastguard Worker //     This iterator stores the 'visited' set in an external set, which allows
22*9880d681SAndroid Build Coastguard Worker //     it to be more efficient, and allows external clients to use the set for
23*9880d681SAndroid Build Coastguard Worker //     other purposes.
24*9880d681SAndroid Build Coastguard Worker //
25*9880d681SAndroid Build Coastguard Worker // idf_ext_begin/idf_ext_end/idf_ext_iterator
26*9880d681SAndroid Build Coastguard Worker //   * Depth-first iteration on the 'inverse' graph.
27*9880d681SAndroid Build Coastguard Worker //     This iterator stores the 'visited' set in an external set, which allows
28*9880d681SAndroid Build Coastguard Worker //     it to be more efficient, and allows external clients to use the set for
29*9880d681SAndroid Build Coastguard Worker //     other purposes.
30*9880d681SAndroid Build Coastguard Worker //
31*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H
34*9880d681SAndroid Build Coastguard Worker #define LLVM_ADT_DEPTHFIRSTITERATOR_H
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/GraphTraits.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/PointerIntPair.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/iterator_range.h"
40*9880d681SAndroid Build Coastguard Worker #include <set>
41*9880d681SAndroid Build Coastguard Worker #include <vector>
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker namespace llvm {
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker // df_iterator_storage - A private class which is used to figure out where to
46*9880d681SAndroid Build Coastguard Worker // store the visited set.
47*9880d681SAndroid Build Coastguard Worker template<class SetType, bool External>   // Non-external set
48*9880d681SAndroid Build Coastguard Worker class df_iterator_storage {
49*9880d681SAndroid Build Coastguard Worker public:
50*9880d681SAndroid Build Coastguard Worker   SetType Visited;
51*9880d681SAndroid Build Coastguard Worker };
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker template<class SetType>
54*9880d681SAndroid Build Coastguard Worker class df_iterator_storage<SetType, true> {
55*9880d681SAndroid Build Coastguard Worker public:
df_iterator_storage(SetType & VSet)56*9880d681SAndroid Build Coastguard Worker   df_iterator_storage(SetType &VSet) : Visited(VSet) {}
df_iterator_storage(const df_iterator_storage & S)57*9880d681SAndroid Build Coastguard Worker   df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
58*9880d681SAndroid Build Coastguard Worker   SetType &Visited;
59*9880d681SAndroid Build Coastguard Worker };
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker // Generic Depth First Iterator
62*9880d681SAndroid Build Coastguard Worker template<class GraphT,
63*9880d681SAndroid Build Coastguard Worker class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
64*9880d681SAndroid Build Coastguard Worker          bool ExtStorage = false, class GT = GraphTraits<GraphT> >
65*9880d681SAndroid Build Coastguard Worker class df_iterator : public std::iterator<std::forward_iterator_tag,
66*9880d681SAndroid Build Coastguard Worker                                          typename GT::NodeType, ptrdiff_t>,
67*9880d681SAndroid Build Coastguard Worker                     public df_iterator_storage<SetType, ExtStorage> {
68*9880d681SAndroid Build Coastguard Worker   typedef std::iterator<std::forward_iterator_tag,
69*9880d681SAndroid Build Coastguard Worker                         typename GT::NodeType, ptrdiff_t> super;
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   typedef typename GT::NodeType          NodeType;
72*9880d681SAndroid Build Coastguard Worker   typedef typename GT::ChildIteratorType ChildItTy;
73*9880d681SAndroid Build Coastguard Worker   typedef PointerIntPair<NodeType*, 1>   PointerIntTy;
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker   // VisitStack - Used to maintain the ordering.  Top = current block
76*9880d681SAndroid Build Coastguard Worker   // First element is node pointer, second is the 'next child' to visit
77*9880d681SAndroid Build Coastguard Worker   // if the int in PointerIntTy is 0, the 'next child' to visit is invalid
78*9880d681SAndroid Build Coastguard Worker   std::vector<std::pair<PointerIntTy, ChildItTy>> VisitStack;
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker private:
df_iterator(NodeType * Node)81*9880d681SAndroid Build Coastguard Worker   inline df_iterator(NodeType *Node) {
82*9880d681SAndroid Build Coastguard Worker     this->Visited.insert(Node);
83*9880d681SAndroid Build Coastguard Worker     VisitStack.push_back(
84*9880d681SAndroid Build Coastguard Worker         std::make_pair(PointerIntTy(Node, 0), GT::child_begin(Node)));
85*9880d681SAndroid Build Coastguard Worker   }
df_iterator()86*9880d681SAndroid Build Coastguard Worker   inline df_iterator() {
87*9880d681SAndroid Build Coastguard Worker     // End is when stack is empty
88*9880d681SAndroid Build Coastguard Worker   }
df_iterator(NodeType * Node,SetType & S)89*9880d681SAndroid Build Coastguard Worker   inline df_iterator(NodeType *Node, SetType &S)
90*9880d681SAndroid Build Coastguard Worker     : df_iterator_storage<SetType, ExtStorage>(S) {
91*9880d681SAndroid Build Coastguard Worker     if (!S.count(Node)) {
92*9880d681SAndroid Build Coastguard Worker       VisitStack.push_back(
93*9880d681SAndroid Build Coastguard Worker           std::make_pair(PointerIntTy(Node, 0), GT::child_begin(Node)));
94*9880d681SAndroid Build Coastguard Worker       this->Visited.insert(Node);
95*9880d681SAndroid Build Coastguard Worker     }
96*9880d681SAndroid Build Coastguard Worker   }
df_iterator(SetType & S)97*9880d681SAndroid Build Coastguard Worker   inline df_iterator(SetType &S)
98*9880d681SAndroid Build Coastguard Worker     : df_iterator_storage<SetType, ExtStorage>(S) {
99*9880d681SAndroid Build Coastguard Worker     // End is when stack is empty
100*9880d681SAndroid Build Coastguard Worker   }
101*9880d681SAndroid Build Coastguard Worker 
toNext()102*9880d681SAndroid Build Coastguard Worker   inline void toNext() {
103*9880d681SAndroid Build Coastguard Worker     do {
104*9880d681SAndroid Build Coastguard Worker       std::pair<PointerIntTy, ChildItTy> &Top = VisitStack.back();
105*9880d681SAndroid Build Coastguard Worker       NodeType *Node = Top.first.getPointer();
106*9880d681SAndroid Build Coastguard Worker       ChildItTy &It  = Top.second;
107*9880d681SAndroid Build Coastguard Worker       if (!Top.first.getInt()) {
108*9880d681SAndroid Build Coastguard Worker         // now retrieve the real begin of the children before we dive in
109*9880d681SAndroid Build Coastguard Worker         It = GT::child_begin(Node);
110*9880d681SAndroid Build Coastguard Worker         Top.first.setInt(1);
111*9880d681SAndroid Build Coastguard Worker       }
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker       while (It != GT::child_end(Node)) {
114*9880d681SAndroid Build Coastguard Worker         NodeType *Next = *It++;
115*9880d681SAndroid Build Coastguard Worker         // Has our next sibling been visited?
116*9880d681SAndroid Build Coastguard Worker         if (Next && this->Visited.insert(Next).second) {
117*9880d681SAndroid Build Coastguard Worker           // No, do it now.
118*9880d681SAndroid Build Coastguard Worker           VisitStack.push_back(
119*9880d681SAndroid Build Coastguard Worker               std::make_pair(PointerIntTy(Next, 0), GT::child_begin(Next)));
120*9880d681SAndroid Build Coastguard Worker           return;
121*9880d681SAndroid Build Coastguard Worker         }
122*9880d681SAndroid Build Coastguard Worker       }
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker       // Oops, ran out of successors... go up a level on the stack.
125*9880d681SAndroid Build Coastguard Worker       VisitStack.pop_back();
126*9880d681SAndroid Build Coastguard Worker     } while (!VisitStack.empty());
127*9880d681SAndroid Build Coastguard Worker   }
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker public:
130*9880d681SAndroid Build Coastguard Worker   typedef typename super::pointer pointer;
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker   // Provide static begin and end methods as our public "constructors"
begin(const GraphT & G)133*9880d681SAndroid Build Coastguard Worker   static df_iterator begin(const GraphT &G) {
134*9880d681SAndroid Build Coastguard Worker     return df_iterator(GT::getEntryNode(G));
135*9880d681SAndroid Build Coastguard Worker   }
end(const GraphT & G)136*9880d681SAndroid Build Coastguard Worker   static df_iterator end(const GraphT &G) { return df_iterator(); }
137*9880d681SAndroid Build Coastguard Worker 
138*9880d681SAndroid Build Coastguard Worker   // Static begin and end methods as our public ctors for external iterators
begin(const GraphT & G,SetType & S)139*9880d681SAndroid Build Coastguard Worker   static df_iterator begin(const GraphT &G, SetType &S) {
140*9880d681SAndroid Build Coastguard Worker     return df_iterator(GT::getEntryNode(G), S);
141*9880d681SAndroid Build Coastguard Worker   }
end(const GraphT & G,SetType & S)142*9880d681SAndroid Build Coastguard Worker   static df_iterator end(const GraphT &G, SetType &S) { return df_iterator(S); }
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker   bool operator==(const df_iterator &x) const {
145*9880d681SAndroid Build Coastguard Worker     return VisitStack == x.VisitStack;
146*9880d681SAndroid Build Coastguard Worker   }
147*9880d681SAndroid Build Coastguard Worker   bool operator!=(const df_iterator &x) const { return !(*this == x); }
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   pointer operator*() const { return VisitStack.back().first.getPointer(); }
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker   // This is a nonstandard operator-> that dereferences the pointer an extra
152*9880d681SAndroid Build Coastguard Worker   // time... so that you can actually call methods ON the Node, because
153*9880d681SAndroid Build Coastguard Worker   // the contained type is a pointer.  This allows BBIt->getTerminator() f.e.
154*9880d681SAndroid Build Coastguard Worker   //
155*9880d681SAndroid Build Coastguard Worker   NodeType *operator->() const { return **this; }
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker   df_iterator &operator++() { // Preincrement
158*9880d681SAndroid Build Coastguard Worker     toNext();
159*9880d681SAndroid Build Coastguard Worker     return *this;
160*9880d681SAndroid Build Coastguard Worker   }
161*9880d681SAndroid Build Coastguard Worker 
162*9880d681SAndroid Build Coastguard Worker   /// \brief Skips all children of the current node and traverses to next node
163*9880d681SAndroid Build Coastguard Worker   ///
164*9880d681SAndroid Build Coastguard Worker   /// Note: This function takes care of incrementing the iterator. If you
165*9880d681SAndroid Build Coastguard Worker   /// always increment and call this function, you risk walking off the end.
skipChildren()166*9880d681SAndroid Build Coastguard Worker   df_iterator &skipChildren() {
167*9880d681SAndroid Build Coastguard Worker     VisitStack.pop_back();
168*9880d681SAndroid Build Coastguard Worker     if (!VisitStack.empty())
169*9880d681SAndroid Build Coastguard Worker       toNext();
170*9880d681SAndroid Build Coastguard Worker     return *this;
171*9880d681SAndroid Build Coastguard Worker   }
172*9880d681SAndroid Build Coastguard Worker 
173*9880d681SAndroid Build Coastguard Worker   df_iterator operator++(int) { // Postincrement
174*9880d681SAndroid Build Coastguard Worker     df_iterator tmp = *this;
175*9880d681SAndroid Build Coastguard Worker     ++*this;
176*9880d681SAndroid Build Coastguard Worker     return tmp;
177*9880d681SAndroid Build Coastguard Worker   }
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker   // nodeVisited - return true if this iterator has already visited the
180*9880d681SAndroid Build Coastguard Worker   // specified node.  This is public, and will probably be used to iterate over
181*9880d681SAndroid Build Coastguard Worker   // nodes that a depth first iteration did not find: ie unreachable nodes.
182*9880d681SAndroid Build Coastguard Worker   //
nodeVisited(NodeType * Node)183*9880d681SAndroid Build Coastguard Worker   bool nodeVisited(NodeType *Node) const {
184*9880d681SAndroid Build Coastguard Worker     return this->Visited.count(Node) != 0;
185*9880d681SAndroid Build Coastguard Worker   }
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker   /// getPathLength - Return the length of the path from the entry node to the
188*9880d681SAndroid Build Coastguard Worker   /// current node, counting both nodes.
getPathLength()189*9880d681SAndroid Build Coastguard Worker   unsigned getPathLength() const { return VisitStack.size(); }
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker   /// getPath - Return the n'th node in the path from the entry node to the
192*9880d681SAndroid Build Coastguard Worker   /// current node.
getPath(unsigned n)193*9880d681SAndroid Build Coastguard Worker   NodeType *getPath(unsigned n) const {
194*9880d681SAndroid Build Coastguard Worker     return VisitStack[n].first.getPointer();
195*9880d681SAndroid Build Coastguard Worker   }
196*9880d681SAndroid Build Coastguard Worker };
197*9880d681SAndroid Build Coastguard Worker 
198*9880d681SAndroid Build Coastguard Worker // Provide global constructors that automatically figure out correct types...
199*9880d681SAndroid Build Coastguard Worker //
200*9880d681SAndroid Build Coastguard Worker template <class T>
df_begin(const T & G)201*9880d681SAndroid Build Coastguard Worker df_iterator<T> df_begin(const T& G) {
202*9880d681SAndroid Build Coastguard Worker   return df_iterator<T>::begin(G);
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker template <class T>
df_end(const T & G)206*9880d681SAndroid Build Coastguard Worker df_iterator<T> df_end(const T& G) {
207*9880d681SAndroid Build Coastguard Worker   return df_iterator<T>::end(G);
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker 
210*9880d681SAndroid Build Coastguard Worker // Provide an accessor method to use them in range-based patterns.
211*9880d681SAndroid Build Coastguard Worker template <class T>
depth_first(const T & G)212*9880d681SAndroid Build Coastguard Worker iterator_range<df_iterator<T>> depth_first(const T& G) {
213*9880d681SAndroid Build Coastguard Worker   return make_range(df_begin(G), df_end(G));
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker // Provide global definitions of external depth first iterators...
217*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
218*9880d681SAndroid Build Coastguard Worker struct df_ext_iterator : public df_iterator<T, SetTy, true> {
df_ext_iteratordf_ext_iterator219*9880d681SAndroid Build Coastguard Worker   df_ext_iterator(const df_iterator<T, SetTy, true> &V)
220*9880d681SAndroid Build Coastguard Worker     : df_iterator<T, SetTy, true>(V) {}
221*9880d681SAndroid Build Coastguard Worker };
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy>
df_ext_begin(const T & G,SetTy & S)224*9880d681SAndroid Build Coastguard Worker df_ext_iterator<T, SetTy> df_ext_begin(const T& G, SetTy &S) {
225*9880d681SAndroid Build Coastguard Worker   return df_ext_iterator<T, SetTy>::begin(G, S);
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy>
df_ext_end(const T & G,SetTy & S)229*9880d681SAndroid Build Coastguard Worker df_ext_iterator<T, SetTy> df_ext_end(const T& G, SetTy &S) {
230*9880d681SAndroid Build Coastguard Worker   return df_ext_iterator<T, SetTy>::end(G, S);
231*9880d681SAndroid Build Coastguard Worker }
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy>
depth_first_ext(const T & G,SetTy & S)234*9880d681SAndroid Build Coastguard Worker iterator_range<df_ext_iterator<T, SetTy>> depth_first_ext(const T& G,
235*9880d681SAndroid Build Coastguard Worker                                                           SetTy &S) {
236*9880d681SAndroid Build Coastguard Worker   return make_range(df_ext_begin(G, S), df_ext_end(G, S));
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker 
239*9880d681SAndroid Build Coastguard Worker // Provide global definitions of inverse depth first iterators...
240*9880d681SAndroid Build Coastguard Worker template <class T,
241*9880d681SAndroid Build Coastguard Worker   class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
242*9880d681SAndroid Build Coastguard Worker           bool External = false>
243*9880d681SAndroid Build Coastguard Worker struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
idf_iteratoridf_iterator244*9880d681SAndroid Build Coastguard Worker   idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
245*9880d681SAndroid Build Coastguard Worker     : df_iterator<Inverse<T>, SetTy, External>(V) {}
246*9880d681SAndroid Build Coastguard Worker };
247*9880d681SAndroid Build Coastguard Worker 
248*9880d681SAndroid Build Coastguard Worker template <class T>
idf_begin(const T & G)249*9880d681SAndroid Build Coastguard Worker idf_iterator<T> idf_begin(const T& G) {
250*9880d681SAndroid Build Coastguard Worker   return idf_iterator<T>::begin(Inverse<T>(G));
251*9880d681SAndroid Build Coastguard Worker }
252*9880d681SAndroid Build Coastguard Worker 
253*9880d681SAndroid Build Coastguard Worker template <class T>
idf_end(const T & G)254*9880d681SAndroid Build Coastguard Worker idf_iterator<T> idf_end(const T& G){
255*9880d681SAndroid Build Coastguard Worker   return idf_iterator<T>::end(Inverse<T>(G));
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker 
258*9880d681SAndroid Build Coastguard Worker // Provide an accessor method to use them in range-based patterns.
259*9880d681SAndroid Build Coastguard Worker template <class T>
inverse_depth_first(const T & G)260*9880d681SAndroid Build Coastguard Worker iterator_range<idf_iterator<T>> inverse_depth_first(const T& G) {
261*9880d681SAndroid Build Coastguard Worker   return make_range(idf_begin(G), idf_end(G));
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker // Provide global definitions of external inverse depth first iterators...
265*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
266*9880d681SAndroid Build Coastguard Worker struct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
idf_ext_iteratoridf_ext_iterator267*9880d681SAndroid Build Coastguard Worker   idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
268*9880d681SAndroid Build Coastguard Worker     : idf_iterator<T, SetTy, true>(V) {}
idf_ext_iteratoridf_ext_iterator269*9880d681SAndroid Build Coastguard Worker   idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
270*9880d681SAndroid Build Coastguard Worker     : idf_iterator<T, SetTy, true>(V) {}
271*9880d681SAndroid Build Coastguard Worker };
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy>
idf_ext_begin(const T & G,SetTy & S)274*9880d681SAndroid Build Coastguard Worker idf_ext_iterator<T, SetTy> idf_ext_begin(const T& G, SetTy &S) {
275*9880d681SAndroid Build Coastguard Worker   return idf_ext_iterator<T, SetTy>::begin(Inverse<T>(G), S);
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker 
278*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy>
idf_ext_end(const T & G,SetTy & S)279*9880d681SAndroid Build Coastguard Worker idf_ext_iterator<T, SetTy> idf_ext_end(const T& G, SetTy &S) {
280*9880d681SAndroid Build Coastguard Worker   return idf_ext_iterator<T, SetTy>::end(Inverse<T>(G), S);
281*9880d681SAndroid Build Coastguard Worker }
282*9880d681SAndroid Build Coastguard Worker 
283*9880d681SAndroid Build Coastguard Worker template <class T, class SetTy>
inverse_depth_first_ext(const T & G,SetTy & S)284*9880d681SAndroid Build Coastguard Worker iterator_range<idf_ext_iterator<T, SetTy>> inverse_depth_first_ext(const T& G,
285*9880d681SAndroid Build Coastguard Worker                                                                    SetTy &S) {
286*9880d681SAndroid Build Coastguard Worker   return make_range(idf_ext_begin(G, S), idf_ext_end(G, S));
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker 
289*9880d681SAndroid Build Coastguard Worker } // End llvm namespace
290*9880d681SAndroid Build Coastguard Worker 
291*9880d681SAndroid Build Coastguard Worker #endif
292