[llvm] [Support][NFC] Use single predecessor array in DomTreeConstr (PR #207535)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 4 12:37:49 PDT 2026


https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/207535

Storing many small vectors of predecessors is bad for performance, as
each of these has to be non-trivially initialized when growing the
NodeInfos vector. Therefore, store all predecessors in a separate
vector, in which predecessors form a linked list.


>From 608981c160d2bf00d1e3dff8743da519cb76bdcb Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Sat, 4 Jul 2026 19:37:11 +0000
Subject: [PATCH] [spr] initial version

Created using spr 1.3.8-wip
---
 .../llvm/Support/GenericDomTreeConstruction.h   | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
index 869087cda219a..dcfeaae6fab98 100644
--- a/llvm/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
@@ -66,7 +66,7 @@ template <typename DomTreeT> struct SemiNCAInfo {
     unsigned Semi = 0;
     unsigned Label = 0;
     NodePtr IDom = nullptr;
-    SmallVector<unsigned, 4> ReverseChildren;
+    unsigned ReverseChildrenStart = 0; ///< Index in ReverseChildren vector.
   };
 
   // Number to node mapping is 1-based. Initialize the mapping to start with
@@ -78,6 +78,10 @@ template <typename DomTreeT> struct SemiNCAInfo {
                      DenseMap<NodePtr, InfoRec>>
       NodeInfos;
 
+  /// Reverse children of nodes; pairs of (DFSNum (predecessor), next-or-zero);
+  /// forms a linked list in this vector; first entry is sentinel.
+  SmallVector<std::pair<unsigned, unsigned>> ReverseChildren = {{0, 0}};
+
   using UpdateT = typename DomTreeT::UpdateType;
   using UpdateKind = typename DomTreeT::UpdateKind;
   struct BatchUpdateInfo {
@@ -209,7 +213,8 @@ template <typename DomTreeT> struct SemiNCAInfo {
     while (!WorkList.empty()) {
       const auto [BB, ParentNum] = WorkList.pop_back_val();
       auto &BBInfo = getNodeInfo(BB);
-      BBInfo.ReverseChildren.push_back(ParentNum);
+      ReverseChildren.emplace_back(ParentNum, BBInfo.ReverseChildrenStart);
+      BBInfo.ReverseChildrenStart = ReverseChildren.size() - 1;
 
       // Visited nodes always have positive DFS numbers.
       if (BBInfo.DFSNum != 0)
@@ -314,8 +319,12 @@ template <typename DomTreeT> struct SemiNCAInfo {
 
       // Initialize the semi dominator to point to the parent node.
       WInfo.Semi = WInfo.Parent;
-      for (unsigned N : WInfo.ReverseChildren) {
-        unsigned SemiU = NumToInfo[eval(N, i + 1, EvalStack, NumToInfo)]->Semi;
+      unsigned RCIdx = WInfo.ReverseChildrenStart;
+      while (RCIdx != 0) {
+        const auto &Entry = ReverseChildren[RCIdx];
+        RCIdx = Entry.second;
+        unsigned SemiU =
+            NumToInfo[eval(Entry.first, i + 1, EvalStack, NumToInfo)]->Semi;
         if (SemiU < WInfo.Semi)
           WInfo.Semi = SemiU;
       }



More information about the llvm-commits mailing list