|
@@ -58,10 +58,25 @@ public:
|
|
SetType &Visited;
|
|
SetType &Visited;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+// The visited stated for the iteration is a simple set augmented with
|
|
|
|
+// one more method, completed, which is invoked when all children of a
|
|
|
|
+// node have been processed. It is intended to distinguish of back and
|
|
|
|
+// cross edges in the spanning tree but is not used in the common case.
|
|
|
|
+template <typename NodeRef, unsigned SmallSize=8>
|
|
|
|
+struct df_iterator_default_set : public llvm::SmallPtrSet<NodeRef, SmallSize> {
|
|
|
|
+ typedef llvm::SmallPtrSet<NodeRef, SmallSize> BaseSet;
|
|
|
|
+ typedef typename BaseSet::iterator iterator;
|
|
|
|
+ std::pair<iterator,bool> insert(NodeRef N) { return BaseSet::insert(N) ; }
|
|
|
|
+ template <typename IterT>
|
|
|
|
+ void insert(IterT Begin, IterT End) { BaseSet::insert(Begin,End); }
|
|
|
|
+
|
|
|
|
+ void completed(NodeRef) { }
|
|
|
|
+};
|
|
|
|
+
|
|
// Generic Depth First Iterator
|
|
// Generic Depth First Iterator
|
|
template <class GraphT,
|
|
template <class GraphT,
|
|
class SetType =
|
|
class SetType =
|
|
- llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeRef, 8>,
|
|
|
|
|
|
+ df_iterator_default_set<typename GraphTraits<GraphT>::NodeRef>,
|
|
bool ExtStorage = false, class GT = GraphTraits<GraphT>>
|
|
bool ExtStorage = false, class GT = GraphTraits<GraphT>>
|
|
class df_iterator
|
|
class df_iterator
|
|
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
|
|
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
|
|
@@ -89,10 +104,8 @@ private:
|
|
}
|
|
}
|
|
inline df_iterator(NodeRef Node, SetType &S)
|
|
inline df_iterator(NodeRef Node, SetType &S)
|
|
: df_iterator_storage<SetType, ExtStorage>(S) {
|
|
: df_iterator_storage<SetType, ExtStorage>(S) {
|
|
- if (!S.count(Node)) {
|
|
|
|
|
|
+ if (this->Visited.insert(Node).second)
|
|
VisitStack.push_back(StackElement(Node, None));
|
|
VisitStack.push_back(StackElement(Node, None));
|
|
- this->Visited.insert(Node);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
inline df_iterator(SetType &S)
|
|
inline df_iterator(SetType &S)
|
|
: df_iterator_storage<SetType, ExtStorage>(S) {
|
|
: df_iterator_storage<SetType, ExtStorage>(S) {
|
|
@@ -119,7 +132,8 @@ private:
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ this->Visited.completed(Node);
|
|
|
|
+
|
|
// Oops, ran out of successors... go up a level on the stack.
|
|
// Oops, ran out of successors... go up a level on the stack.
|
|
VisitStack.pop_back();
|
|
VisitStack.pop_back();
|
|
} while (!VisitStack.empty());
|
|
} while (!VisitStack.empty());
|
|
@@ -235,7 +249,8 @@ iterator_range<df_ext_iterator<T, SetTy>> depth_first_ext(const T& G,
|
|
|
|
|
|
// Provide global definitions of inverse depth first iterators...
|
|
// Provide global definitions of inverse depth first iterators...
|
|
template <class T,
|
|
template <class T,
|
|
- class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeRef, 8>,
|
|
|
|
|
|
+ class SetTy =
|
|
|
|
+ df_iterator_default_set<typename GraphTraits<T>::NodeRef>,
|
|
bool External = false>
|
|
bool External = false>
|
|
struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
|
|
struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
|
|
idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
|
|
idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
|