[llvm] [CycleInfo] Store blocks using Euler tour representation (PR #208614)

Sameer Sahasrabuddhe via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 12 21:18:37 PDT 2026


================
@@ -467,58 +538,56 @@ void GenericCycleInfoCompute<ContextT>::updateDepth(CycleT *SubTree) {
 /// Fills BlockDFSInfo with start/end counters and BlockPreorder.
 template <typename ContextT>
 void GenericCycleInfoCompute<ContextT>::dfs(FunctionT *F, BlockT *EntryBlock) {
-  SmallVector<unsigned, 8> DFSTreeStack;
-  SmallVector<BlockT *, 8> TraverseStack;
+  BlockDFSInfo.resize(GraphTraits<FunctionT *>::getMaxNumber(F));
+
+  // Successors are visited in reverse order to match the legacy
+  // single-LIFO-stack traversal, keeping cycle identification and block order
+  // unchanged.
+  using SuccIt = decltype(successors(EntryBlock).begin());
+  struct Frame {
+    BlockT *Block;
+    std::reverse_iterator<SuccIt> Cur, End;
+  };
+  SmallVector<Frame, 8> Stack;
   unsigned Counter = 0;
-  TraverseStack.emplace_back(EntryBlock);
 
-  BlockDFSInfo.resize(GraphTraits<FunctionT *>::getMaxNumber(F));
-  do {
-    BlockT *Block = TraverseStack.back();
+  auto open = [&](BlockT *Block) {
+    getOrInsertDFSInfo(Block).Start = ++Counter;
+    BlockPreorder.push_back(Block);
     LLVM_DEBUG(errs() << "DFS visiting block: " << Info.Context.print(Block)
-                      << "\n");
-    DFSInfo &Info = getOrInsertDFSInfo(Block);
-    if (Info.Start == 0) {
-      Info.Start = ++Counter;
-
-      // We're visiting the block for the first time. Open its DFSInfo, add
-      // successors to the traversal stack, and remember the traversal stack
-      // depth at which the block was opened, so that we can correctly record
-      // its end time.
-      LLVM_DEBUG(errs() << "  first encountered at depth "
-                        << TraverseStack.size() << "\n");
-
-      DFSTreeStack.emplace_back(TraverseStack.size());
-      llvm::append_range(TraverseStack, successors(Block));
-
-      BlockPreorder.push_back(Block);
-      LLVM_DEBUG(errs() << "  preorder number: " << Counter << "\n");
-    } else {
-      assert(!DFSTreeStack.empty());
-      if (DFSTreeStack.back() == TraverseStack.size()) {
-        LLVM_DEBUG(errs() << "  ended at " << Counter << "\n");
-        Info.End = Counter;
-        DFSTreeStack.pop_back();
-      } else {
-        LLVM_DEBUG(errs() << "  already done\n");
+                      << ", preorder number: " << Counter << "\n");
+    auto Succs = successors(Block);
+    Stack.push_back({Block, std::make_reverse_iterator(Succs.end()),
+                     std::make_reverse_iterator(Succs.begin())});
+  };
+
+  open(EntryBlock);
+  while (!Stack.empty()) {
+    Frame &Top = Stack.back();
+    BlockT *Next = nullptr;
+    while (Top.Cur != Top.End) {
+      BlockT *Succ = *Top.Cur++;
+      if (getOrInsertDFSInfo(Succ).Start == 0) {
+        Next = Succ;
+        break;
       }
-      TraverseStack.pop_back();
     }
-  } while (!TraverseStack.empty());
-  assert(DFSTreeStack.empty());
-
-  LLVM_DEBUG(
-    errs() << "Preorder:\n";
-    for (int i = 0, e = BlockPreorder.size(); i != e; ++i) {
----------------
ssahasra wrote:

While removing the old code, please find similar points to add step-by-step LLVM_DEBUG output. This very helpful for anyone who just want to trace how their CycleInfo was built.

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


More information about the llvm-commits mailing list