[llvm] [CFG][NFC] Use block numbers for FindFunctionBackedges (PR #186668)

via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 15 06:27:26 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Alexis Engelke (aengelke)

<details>
<summary>Changes</summary>

The function traverses all basic blocks, so instead of two SmallPtrSets use a single vector indexed by block number.

---
Full diff: https://github.com/llvm/llvm-project/pull/186668.diff


1 Files Affected:

- (modified) llvm/lib/Analysis/CFG.cpp (+34-25) 


``````````diff
diff --git a/llvm/lib/Analysis/CFG.cpp b/llvm/lib/Analysis/CFG.cpp
index 1676d6b6f592e..da74691a6e6a5 100644
--- a/llvm/lib/Analysis/CFG.cpp
+++ b/llvm/lib/Analysis/CFG.cpp
@@ -35,40 +35,49 @@ static cl::opt<unsigned> DefaultMaxBBsToExplore(
 void llvm::FindFunctionBackedges(const Function &F,
      SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result) {
   const BasicBlock *BB = &F.getEntryBlock();
-  if (succ_empty(BB))
-    return;
 
-  SmallPtrSet<const BasicBlock*, 8> Visited;
-  SmallVector<std::pair<const BasicBlock *, const_succ_iterator>, 8> VisitStack;
-  SmallPtrSet<const BasicBlock*, 8> InStack;
+  // In the DFS traversal, we maintain three states: unvisited, visited in the
+  // past, and visited and currently in the DFS stack. If we have an edge to a
+  // block in the stack, we have found a backedge.
+  enum VisitState : uint8_t { Unvisited = 0, Visited = 1, InStack = 2 };
+  SmallVector<VisitState> BlockState(F.getMaxBlockNumber(), Unvisited);
+  struct StackEntry {
+    const BasicBlock *BB;
+    const_succ_iterator SuccIt;
+    const_succ_iterator SuccEnd;
+
+    StackEntry(const BasicBlock *BB)
+        : BB(BB), SuccIt(nullptr), SuccEnd(nullptr) {
+      auto Succs = successors(BB);
+      SuccIt = Succs.begin();
+      SuccEnd = Succs.end();
+    }
+  };
+  SmallVector<StackEntry, 8> VisitStack;
 
-  Visited.insert(BB);
-  VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
-  InStack.insert(BB);
+  BlockState[BB->getNumber()] = InStack;
+  VisitStack.emplace_back(BB);
   do {
-    std::pair<const BasicBlock *, const_succ_iterator> &Top = VisitStack.back();
-    const BasicBlock *ParentBB = Top.first;
-    const_succ_iterator &I = Top.second;
-
+    StackEntry &Top = VisitStack.back();
     bool FoundNew = false;
-    while (I != succ_end(ParentBB)) {
-      BB = *I++;
-      if (Visited.insert(BB).second) {
+    while (Top.SuccIt != Top.SuccEnd) {
+      BB = *Top.SuccIt++;
+      if (BlockState[BB->getNumber()] == Unvisited) {
+        // Unvisited successor => go down one level.
+        BlockState[BB->getNumber()] = InStack;
+        VisitStack.emplace_back(BB);
         FoundNew = true;
         break;
       }
-      // Successor is in VisitStack, it's a back edge.
-      if (InStack.count(BB))
-        Result.push_back(std::make_pair(ParentBB, BB));
+      // Successor in VisitStack => backedge.
+      if (BlockState[BB->getNumber()] == InStack)
+        Result.emplace_back(Top.BB, BB);
     }
 
-    if (FoundNew) {
-      // Go down one level if there is a unvisited successor.
-      InStack.insert(BB);
-      VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
-    } else {
-      // Go up one level.
-      InStack.erase(VisitStack.pop_back_val().first);
+    // Go up one level.
+    if (!FoundNew) {
+      BlockState[Top.BB->getNumber()] = Visited;
+      VisitStack.pop_back();
     }
   } while (!VisitStack.empty());
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/186668


More information about the llvm-commits mailing list