[llvm] [DomTree] Avoid duplicate hash lookups in runDFS() (NFCI) (PR #96460)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 24 01:09:18 PDT 2024


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/96460

runDFS() currently performs three hash table lookups. One in the main loop, one when checking whether a successor has already been visited and another when adding parent and reverse children to the successor.

We can avoid the two additional lookups by making the parent number part of the stack, and then making the parent / reverse children update part of the main loop.

The main loop already has a check for already visited nodes, so we don't have to check this in advance -- we can simply push the node to the worklist and skip it later.

This results in a minor compile-time improvement: http://llvm-compile-time-tracker.com/compare.php?from=c43d5f540fd43409e7997c9fec97a1d415855b7c&to=1844fc47329a2905bf73b7b86964e8a31fa3b758&stat=instructions:u

>From 1844fc47329a2905bf73b7b86964e8a31fa3b758 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Wed, 6 Dec 2023 14:52:20 +0100
Subject: [PATCH] [DomTree] Avoid duplicate hash lookups in runDFS() (NFCI)

runDFS() currently performs three hash table lookups. One in the main
loop, one when checking whether a successor has already been
visited and another when adding parent and reverse children to the
successor.

We can avoid the two additional lookups by making the parent
number part of the stack, and then making the parent / reverse
children update part of the main loop.

The main loop already has a check for already visited nodes, so
we don't have to check this in advance -- we can simply push the
node to the worklist and skip it later.
---
 .../llvm/Support/GenericDomTreeConstruction.h | 21 +++++--------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
index 401cc4eb0ec1b..57cbe993d8739 100644
--- a/llvm/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
@@ -180,15 +180,17 @@ struct SemiNCAInfo {
                   unsigned AttachToNum,
                   const NodeOrderMap *SuccOrder = nullptr) {
     assert(V);
-    SmallVector<NodePtr, 64> WorkList = {V};
+    SmallVector<std::pair<NodePtr, unsigned>, 64> WorkList = {{V, AttachToNum}};
     NodeToInfo[V].Parent = AttachToNum;
 
     while (!WorkList.empty()) {
-      const NodePtr BB = WorkList.pop_back_val();
+      const auto [BB, ParentNum] = WorkList.pop_back_val();
       auto &BBInfo = NodeToInfo[BB];
+      BBInfo.ReverseChildren.push_back(ParentNum);
 
       // Visited nodes always have positive DFS numbers.
       if (BBInfo.DFSNum != 0) continue;
+      BBInfo.Parent = ParentNum;
       BBInfo.DFSNum = BBInfo.Semi = BBInfo.Label = ++LastNum;
       NumToNode.push_back(BB);
 
@@ -201,22 +203,9 @@ struct SemiNCAInfo {
             });
 
       for (const NodePtr Succ : Successors) {
-        const auto SIT = NodeToInfo.find(Succ);
-        // Don't visit nodes more than once but remember to collect
-        // ReverseChildren.
-        if (SIT != NodeToInfo.end() && SIT->second.DFSNum != 0) {
-          if (Succ != BB) SIT->second.ReverseChildren.push_back(LastNum);
-          continue;
-        }
-
         if (!Condition(BB, Succ)) continue;
 
-        // It's fine to add Succ to the map, because we know that it will be
-        // visited later.
-        auto &SuccInfo = NodeToInfo[Succ];
-        WorkList.push_back(Succ);
-        SuccInfo.Parent = LastNum;
-        SuccInfo.ReverseChildren.push_back(LastNum);
+        WorkList.push_back({Succ, LastNum});
       }
     }
 



More information about the llvm-commits mailing list