@@ -25,52 +25,42 @@ namespace llvm {
25
25
// / predecessor iterator queries. This is useful for code that repeatedly
26
26
// / wants the predecessor list for the same blocks.
27
27
class PredIteratorCache {
28
- // / BlockToPredsMap - Pointer to null-terminated list.
29
- mutable DenseMap<BasicBlock *, BasicBlock **> BlockToPredsMap;
30
- mutable DenseMap<BasicBlock *, unsigned > BlockToPredCountMap;
28
+ // / Storage, indexed by block number.
29
+ SmallVector<ArrayRef<BasicBlock *>> Storage;
30
+ // / Block number epoch to guard against renumberings.
31
+ unsigned BlockNumberEpoch;
31
32
32
33
// / Memory - This is the space that holds cached preds.
33
34
BumpPtrAllocator Memory;
34
35
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)
45
- return Entry;
46
-
47
- SmallVector<BasicBlock *, 32 > PredCache (predecessors (BB));
48
- PredCache.push_back (nullptr ); // null terminator.
36
+ public:
37
+ size_t size (BasicBlock *BB) { return get (BB).size (); }
38
+ ArrayRef<BasicBlock *> get (BasicBlock *BB) {
39
+ #ifndef NDEBUG
40
+ // In debug builds, verify that no renumbering has occured.
41
+ if (Storage.empty ())
42
+ BlockNumberEpoch = BB->getParent ()->getBlockNumberEpoch ();
43
+ else
44
+ assert (BlockNumberEpoch == BB->getParent ()->getBlockNumberEpoch () &&
45
+ " Blocks renumbered during lifetime of PredIteratorCache" );
46
+ #endif
49
47
50
- BlockToPredCountMap[BB] = PredCache.size () - 1 ;
48
+ if (LLVM_LIKELY (BB->getNumber () < Storage.size ()))
49
+ if (auto Res = Storage[BB->getNumber ()]; Res.data ())
50
+ return Res;
51
51
52
- Entry = Memory.Allocate <BasicBlock *>(PredCache.size ());
53
- std::copy (PredCache.begin (), PredCache.end (), Entry);
54
- return Entry;
55
- }
52
+ if (BB->getNumber () >= Storage.size ())
53
+ Storage.resize (BB->getParent ()->getMaxBlockNumber ());
56
54
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));
55
+ SmallVector<BasicBlock *, 32 > PredCache (predecessors (BB));
56
+ BasicBlock **Data = Memory.Allocate <BasicBlock *>(PredCache.size ());
57
+ std::copy (PredCache.begin (), PredCache.end (), Data);
58
+ return Storage[BB->getNumber ()] = ArrayRef (Data, PredCache.size ());
68
59
}
69
60
70
61
// / clear - Remove all information.
71
62
void clear () {
72
- BlockToPredsMap.clear ();
73
- BlockToPredCountMap.clear ();
63
+ Storage.clear ();
74
64
Memory.Reset ();
75
65
}
76
66
};
0 commit comments