[llvm] [IDF] Use BitVectors indexed by DFS number for visited sets (NFC). (PR #227832)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 10:04:30 PDT 2026
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/227832
>From 4405abaeab711aeb6deef1875aafc37cdac56b97 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 29 Sep 2026 09:18:31 +0100
Subject: [PATCH 1/2] [IDF] Use BitVectors indexed by DFS number for visited
sets (NFC).
IDFCalculatorBase::calculate tracks visited dominator tree nodes in two
SmallPtrSets. The DFS numbers computed at the start of calculate are
unique and dense in [0, number of nodes), with the DFS out-number of the
root being the number of nodes, so use them to index BitVectors instead.
This reduces hashing overhead and improves compile-time, depending on
configuration/workload:
stage1-O3: -0.04%
stage1-ReleaseThinLTO: -0.05%
stage1-ReleaseLTO-g: -0.22%
stage1-aarch64-O3: -0.06%
stage2-O3: -0.04%
stage2-clang: -0.04%
https://llvm-compile-time-tracker.com/compare.php?from=b96b66160ace30c2b5eef1f4afdb14c95ecc26cd&to=5ffb13d6d1f87195bba8af13366a152a7de2bfe0&stat=instructions:u
---
.../GenericIteratedDominanceFrontier.h | 26 ++++++++++++-------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
index c52b2cab377bf87..4e9b30a97060144 100644
--- a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
+++ b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
@@ -23,6 +23,7 @@
#ifndef LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H
#define LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
@@ -144,18 +145,20 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
DT.updateDFSNumbers();
+ // The DFS in-numbers are unique and dense in [0, number of nodes), with the
+ // root's DFS out-number being the number of nodes. Use them to index the
+ // visited sets.
+ const DomTreeNodeBase<NodeTy> *RootNode = DT.getRootNode();
+ unsigned NumNodes = RootNode ? RootNode->getDFSNumOut() : 0;
+
SmallVector<DomTreeNodeBase<NodeTy> *, 32> Worklist;
- SmallPtrSet<DomTreeNodeBase<NodeTy> *, 16> VisitedPQ;
- SmallPtrSet<DomTreeNodeBase<NodeTy> *, 16> VisitedWorklist;
- if (useLiveIn) {
- VisitedPQ.reserve(LiveInBlocks->size());
- VisitedWorklist.reserve(LiveInBlocks->size());
- }
+ BitVector VisitedPQ(NumNodes);
+ BitVector VisitedWorklist(NumNodes);
for (NodeTy *BB : *DefBlocks)
if (DomTreeNodeBase<NodeTy> *Node = DT.getNode(BB)) {
PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
- VisitedWorklist.insert(Node);
+ VisitedWorklist.set(Node->getDFSNumIn());
}
while (!PQ.empty()) {
@@ -184,8 +187,9 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
if (SuccLevel > RootLevel)
return;
- if (!VisitedPQ.insert(SuccNode).second)
+ if (VisitedPQ.test(SuccNode->getDFSNumIn()))
return;
+ VisitedPQ.set(SuccNode->getDFSNumIn());
NodeTy *SuccBB = SuccNode->getBlock();
if (useLiveIn && !LiveInBlocks->count(SuccBB))
@@ -201,8 +205,10 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
DoWork(Succ);
for (auto DomChild : *Node) {
- if (VisitedWorklist.insert(DomChild).second)
- Worklist.push_back(DomChild);
+ if (VisitedWorklist.test(DomChild->getDFSNumIn()))
+ continue;
+ VisitedWorklist.set(DomChild->getDFSNumIn());
+ Worklist.push_back(DomChild);
}
}
}
>From 26453e778b0f5feab44b9ffe801655e9a8a1f769 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 1 Oct 2026 09:54:03 +0100
Subject: [PATCH 2/2] Use SmallVector<bool>
---
.../Support/GenericIteratedDominanceFrontier.h | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
index 4e9b30a97060144..32baf09b8b19d30 100644
--- a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
+++ b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
@@ -23,7 +23,6 @@
#ifndef LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H
#define LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H
-#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
@@ -152,13 +151,13 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
unsigned NumNodes = RootNode ? RootNode->getDFSNumOut() : 0;
SmallVector<DomTreeNodeBase<NodeTy> *, 32> Worklist;
- BitVector VisitedPQ(NumNodes);
- BitVector VisitedWorklist(NumNodes);
+ SmallVector<bool, 32> VisitedPQ(NumNodes, false);
+ SmallVector<bool, 32> VisitedWorklist(NumNodes, false);
for (NodeTy *BB : *DefBlocks)
if (DomTreeNodeBase<NodeTy> *Node = DT.getNode(BB)) {
PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
- VisitedWorklist.set(Node->getDFSNumIn());
+ VisitedWorklist[Node->getDFSNumIn()] = true;
}
while (!PQ.empty()) {
@@ -187,9 +186,8 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
if (SuccLevel > RootLevel)
return;
- if (VisitedPQ.test(SuccNode->getDFSNumIn()))
+ if (std::exchange(VisitedPQ[SuccNode->getDFSNumIn()], true))
return;
- VisitedPQ.set(SuccNode->getDFSNumIn());
NodeTy *SuccBB = SuccNode->getBlock();
if (useLiveIn && !LiveInBlocks->count(SuccBB))
@@ -205,10 +203,8 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
DoWork(Succ);
for (auto DomChild : *Node) {
- if (VisitedWorklist.test(DomChild->getDFSNumIn()))
- continue;
- VisitedWorklist.set(DomChild->getDFSNumIn());
- Worklist.push_back(DomChild);
+ if (!std::exchange(VisitedWorklist[DomChild->getDFSNumIn()], true))
+ Worklist.push_back(DomChild);
}
}
}
More information about the llvm-commits
mailing list