diff options
author | David Callahan <dcallahan@fb.com> | 2016-10-05 21:36:16 +0000 |
---|---|---|
committer | David Callahan <dcallahan@fb.com> | 2016-10-05 21:36:16 +0000 |
commit | 8be61a8c7e1f0d0c7ac30e1457a36af5a01fcaf7 (patch) | |
tree | c2cb50587ef02f1e416ae6aea50e29fac1f5b72b | |
parent | 5ea3570b6a160837d0c1456c2efc7fbe72af7591 (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.h | 27 | ||||
-rw-r--r-- | include/llvm/Analysis/LoopInfoImpl.h | 4 | ||||
-rw-r--r-- | include/llvm/Analysis/RegionInfo.h | 14 | ||||
-rw-r--r-- | include/llvm/Analysis/RegionIterator.h | 6 | ||||
-rw-r--r-- | include/llvm/CodeGen/MachineRegionInfo.h | 4 | ||||
-rw-r--r-- | include/llvm/IR/Dominators.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/LiveVariables.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/MachineVerifier.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/PrologEpilogInserter.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/UnreachableBlockElim.cpp | 4 | ||||
-rw-r--r-- | lib/Target/X86/X86FloatingPoint.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/IPO/ArgumentPromotion.cpp | 2 | ||||
-rw-r--r-- | unittests/ADT/DepthFirstIteratorTest.cpp | 2 |
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> { |