[llvm] 50f0ee8 - [PostOrderIterator] Store end iterator (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon May 22 06:50:23 PDT 2023


Author: Nikita Popov
Date: 2023-05-22T15:50:12+02:00
New Revision: 50f0ee8fbfc1f597ae7d2d49e0996c4338e5652f

URL: https://github.com/llvm/llvm-project/commit/50f0ee8fbfc1f597ae7d2d49e0996c4338e5652f
DIFF: https://github.com/llvm/llvm-project/commit/50f0ee8fbfc1f597ae7d2d49e0996c4338e5652f.diff

LOG: [PostOrderIterator] Store end iterator (NFC)

Store the end iterator on the VisitStack, instead of recomputing
it every time, as doing so is not free.

Added: 
    

Modified: 
    llvm/include/llvm/ADT/PostOrderIterator.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/PostOrderIterator.h b/llvm/include/llvm/ADT/PostOrderIterator.h
index a80eed78c94d1..abc510714f345 100644
--- a/llvm/include/llvm/ADT/PostOrderIterator.h
+++ b/llvm/include/llvm/ADT/PostOrderIterator.h
@@ -106,13 +106,14 @@ class po_iterator : public po_iterator_storage<SetType, ExtStorage> {
   using NodeRef = typename GT::NodeRef;
   using ChildItTy = typename GT::ChildIteratorType;
 
-  // VisitStack - Used to maintain the ordering.  Top = current block
-  // First element is basic block pointer, second is the 'next child' to visit
-  SmallVector<std::pair<NodeRef, ChildItTy>, 8> VisitStack;
+  /// Used to maintain the ordering.
+  /// First element is basic block pointer, second is iterator for the next
+  /// child to visit, third is the end iterator.
+  SmallVector<std::tuple<NodeRef, ChildItTy, ChildItTy>, 8> VisitStack;
 
   po_iterator(NodeRef BB) {
     this->insertEdge(std::optional<NodeRef>(), BB);
-    VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+    VisitStack.emplace_back(BB, GT::child_begin(BB), GT::child_end(BB));
     traverseChild();
   }
 
@@ -121,7 +122,7 @@ class po_iterator : public po_iterator_storage<SetType, ExtStorage> {
   po_iterator(NodeRef BB, SetType &S)
       : po_iterator_storage<SetType, ExtStorage>(S) {
     if (this->insertEdge(std::optional<NodeRef>(), BB)) {
-      VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+      VisitStack.emplace_back(BB, GT::child_begin(BB), GT::child_end(BB));
       traverseChild();
     }
   }
@@ -131,12 +132,14 @@ class po_iterator : public po_iterator_storage<SetType, ExtStorage> {
   } // End is when stack is empty.
 
   void traverseChild() {
-    while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
-      NodeRef BB = *VisitStack.back().second++;
-      if (this->insertEdge(std::optional<NodeRef>(VisitStack.back().first),
-                           BB)) {
+    while (true) {
+      auto &[ParentBB, It, End] = VisitStack.back();
+      if (It == End)
+        break;
+      NodeRef BB = *It++;
+      if (this->insertEdge(std::optional<NodeRef>(ParentBB), BB)) {
         // If the block is not visited...
-        VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+        VisitStack.emplace_back(BB, GT::child_begin(BB), GT::child_end(BB));
       }
     }
   }
@@ -158,7 +161,7 @@ class po_iterator : public po_iterator_storage<SetType, ExtStorage> {
   }
   bool operator!=(const po_iterator &x) const { return !(*this == x); }
 
-  const NodeRef &operator*() const { return VisitStack.back().first; }
+  const NodeRef &operator*() const { return std::get<0>(VisitStack.back()); }
 
   // This is a nonstandard operator-> that dereferences the pointer an extra
   // time... so that you can actually call methods ON the BasicBlock, because
@@ -167,7 +170,7 @@ class po_iterator : public po_iterator_storage<SetType, ExtStorage> {
   NodeRef operator->() const { return **this; }
 
   po_iterator &operator++() { // Preincrement
-    this->finishPostorder(VisitStack.back().first);
+    this->finishPostorder(std::get<0>(VisitStack.back()));
     VisitStack.pop_back();
     if (!VisitStack.empty())
       traverseChild();


        


More information about the llvm-commits mailing list