[llvm] [DomTree] Store immediate dominator as DFS number. NFC (PR #215059)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 8 23:22:02 PDT 2026


https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/215059

Replace the local variable `IDoms` and the pointer `InfoRec::IDom` with
a DFS number member.

Since `attachNewSubtree` and `reattachExistingSubtree` walk NumToNode in
DFS order, they can index IDom directly. Replace an always-false `if
(DT.getNode(W))` condition with an assert.


>From ee1308715b3197ccb3ff8898ba6a3c8e36a04f15 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 8 Aug 2026 20:28:04 -0700
Subject: [PATCH] [DomTree] Store immediate dominator as DFS number. NFC

Replace the local variable `IDoms` and the pointer `InfoRec::IDom` with
a DFS number member.

Since `attachNewSubtree` and `reattachExistingSubtree` walk NumToNode in
DFS order, they can index IDom directly. Replace an always-false `if
(DT.getNode(W))` condition with an assert.
---
 .../llvm/Support/GenericDomTreeConstruction.h | 51 ++++++++-----------
 1 file changed, 20 insertions(+), 31 deletions(-)

diff --git a/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
index f644ddc1bc407..b2eb8c63dcfe7 100644
--- a/llvm/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
@@ -69,7 +69,7 @@ template <typename DomTreeT> struct SemiNCAInfo {
     unsigned Parent = 0;
     unsigned Semi = 0;
     unsigned Label = 0;
-    NodePtr IDom = nullptr;
+    unsigned IDom = 0;
     // Head index + 1 into ReverseChildren; 0: empty list.
     unsigned ReverseChildrenStart = 0;
   };
@@ -140,8 +140,6 @@ template <typename DomTreeT> struct SemiNCAInfo {
     return NodeInfos[GraphTraits<NodePtr>::getNumber(BB)];
   }
 
-  NodePtr getIDom(NodePtr BB) { return getNodeInfo(BB).IDom; }
-
   static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
 
   struct BlockNamePrinter {
@@ -271,16 +269,14 @@ template <typename DomTreeT> struct SemiNCAInfo {
   // This function requires DFS to be run before calling it.
   void runSemiNCA() {
     const unsigned NextDFSNum(NumToNode.size());
-    // NumToInfo and IDoms are indexed by DFS number; 0 is the root. IDoms holds
+    // NumToInfo is indexed by DFS number; 0 is the root. IDoms holds
     // immediate dominators in DFS-number space, initialized below to spanning
     // tree parents.
     SmallVector<InfoRec *, 32> NumToInfo;
     NumToInfo.resize_for_overwrite(NextDFSNum);
-    SmallVector<unsigned, 32> IDoms;
-    IDoms.resize_for_overwrite(NextDFSNum);
     for (unsigned i = 0; i < NextDFSNum; ++i) {
       auto &VInfo = getNodeInfo(NumToNode[i]);
-      IDoms[i] = VInfo.Parent;
+      VInfo.IDom = VInfo.Parent;
       NumToInfo[i] = &VInfo;
     }
 
@@ -307,11 +303,10 @@ template <typename DomTreeT> struct SemiNCAInfo {
     // SDom[i]'s DFS number is just Semi.
     for (unsigned i = 1; i < NextDFSNum; ++i) {
       auto &WInfo = *NumToInfo[i];
-      unsigned WIDom = IDoms[i];
+      unsigned WIDom = WInfo.IDom;
       while (WIDom > WInfo.Semi)
-        WIDom = IDoms[WIDom];
-      IDoms[i] = WIDom;
-      WInfo.IDom = NumToNode[WIDom];
+        WIDom = NumToInfo[WIDom]->IDom;
+      WInfo.IDom = WIDom;
     }
   }
 
@@ -593,35 +588,28 @@ template <typename DomTreeT> struct SemiNCAInfo {
     NodePtr Root = IsPostDom ? nullptr : DT.Roots[0];
 
     DT.RootNode = DT.createNode(Root);
-    SNCA.attachNewSubtree(DT, DT.RootNode);
+    SNCA.attachNewSubtree(DT);
   }
 
-  void attachNewSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) {
-    // Attach the first unreachable block to AttachTo.
-    getNodeInfo(NumToNode[0]).IDom = AttachTo->getBlock();
-    // Loop over all of the discovered blocks in the function...
-    for (NodePtr W : NumToNode) {
-      if (DT.getNode(W))
-        continue; // Already calculated the node before
-
-      // W's dominator has a smaller DFS number, so its tree node already exists.
-      NodePtr ImmDom = getIDom(W);
-      TreeNodePtr IDomNode = DT.getNode(ImmDom);
-      assert(IDomNode);
+  // For each non-root node in a subtree, attach it to the immediate dominator.
+  void attachNewSubtree(DomTreeT &DT) {
+    for (unsigned Num = 1, E = NumToNode.size(); Num != E; ++Num) {
+      NodePtr W = NumToNode[Num];
+      assert(!DT.getNode(W) && "node was already attached");
 
       // Add a new tree node for this BasicBlock, and link it as a child of
       // IDomNode.
+      auto IDomNode = DT.getNode(NumToNode[getNodeInfo(W).IDom]);
       DT.createNode(W, IDomNode);
     }
   }
 
   void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) {
-    getNodeInfo(NumToNode[0]).IDom = AttachTo->getBlock();
-    for (const NodePtr N : NumToNode) {
-      const TreeNodePtr TN = DT.getNode(N);
-      assert(TN);
-      const TreeNodePtr NewIDom = DT.getNode(getNodeInfo(N).IDom);
-      TN->setIDom(NewIDom);
+    DT.getNode(NumToNode[0])->setIDom(AttachTo);
+    for (unsigned Num = 1, E = NumToNode.size(); Num != E; ++Num) {
+      NodePtr N = NumToNode[Num];
+      auto IDomNode = DT.getNode(NumToNode[getNodeInfo(N).IDom]);
+      DT.getNode(N)->setIDom(IDomNode);
     }
   }
 
@@ -909,7 +897,8 @@ template <typename DomTreeT> struct SemiNCAInfo {
     SemiNCAInfo SNCA(DT, BUI);
     SNCA.runDFS(Root, 0, UnreachableDescender, 0);
     SNCA.runSemiNCA();
-    SNCA.attachNewSubtree(DT, Incoming);
+    DT.createNode(SNCA.NumToNode[0], Incoming);
+    SNCA.attachNewSubtree(DT);
 
     LLVM_DEBUG(dbgs() << "After adding unreachable nodes\n");
   }



More information about the llvm-commits mailing list