[llvm] [SSAUpdater] Don't use large SmallSets for IDFcalc (PR #97823)
Jeremy Morse via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 16 06:24:25 PDT 2024
https://github.com/jmorse updated https://github.com/llvm/llvm-project/pull/97823
>From 33666499d5b99b9e50305047ce52cf440fd5dfb0 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Fri, 5 Jul 2024 13:15:43 +0100
Subject: [PATCH 1/3] [SSAUpdater] Don't use large SmallSets for IDFcalc
As per the LLVM programmers manual, SmallSets do linear scans on insertion
and then turn into a hash-table if the set gets big. Here in the
IDFCalculator, the SmallSets have been configured to have 32 elements in
each static allocation... which means that we linearly scan for all
problems with up to 32 elements.
Replace these SmallSets with a plain DenseSet (and use reserve to avoid any
repeated allocations). Doing this yields a 0.13% compile-time improvement
for debug-info builds, as we hit IDFCalculator pretty hard in
InstrRefBasedLDV.
---
.../llvm/Support/GenericIteratedDominanceFrontier.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
index 0dc58e37c821d..c218d33c3eb30 100644
--- a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
+++ b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
@@ -144,8 +144,12 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
DT.updateDFSNumbers();
SmallVector<DomTreeNodeBase<NodeTy> *, 32> Worklist;
- SmallPtrSet<DomTreeNodeBase<NodeTy> *, 32> VisitedPQ;
- SmallPtrSet<DomTreeNodeBase<NodeTy> *, 32> VisitedWorklist;
+ SmallDenseSet<DomTreeNodeBase<NodeTy> *, 16> VisitedPQ;
+ SmallDenseSet<DomTreeNodeBase<NodeTy> *, 16> VisitedWorklist;
+ if (useLiveIn) {
+ VisitedPQ.reserve(LiveInBlocks->size());
+ VisitedWorklist.reserve(LiveInBlocks->size());
+ }
for (NodeTy *BB : *DefBlocks)
if (DomTreeNodeBase<NodeTy> *Node = DT.getNode(BB)) {
>From 3ab1e7d9559ddd3b5b809824978e721181d51a42 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 16 Jul 2024 14:23:33 +0100
Subject: [PATCH 2/3] Implement a reserve call for SmallPtrSet
---
llvm/include/llvm/ADT/SmallPtrSet.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/llvm/include/llvm/ADT/SmallPtrSet.h b/llvm/include/llvm/ADT/SmallPtrSet.h
index 597cad8444f69..dd6d5ee72867e 100644
--- a/llvm/include/llvm/ADT/SmallPtrSet.h
+++ b/llvm/include/llvm/ADT/SmallPtrSet.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/EpochTracker.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ReverseIteration.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
@@ -108,6 +109,21 @@ class SmallPtrSetImplBase : public DebugEpochBase {
NumTombstones = 0;
}
+ void reserve(size_type NumEntries) {
+ incrementEpoch();
+ // No need to expand if we're small and NumEntries will fit in the space.
+ if (isSmall() && NumEntries < CurArraySize)
+ return;
+ // insert_imp_big will reallocate if stores is more than 75% full.
+ if (!isSmall() && (NumEntries * 4) <= (CurArraySize * 3))
+ return;
+ // We must Grow -- find the size where we'd be 75% full, then round up to
+ // the next power of two.
+ size_type NewSize = NumEntries + (NumEntries / 3);
+ NewSize = 1 << (Log2_32_Ceil(NewSize) + 1);
+ Grow(NewSize);
+ }
+
protected:
static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
>From ab267cc31f01dcc088c4839a4fadd3eca92b902f Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 16 Jul 2024 14:23:43 +0100
Subject: [PATCH 3/3] Switch back to using SmallPtrSets in IDF calculator
---
llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
index c218d33c3eb30..e08a75c137d00 100644
--- a/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
+++ b/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
@@ -144,8 +144,8 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
DT.updateDFSNumbers();
SmallVector<DomTreeNodeBase<NodeTy> *, 32> Worklist;
- SmallDenseSet<DomTreeNodeBase<NodeTy> *, 16> VisitedPQ;
- SmallDenseSet<DomTreeNodeBase<NodeTy> *, 16> VisitedWorklist;
+ SmallPtrSet<DomTreeNodeBase<NodeTy> *, 16> VisitedPQ;
+ SmallPtrSet<DomTreeNodeBase<NodeTy> *, 16> VisitedWorklist;
if (useLiveIn) {
VisitedPQ.reserve(LiveInBlocks->size());
VisitedWorklist.reserve(LiveInBlocks->size());
More information about the llvm-commits
mailing list