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.\13
+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
template <class GraphT,
class SetType =
- llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeRef, 8>,
+ df_iterator_default_set<typename GraphTraits<GraphT>::NodeRef>,
bool ExtStorage = false, class GT = GraphTraits<GraphT>>
class df_iterator
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
}
inline df_iterator(NodeRef Node, SetType &S)
: df_iterator_storage<SetType, ExtStorage>(S) {
- if (!S.count(Node)) {
+ if (this->Visited.insert(Node).second)
VisitStack.push_back(StackElement(Node, None));
- this->Visited.insert(Node);
- }
}
inline df_iterator(SetType &S)
: df_iterator_storage<SetType, ExtStorage>(S) {
return;
}
}
-
+ this->Visited.completed(Node);
+
// Oops, ran out of successors... go up a level on the stack.
VisitStack.pop_back();
} while (!VisitStack.empty());
// Provide global definitions of inverse depth first iterators...
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>
struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
// Setup for using a depth-first iterator to visit every block in the loop.
SmallVector<BlockT*, 8> ExitBBs;
getExitBlocks(ExitBBs);
- llvm::SmallPtrSet<BlockT*, 8> VisitSet;
+ df_iterator_default_set<BlockT*> VisitSet;
VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
- df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> >
+ df_ext_iterator<BlockT*, df_iterator_default_set<BlockT*>>
BI = df_ext_begin(getHeader(), VisitSet),
BE = df_ext_end(getHeader(), VisitSet);
/// are direct children of this Region. It does not iterate over any
/// RegionNodes that are also element of a subregion of this Region.
//@{
- typedef df_iterator<RegionNodeT *, SmallPtrSet<RegionNodeT *, 8>, false,
- GraphTraits<RegionNodeT *>> element_iterator;
-
- typedef df_iterator<const RegionNodeT *, SmallPtrSet<const RegionNodeT *, 8>,
- false,
- GraphTraits<const RegionNodeT *>> const_element_iterator;
+ typedef df_iterator<RegionNodeT *, df_iterator_default_set<RegionNodeT *>,
+ false, GraphTraits<RegionNodeT *>>
+ element_iterator;
+
+ typedef df_iterator<const RegionNodeT *,
+ df_iterator_default_set<const RegionNodeT *>, false,
+ GraphTraits<const RegionNodeT *>>
+ const_element_iterator;
element_iterator element_begin();
element_iterator element_end();
template <> \
struct GraphTraits<FlatIt<RegionT *>> \
: public GraphTraits<FlatIt<NodeT *>> { \
- typedef df_iterator<NodeRef, SmallPtrSet<NodeRef, 8>, false, \
+ typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, \
GraphTraits<FlatIt<NodeRef>>> \
nodes_iterator; \
static NodeRef getEntryNode(RegionT *R) { \
template <> struct GraphTraits<RegionInfo*>
: public GraphTraits<FlatIt<RegionNode*> > {
- typedef df_iterator<NodeRef, SmallPtrSet<NodeRef, 8>, false,
+ typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
GraphTraits<FlatIt<NodeRef>>>
nodes_iterator;
template <> struct GraphTraits<RegionInfoPass*>
: public GraphTraits<RegionInfo *> {
- typedef df_iterator<NodeRef, SmallPtrSet<NodeRef, 8>, false,
+ typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
GraphTraits<FlatIt<NodeRef>>>
nodes_iterator;
template <> struct GraphTraits<MachineRegionInfo*>
: public GraphTraits<FlatIt<MachineRegionNode*> > {
- typedef df_iterator<NodeRef, SmallPtrSet<NodeRef, 8>, false,
+ typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
GraphTraits<FlatIt<NodeRef>>>
nodes_iterator;
template <> struct GraphTraits<MachineRegionInfoPass*>
: public GraphTraits<MachineRegionInfo *> {
- typedef df_iterator<NodeRef, SmallPtrSet<NodeRef, 8>, false,
+ typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
GraphTraits<FlatIt<NodeRef>>>
nodes_iterator;
template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase {
typedef Node *NodeRef;
typedef ChildIterator ChildIteratorType;
- typedef df_iterator<Node *, SmallPtrSet<NodeRef, 8>> nodes_iterator;
+ typedef df_iterator<Node *, df_iterator_default_set<Node*>> nodes_iterator;
static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
// Find all blocks that are reachable from KillMBB without leaving VNI's live
// range. It is possible that KillMBB itself is reachable, so start a DFS
// from each successor.
- typedef SmallPtrSet<MachineBasicBlock*, 9> VisitedTy;
+ typedef df_iterator_default_set<MachineBasicBlock*,9> VisitedTy;
VisitedTy Visited;
for (MachineBasicBlock::succ_iterator
SuccI = KillMBB->succ_begin(), SuccE = KillMBB->succ_end();
// register before its uses due to dominance properties of SSA (except for PHI
// nodes, which are treated as a special case).
MachineBasicBlock *Entry = &MF->front();
- SmallPtrSet<MachineBasicBlock*,16> Visited;
+ df_iterator_default_set<MachineBasicBlock*,16> Visited;
for (MachineBasicBlock *MBB : depth_first_ext(Entry, Visited)) {
runOnBlock(MBB, NumRegs);
SmallVector<StackStateOfBB, 8> SPState;
SPState.resize(MF->getNumBlockIDs());
- SmallPtrSet<const MachineBasicBlock*, 8> Reachable;
+ df_iterator_default_set<const MachineBasicBlock*> Reachable;
// Visit the MBBs in DFS order.
for (df_ext_iterator<const MachineFunction*,
- SmallPtrSet<const MachineBasicBlock*, 8> >
+ df_iterator_default_set<const MachineBasicBlock*> >
DFI = df_ext_begin(MF, Reachable), DFE = df_ext_end(MF, Reachable);
DFI != DFE; ++DFI) {
const MachineBasicBlock *MBB = *DFI;
// Store SPAdj at exit of a basic block.
SmallVector<int, 8> SPState;
SPState.resize(Fn.getNumBlockIDs());
- SmallPtrSet<MachineBasicBlock*, 8> Reachable;
+ df_iterator_default_set<MachineBasicBlock*> Reachable;
// Iterate over the reachable blocks in DFS order.
for (auto DFI = df_ext_begin(&Fn, Reachable), DFE = df_ext_end(&Fn, Reachable);
using namespace llvm;
static bool eliminateUnreachableBlock(Function &F) {
- SmallPtrSet<BasicBlock*, 8> Reachable;
+ df_iterator_default_set<BasicBlock*> Reachable;
// Mark all reachable blocks.
for (BasicBlock *BB : depth_first_ext(&F, Reachable))
}
bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
- SmallPtrSet<MachineBasicBlock*, 8> Reachable;
+ df_iterator_default_set<MachineBasicBlock*> Reachable;
bool ModifiedPHI = false;
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
// Process the function in depth first order so that we process at least one
// of the predecessors for every reachable block in the function.
- SmallPtrSet<MachineBasicBlock*, 8> Processed;
+ df_iterator_default_set<MachineBasicBlock*> Processed;
MachineBasicBlock *Entry = &MF.front();
bool Changed = false;
// Because there could be several/many load instructions, remember which
// blocks we know to be transparent to the load.
- SmallPtrSet<BasicBlock*, 16> TranspBlocks;
+ df_iterator_default_set<BasicBlock*, 16> TranspBlocks;
for (LoadInst *Load : Loads) {
// Check to see if the load is invalidated from the start of the block to
}
size_t count(const T &Item) const { return S.count(Item); }
+
+ void completed(T) { }
};
template <typename T> class df_iterator_storage<CountedSet<T>, true> {