[llvm] [IR] Use single map in PredIteratorCache (NFC) (PR #101950)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 5 02:59:50 PDT 2024
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/101950
Use a single map storing ArrayRef instead of two separate maps for the base pointer and size. This saves one map lookup per cache accesses.
This is an alternative to https://github.com/llvm/llvm-project/pull/101885 with a similar compile-time improvement: http://llvm-compile-time-tracker.com/compare.php?from=1fa7f05b709748e8a36936cbb5508070c8214354&to=1af82f2ca51aa324c772941770dd3ee4043b2b4d&stat=instructions:u
>From 15f339ca0f1614050793c5103a23d6fe88bbef8e Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 5 Aug 2024 10:35:47 +0200
Subject: [PATCH] [IR] Use single map in PredIteratorCache (NFC)
Use a single map storing ArrayRef instead of two separate maps
for the base pointer and size. This saves one map lookup per
cache accesses.
This is an alternative to https://github.com/llvm/llvm-project/pull/101885.
---
llvm/include/llvm/IR/PredIteratorCache.h | 43 ++++++------------------
1 file changed, 10 insertions(+), 33 deletions(-)
diff --git a/llvm/include/llvm/IR/PredIteratorCache.h b/llvm/include/llvm/IR/PredIteratorCache.h
index fc8cf20e9f759..d52e78b25fc33 100644
--- a/llvm/include/llvm/IR/PredIteratorCache.h
+++ b/llvm/include/llvm/IR/PredIteratorCache.h
@@ -25,52 +25,29 @@ namespace llvm {
/// predecessor iterator queries. This is useful for code that repeatedly
/// wants the predecessor list for the same blocks.
class PredIteratorCache {
- /// BlockToPredsMap - Pointer to null-terminated list.
- mutable DenseMap<BasicBlock *, BasicBlock **> BlockToPredsMap;
- mutable DenseMap<BasicBlock *, unsigned> BlockToPredCountMap;
+ /// Cached list of predecessors, allocated in Memory.
+ mutable DenseMap<BasicBlock *, ArrayRef<BasicBlock *>> BlockToPredsMap;
/// Memory - This is the space that holds cached preds.
BumpPtrAllocator Memory;
-private:
- /// GetPreds - Get a cached list for the null-terminated predecessor list of
- /// the specified block. This can be used in a loop like this:
- /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
- /// use(*PI);
- /// instead of:
- /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
- BasicBlock **GetPreds(BasicBlock *BB) {
- BasicBlock **&Entry = BlockToPredsMap[BB];
- if (Entry)
+public:
+ size_t size(BasicBlock *BB) { return get(BB).size(); }
+ ArrayRef<BasicBlock *> get(BasicBlock *BB) {
+ ArrayRef<BasicBlock *> &Entry = BlockToPredsMap[BB];
+ if (Entry.data())
return Entry;
SmallVector<BasicBlock *, 32> PredCache(predecessors(BB));
- PredCache.push_back(nullptr); // null terminator.
-
- BlockToPredCountMap[BB] = PredCache.size() - 1;
-
- Entry = Memory.Allocate<BasicBlock *>(PredCache.size());
- std::copy(PredCache.begin(), PredCache.end(), Entry);
+ BasicBlock **Data = Memory.Allocate<BasicBlock *>(PredCache.size());
+ std::copy(PredCache.begin(), PredCache.end(), Data);
+ Entry = ArrayRef(Data, PredCache.size());
return Entry;
}
- unsigned GetNumPreds(BasicBlock *BB) const {
- auto Result = BlockToPredCountMap.find(BB);
- if (Result != BlockToPredCountMap.end())
- return Result->second;
- return BlockToPredCountMap[BB] = pred_size(BB);
- }
-
-public:
- size_t size(BasicBlock *BB) const { return GetNumPreds(BB); }
- ArrayRef<BasicBlock *> get(BasicBlock *BB) {
- return ArrayRef(GetPreds(BB), GetNumPreds(BB));
- }
-
/// clear - Remove all information.
void clear() {
BlockToPredsMap.clear();
- BlockToPredCountMap.clear();
Memory.Reset();
}
};
More information about the llvm-commits
mailing list