Skip to content

Commit 032ce73

Browse files
committed
Use two-level storage to avoid large memset
1 parent ad71aea commit 032ce73

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

llvm/include/llvm/IR/PredIteratorCache.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define LLVM_IR_PREDITERATORCACHE_H
1515

1616
#include "llvm/ADT/ArrayRef.h"
17-
#include "llvm/ADT/DenseMap.h"
17+
#include "llvm/ADT/BitVector.h"
1818
#include "llvm/ADT/SmallVector.h"
1919
#include "llvm/IR/CFG.h"
2020
#include "llvm/Support/Allocator.h"
@@ -27,6 +27,8 @@ namespace llvm {
2727
class PredIteratorCache {
2828
/// Storage, indexed by block number.
2929
SmallVector<ArrayRef<BasicBlock *>> Storage;
30+
/// Whether storage is valid, indexed by block number.
31+
BitVector StorageValid;
3032
/// Block number epoch to guard against renumberings.
3133
unsigned BlockNumberEpoch;
3234

@@ -38,29 +40,33 @@ class PredIteratorCache {
3840
ArrayRef<BasicBlock *> get(BasicBlock *BB) {
3941
#ifndef NDEBUG
4042
// In debug builds, verify that no renumbering has occured.
41-
if (Storage.empty())
43+
if (StorageValid.empty())
4244
BlockNumberEpoch = BB->getParent()->getBlockNumberEpoch();
4345
else
4446
assert(BlockNumberEpoch == BB->getParent()->getBlockNumberEpoch() &&
4547
"Blocks renumbered during lifetime of PredIteratorCache");
4648
#endif
4749

48-
if (LLVM_LIKELY(BB->getNumber() < Storage.size()))
49-
if (auto Res = Storage[BB->getNumber()]; Res.data())
50-
return Res;
50+
if (LLVM_LIKELY(BB->getNumber() < StorageValid.size()))
51+
if (StorageValid[BB->getNumber()])
52+
return Storage[BB->getNumber()];
5153

52-
if (BB->getNumber() >= Storage.size())
53-
Storage.resize(BB->getParent()->getMaxBlockNumber());
54+
if (BB->getNumber() >= StorageValid.size()) {
55+
StorageValid.resize(BB->getParent()->getMaxBlockNumber());
56+
// Don't initialize memory for performance
57+
Storage.resize_for_overwrite(BB->getParent()->getMaxBlockNumber());
58+
}
5459

5560
SmallVector<BasicBlock *, 32> PredCache(predecessors(BB));
5661
BasicBlock **Data = Memory.Allocate<BasicBlock *>(PredCache.size());
5762
std::copy(PredCache.begin(), PredCache.end(), Data);
63+
StorageValid[BB->getNumber()] = true;
5864
return Storage[BB->getNumber()] = ArrayRef(Data, PredCache.size());
5965
}
6066

6167
/// clear - Remove all information.
6268
void clear() {
63-
Storage.clear();
69+
StorageValid.clear();
6470
Memory.Reset();
6571
}
6672
};

0 commit comments

Comments
 (0)