Skip to content

Commit 6676f79

Browse files
authored
[IR] Use single map in PredIteratorCache (NFC) (#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 #101885 with a similar compile-time improvement.
1 parent b032920 commit 6676f79

File tree

1 file changed

+10
-33
lines changed

1 file changed

+10
-33
lines changed

llvm/include/llvm/IR/PredIteratorCache.h

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,52 +25,29 @@ namespace llvm {
2525
/// predecessor iterator queries. This is useful for code that repeatedly
2626
/// wants the predecessor list for the same blocks.
2727
class PredIteratorCache {
28-
/// BlockToPredsMap - Pointer to null-terminated list.
29-
mutable DenseMap<BasicBlock *, BasicBlock **> BlockToPredsMap;
30-
mutable DenseMap<BasicBlock *, unsigned> BlockToPredCountMap;
28+
/// Cached list of predecessors, allocated in Memory.
29+
DenseMap<BasicBlock *, ArrayRef<BasicBlock *>> BlockToPredsMap;
3130

3231
/// Memory - This is the space that holds cached preds.
3332
BumpPtrAllocator Memory;
3433

35-
private:
36-
/// GetPreds - Get a cached list for the null-terminated predecessor list of
37-
/// the specified block. This can be used in a loop like this:
38-
/// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
39-
/// use(*PI);
40-
/// instead of:
41-
/// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
42-
BasicBlock **GetPreds(BasicBlock *BB) {
43-
BasicBlock **&Entry = BlockToPredsMap[BB];
44-
if (Entry)
34+
public:
35+
size_t size(BasicBlock *BB) { return get(BB).size(); }
36+
ArrayRef<BasicBlock *> get(BasicBlock *BB) {
37+
ArrayRef<BasicBlock *> &Entry = BlockToPredsMap[BB];
38+
if (Entry.data())
4539
return Entry;
4640

4741
SmallVector<BasicBlock *, 32> PredCache(predecessors(BB));
48-
PredCache.push_back(nullptr); // null terminator.
49-
50-
BlockToPredCountMap[BB] = PredCache.size() - 1;
51-
52-
Entry = Memory.Allocate<BasicBlock *>(PredCache.size());
53-
std::copy(PredCache.begin(), PredCache.end(), Entry);
42+
BasicBlock **Data = Memory.Allocate<BasicBlock *>(PredCache.size());
43+
std::copy(PredCache.begin(), PredCache.end(), Data);
44+
Entry = ArrayRef(Data, PredCache.size());
5445
return Entry;
5546
}
5647

57-
unsigned GetNumPreds(BasicBlock *BB) const {
58-
auto Result = BlockToPredCountMap.find(BB);
59-
if (Result != BlockToPredCountMap.end())
60-
return Result->second;
61-
return BlockToPredCountMap[BB] = pred_size(BB);
62-
}
63-
64-
public:
65-
size_t size(BasicBlock *BB) const { return GetNumPreds(BB); }
66-
ArrayRef<BasicBlock *> get(BasicBlock *BB) {
67-
return ArrayRef(GetPreds(BB), GetNumPreds(BB));
68-
}
69-
7048
/// clear - Remove all information.
7149
void clear() {
7250
BlockToPredsMap.clear();
73-
BlockToPredCountMap.clear();
7451
Memory.Reset();
7552
}
7653
};

0 commit comments

Comments
 (0)