Add range iterators for post order and inverse post order. Use them
authorDaniel Berlin <dberlin@dberlin.org>
Wed, 15 Apr 2015 17:41:42 +0000 (17:41 +0000)
committerDaniel Berlin <dberlin@dberlin.org>
Wed, 15 Apr 2015 17:41:42 +0000 (17:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235026 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/PostOrderIterator.h
include/llvm/Analysis/LoopInfoImpl.h
include/llvm/Analysis/RegionInfoImpl.h
lib/Analysis/BranchProbabilityInfo.cpp
lib/CodeGen/EarlyIfConversion.cpp
lib/CodeGen/MachineTraceMetrics.cpp
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
lib/Transforms/Vectorize/SLPVectorizer.cpp

index fa337e9efb897b79c3a90705419f30ec619a847c..e7214e3049503ad6e952f3f5d59c846246674170 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/iterator_range.h"
 #include <set>
 #include <vector>
 
@@ -178,6 +179,10 @@ po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
 template <class T>
 po_iterator<T> po_end  (T G) { return po_iterator<T>::end(G); }
 
+template <class T> iterator_range<po_iterator<T>> post_order(T G) {
+  return iterator_range<po_iterator<T>>(po_begin(G), po_end(G));
+}
+
 // Provide global definitions of external postorder iterators...
 template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
 struct po_ext_iterator : public po_iterator<T, SetType, true> {
@@ -195,6 +200,12 @@ po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) {
   return po_ext_iterator<T, SetType>::end(G, S);
 }
 
+template <class T, class SetType>
+iterator_range<po_ext_iterator<T, SetType>> post_order_ext(T G, SetType &S) {
+  return iterator_range<po_ext_iterator<T, SetType>>(po_ext_begin(G, S),
+                                                     po_ext_end(G, S));
+}
+
 // Provide global definitions of inverse post order iterators...
 template <class T,
           class SetType = std::set<typename GraphTraits<T>::NodeType*>,
@@ -214,6 +225,11 @@ ipo_iterator<T> ipo_end(T G){
   return ipo_iterator<T>::end(G);
 }
 
+template <class T>
+iterator_range<ipo_iterator<T>> inverse_post_order(T G, bool Reverse = false) {
+  return iterator_range<ipo_iterator<T>>(ipo_begin(G, Reverse), ipo_end(G));
+}
+
 // Provide global definitions of external inverse postorder iterators...
 template <class T,
           class SetType = std::set<typename GraphTraits<T>::NodeType*> >
@@ -234,6 +250,13 @@ ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
   return ipo_ext_iterator<T, SetType>::end(G, S);
 }
 
+template <class T, class SetType>
+iterator_range<ipo_ext_iterator<T, SetType>>
+inverse_post_order_ext(T G, SetType &S) {
+  return iterator_range<ipo_ext_iterator<T, SetType>>(ipo_ext_begin(G, S),
+                                                      ipo_ext_end(G, S));
+}
+
 //===--------------------------------------------------------------------===//
 // Reverse Post Order CFG iterator code
 //===--------------------------------------------------------------------===//
index 7cc4a77c690435d3356b394f93b8324fad68d2e1..ded6e9292a7ef3d5951e3c19b4693594ac390d87 100644 (file)
@@ -498,10 +498,9 @@ Analyze(DominatorTreeBase<BlockT> &DomTree) {
 
   // Postorder traversal of the dominator tree.
   DomTreeNodeBase<BlockT>* DomRoot = DomTree.getRootNode();
-  for (po_iterator<DomTreeNodeBase<BlockT>*> DomIter = po_begin(DomRoot),
-         DomEnd = po_end(DomRoot); DomIter != DomEnd; ++DomIter) {
+  for (auto DomNode : post_order(DomRoot)) {
 
-    BlockT *Header = DomIter->getBlock();
+    BlockT *Header = DomNode->getBlock();
     SmallVector<BlockT *, 4> Backedges;
 
     // Check each predecessor of the potential loop header.
index b0dc26312aaa4ae41a8b29ab3f1dbb7f1f2c855e..1f48d046720c8421e0ed165f0bbc4d97d2168b76 100644 (file)
@@ -714,10 +714,8 @@ void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) {
   // regions from the bottom of the dominance tree.  If the small regions are
   // detected first, detection of bigger regions is faster, as we can jump
   // over the small regions.
-  for (po_iterator<DomTreeNodeT *> FI = po_begin(N), FE = po_end(N); FI != FE;
-       ++FI) {
-    findRegionsWithEntry(FI->getBlock(), ShortCut);
-  }
+  for (auto DomNode : post_order(N))
+    findRegionsWithEntry(DomNode->getBlock(), ShortCut);
 }
 
 template <class Tr>
index d7cee3afaf5975c7d0e508fd738f14f2ce273434..8799a710af0142f71072c20d330024130860bf03 100644 (file)
@@ -507,25 +507,23 @@ bool BranchProbabilityInfo::runOnFunction(Function &F) {
 
   // Walk the basic blocks in post-order so that we can build up state about
   // the successors of a block iteratively.
-  for (po_iterator<BasicBlock *> I = po_begin(&F.getEntryBlock()),
-                                 E = po_end(&F.getEntryBlock());
-       I != E; ++I) {
-    DEBUG(dbgs() << "Computing probabilities for " << I->getName() << "\n");
-    if (calcUnreachableHeuristics(*I))
+  for (auto BB : post_order(&F.getEntryBlock())) {
+    DEBUG(dbgs() << "Computing probabilities for " << BB->getName() << "\n");
+    if (calcUnreachableHeuristics(BB))
       continue;
-    if (calcMetadataWeights(*I))
+    if (calcMetadataWeights(BB))
       continue;
-    if (calcColdCallHeuristics(*I))
+    if (calcColdCallHeuristics(BB))
       continue;
-    if (calcLoopBranchHeuristics(*I))
+    if (calcLoopBranchHeuristics(BB))
       continue;
-    if (calcPointerHeuristics(*I))
+    if (calcPointerHeuristics(BB))
       continue;
-    if (calcZeroHeuristics(*I))
+    if (calcZeroHeuristics(BB))
       continue;
-    if (calcFloatingPointHeuristics(*I))
+    if (calcFloatingPointHeuristics(BB))
       continue;
-    calcInvokeHeuristics(*I);
+    calcInvokeHeuristics(BB);
   }
 
   PostDominatedByUnreachable.clear();
index 8f742713ccf99b679572f94de92cf79b5cc73d58..6cde4c249152f45e26ff39b8f71a110c9015db93 100644 (file)
@@ -797,9 +797,8 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
   // if-conversion in a single pass. The tryConvertIf() function may erase
   // blocks, but only blocks dominated by the head block. This makes it safe to
   // update the dominator tree while the post-order iterator is still active.
-  for (po_iterator<MachineDominatorTree*>
-       I = po_begin(DomTree), E = po_end(DomTree); I != E; ++I)
-    if (tryConvertIf(I->getBlock()))
+  for (auto DomNode : post_order(DomTree))
+    if (tryConvertIf(DomNode->getBlock()))
       Changed = true;
 
   return Changed;
index 8aacd1f31bb6f85717cb247d1ae3d334324e8752..5dc7c216994b288e40076e6ba92cbcf98625aad9 100644 (file)
@@ -463,13 +463,11 @@ void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
   // Run an upwards post-order search for the trace start.
   Bounds.Downward = false;
   Bounds.Visited.clear();
-  typedef ipo_ext_iterator<const MachineBasicBlock*, LoopBounds> UpwardPO;
-  for (UpwardPO I = ipo_ext_begin(MBB, Bounds), E = ipo_ext_end(MBB, Bounds);
-       I != E; ++I) {
+  for (auto I : inverse_post_order_ext(MBB, Bounds)) {
     DEBUG(dbgs() << "  pred for BB#" << I->getNumber() << ": ");
     TraceBlockInfo &TBI = BlockInfo[I->getNumber()];
     // All the predecessors have been visited, pick the preferred one.
-    TBI.Pred = pickTracePred(*I);
+    TBI.Pred = pickTracePred(I);
     DEBUG({
       if (TBI.Pred)
         dbgs() << "BB#" << TBI.Pred->getNumber() << '\n';
@@ -477,19 +475,17 @@ void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
         dbgs() << "null\n";
     });
     // The trace leading to I is now known, compute the depth resources.
-    computeDepthResources(*I);
+    computeDepthResources(I);
   }
 
   // Run a downwards post-order search for the trace end.
   Bounds.Downward = true;
   Bounds.Visited.clear();
-  typedef po_ext_iterator<const MachineBasicBlock*, LoopBounds> DownwardPO;
-  for (DownwardPO I = po_ext_begin(MBB, Bounds), E = po_ext_end(MBB, Bounds);
-       I != E; ++I) {
+  for (auto I : post_order_ext(MBB, Bounds)) {
     DEBUG(dbgs() << "  succ for BB#" << I->getNumber() << ": ");
     TraceBlockInfo &TBI = BlockInfo[I->getNumber()];
     // All the successors have been visited, pick the preferred one.
-    TBI.Succ = pickTraceSucc(*I);
+    TBI.Succ = pickTraceSucc(I);
     DEBUG({
       if (TBI.Succ)
         dbgs() << "BB#" << TBI.Succ->getNumber() << '\n';
@@ -497,7 +493,7 @@ void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
         dbgs() << "null\n";
     });
     // The trace leaving I is now known, compute the height resources.
-    computeHeightResources(*I);
+    computeHeightResources(I);
   }
 }
 
index 65a67265d7942a597b9e8466194349d3268ae0b6..4b8ae32e9a5ea5bdd52a120ce7ca1e5c7157f329 100644 (file)
@@ -652,8 +652,7 @@ void llvm::ComputeUsesVAFloatArgument(const CallInst &I,
   if (FT->isVarArg() && !MMI->usesVAFloatArgument()) {
     for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
       Type* T = I.getArgOperand(i)->getType();
-      for (po_iterator<Type*> i = po_begin(T), e = po_end(T);
-           i != e; ++i) {
+      for (auto i : post_order(T)) {
         if (i->isFloatingPointTy()) {
           MMI->setUsesVAFloatArgument(true);
           return;
index 5eae4e278c57cbde73fbe3065ce8d8c7bd996a0a..7267f58d1c9ba9fc9903d08f5d356afb1e130299 100644 (file)
@@ -3101,9 +3101,7 @@ struct SLPVectorizer : public FunctionPass {
     // delete instructions.
 
     // Scan the blocks in the function in post order.
-    for (po_iterator<BasicBlock*> it = po_begin(&F.getEntryBlock()),
-         e = po_end(&F.getEntryBlock()); it != e; ++it) {
-      BasicBlock *BB = *it;
+    for (auto BB : post_order(&F.getEntryBlock())) {
       // Vectorize trees that end at stores.
       if (unsigned count = collectStores(BB, R)) {
         (void)count;