Skip to content

Commit 6233346

Browse files
authored
[GenericCycle] Add a Cache for getExitBlocks in GenericCycle (#112290)
In `UniformityAnalysis`, we need to get the exit blocks of cycles in the `DivergencePropagator` and currently, we have to do a search for the exit blocks every time. In this change, we add a cache of the results in the `GenericCycle` so that it can save the compile time. By testing, for some large cases, this can save about 60% compile time in the `UniformityAnalysis`.
1 parent 1549a0c commit 6233346

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

llvm/include/llvm/ADT/GenericCycleImpl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ bool GenericCycle<ContextT>::contains(const GenericCycle *C) const {
4747
template <typename ContextT>
4848
void GenericCycle<ContextT>::getExitBlocks(
4949
SmallVectorImpl<BlockT *> &TmpStorage) const {
50+
if (!ExitBlocksCache.empty()) {
51+
TmpStorage = ExitBlocksCache;
52+
return;
53+
}
54+
5055
TmpStorage.clear();
5156

5257
size_t NumExitBlocks = 0;
@@ -65,6 +70,7 @@ void GenericCycle<ContextT>::getExitBlocks(
6570

6671
TmpStorage.resize(NumExitBlocks);
6772
}
73+
ExitBlocksCache.append(TmpStorage.begin(), TmpStorage.end());
6874
}
6975

7076
template <typename ContextT>
@@ -298,6 +304,8 @@ void GenericCycleInfo<ContextT>::moveTopLevelCycleToNewParent(CycleT *NewParent,
298304
for (auto &It : BlockMapTopLevel)
299305
if (It.second == Child)
300306
It.second = NewParent;
307+
NewParent->clearCache();
308+
Child->clearCache();
301309
}
302310

303311
template <typename ContextT>
@@ -316,6 +324,7 @@ void GenericCycleInfo<ContextT>::addBlockToCycle(BlockT *Block, CycleT *Cycle) {
316324
}
317325

318326
BlockMapTopLevel.try_emplace(Block, Cycle);
327+
Cycle->clearCache();
319328
}
320329

321330
/// \brief Main function of the cycle info computations.

llvm/include/llvm/ADT/GenericCycleInfo.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,27 @@ template <typename ContextT> class GenericCycle {
7474
/// always have the same depth.
7575
unsigned Depth = 0;
7676

77+
/// Cache for the results of GetExitBlocks
78+
mutable SmallVector<BlockT *, 4> ExitBlocksCache;
79+
7780
void clear() {
7881
Entries.clear();
7982
Children.clear();
8083
Blocks.clear();
8184
Depth = 0;
8285
ParentCycle = nullptr;
86+
clearCache();
87+
}
88+
89+
void appendEntry(BlockT *Block) {
90+
Entries.push_back(Block);
91+
clearCache();
8392
}
8493

85-
void appendEntry(BlockT *Block) { Entries.push_back(Block); }
86-
void appendBlock(BlockT *Block) { Blocks.insert(Block); }
94+
void appendBlock(BlockT *Block) {
95+
Blocks.insert(Block);
96+
clearCache();
97+
}
8798

8899
GenericCycle(const GenericCycle &) = delete;
89100
GenericCycle &operator=(const GenericCycle &) = delete;
@@ -102,6 +113,11 @@ template <typename ContextT> class GenericCycle {
102113
return Entries;
103114
}
104115

116+
/// Clear the cache of the cycle.
117+
/// This should be run in all non-const function in GenericCycle
118+
/// and GenericCycleInfo.
119+
void clearCache() const { ExitBlocksCache.clear(); }
120+
105121
/// \brief Return whether \p Block is an entry block of the cycle.
106122
bool isEntry(const BlockT *Block) const {
107123
return is_contained(Entries, Block);
@@ -112,6 +128,7 @@ template <typename ContextT> class GenericCycle {
112128
assert(contains(Block));
113129
Entries.clear();
114130
Entries.push_back(Block);
131+
clearCache();
115132
}
116133

117134
/// \brief Return whether \p Block is contained in the cycle.

0 commit comments

Comments
 (0)