aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Callahan <dcallahan@fb.com>2016-10-05 21:36:16 +0000
committerDavid Callahan <dcallahan@fb.com>2016-10-05 21:36:16 +0000
commit8be61a8c7e1f0d0c7ac30e1457a36af5a01fcaf7 (patch)
treec2cb50587ef02f1e416ae6aea50e29fac1f5b72b
parent5ea3570b6a160837d0c1456c2efc7fbe72af7591 (diff)
Modify df_iterator to support post-order actions
Summary: This makes a change to the state used to maintain visited information for depth first iterator. We know assume a method "completed(...)" which is called after all children of a node have been visited. In all existing cases, this method does nothing so this patch has no functional changes. It will however allow a client to distinguish back from cross edges in a DFS tree. Reviewers: nadav, mehdi_amini, dberlin Subscribers: MatzeB, mzolotukhin, twoh, freik, llvm-commits Differential Revision: https://reviews.llvm.org/D25191 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283391 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h27
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h4
-rw-r--r--include/llvm/Analysis/RegionInfo.h14
-rw-r--r--include/llvm/Analysis/RegionIterator.h6
-rw-r--r--include/llvm/CodeGen/MachineRegionInfo.h4
-rw-r--r--include/llvm/IR/Dominators.h2
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp2
-rw-r--r--lib/CodeGen/LiveVariables.cpp2
-rw-r--r--lib/CodeGen/MachineVerifier.cpp4
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp2
-rw-r--r--lib/CodeGen/UnreachableBlockElim.cpp4
-rw-r--r--lib/Target/X86/X86FloatingPoint.cpp2
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp2
-rw-r--r--unittests/ADT/DepthFirstIteratorTest.cpp2
14 files changed, 48 insertions, 29 deletions
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index c49ced3da32..a192b12ed31 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -58,10 +58,25 @@ public:
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
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>,
@@ -89,10 +104,8 @@ private:
}
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) {
@@ -119,7 +132,8 @@ private:
return;
}
}
-
+ this->Visited.completed(Node);
+
// Oops, ran out of successors... go up a level on the stack.
VisitStack.pop_back();
} 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...
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)
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 6635860139b..47ab87e9c52 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -228,9 +228,9 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const {
// 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);
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index bb0e800ab17..6d901f4a732 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -626,12 +626,14 @@ public:
/// 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();
diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h
index 80b752352e9..de2f3bf3f12 100644
--- a/include/llvm/Analysis/RegionIterator.h
+++ b/include/llvm/Analysis/RegionIterator.h
@@ -294,7 +294,7 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) {
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) { \
@@ -316,7 +316,7 @@ RegionGraphTraits(const Region, const RegionNode);
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;
@@ -333,7 +333,7 @@ template <> struct GraphTraits<RegionInfo*>
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;
diff --git a/include/llvm/CodeGen/MachineRegionInfo.h b/include/llvm/CodeGen/MachineRegionInfo.h
index 13e86dd6cbf..21f847c7e5b 100644
--- a/include/llvm/CodeGen/MachineRegionInfo.h
+++ b/include/llvm/CodeGen/MachineRegionInfo.h
@@ -142,7 +142,7 @@ RegionGraphTraits(const MachineRegion, const MachineRegionNode);
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;
@@ -159,7 +159,7 @@ template <> struct GraphTraits<MachineRegionInfo*>
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;
diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h
index 957ac12d10c..37c8091e63c 100644
--- a/include/llvm/IR/Dominators.h
+++ b/include/llvm/IR/Dominators.h
@@ -157,7 +157,7 @@ public:
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(); }
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 4195f007d43..c43e8349ff9 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -599,7 +599,7 @@ void LiveIntervals::pruneValue(LiveRange &LR, SlotIndex Kill,
// 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();
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index dd87216f5e6..269b990a314 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -643,7 +643,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
// 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);
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp
index 33bf9abc8ef..6175313e391 100644
--- a/lib/CodeGen/MachineVerifier.cpp
+++ b/lib/CodeGen/MachineVerifier.cpp
@@ -2014,11 +2014,11 @@ void MachineVerifier::verifyStackFrame() {
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;
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 6ddf9537a71..8013c115726 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -1008,7 +1008,7 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
// 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);
diff --git a/lib/CodeGen/UnreachableBlockElim.cpp b/lib/CodeGen/UnreachableBlockElim.cpp
index 501e01c45a8..c2db56a7657 100644
--- a/lib/CodeGen/UnreachableBlockElim.cpp
+++ b/lib/CodeGen/UnreachableBlockElim.cpp
@@ -40,7 +40,7 @@
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))
@@ -130,7 +130,7 @@ void UnreachableMachineBlockElim::getAnalysisUsage(AnalysisUsage &AU) const {
}
bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
- SmallPtrSet<MachineBasicBlock*, 8> Reachable;
+ df_iterator_default_set<MachineBasicBlock*> Reachable;
bool ModifiedPHI = false;
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp
index f0e89590d30..3daa56b4db2 100644
--- a/lib/Target/X86/X86FloatingPoint.cpp
+++ b/lib/Target/X86/X86FloatingPoint.cpp
@@ -326,7 +326,7 @@ bool FPS::runOnMachineFunction(MachineFunction &MF) {
// 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;
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
index 0716a3a9cbe..72731151df9 100644
--- a/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -600,7 +600,7 @@ static bool isSafeToPromoteArgument(Argument *Arg, bool isByValOrInAlloca,
// 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
diff --git a/unittests/ADT/DepthFirstIteratorTest.cpp b/unittests/ADT/DepthFirstIteratorTest.cpp
index 64abe2c1556..463d6928bd5 100644
--- a/unittests/ADT/DepthFirstIteratorTest.cpp
+++ b/unittests/ADT/DepthFirstIteratorTest.cpp
@@ -27,6 +27,8 @@ template <typename T> struct CountedSet {
}
size_t count(const T &Item) const { return S.count(Item); }
+
+ void completed(T) { }
};
template <typename T> class df_iterator_storage<CountedSet<T>, true> {