Skip to content

Commit b5b905e

Browse files
committed
Bring back rc identity cache.
This takes off 0.7% of the 27.7% of the time we spent in SILoptimizer when building Stdlib.
1 parent 55bf215 commit b5b905e

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,16 @@
2727

2828
namespace swift {
2929

30+
/// Limit the size of the rc identity cache. We keep a cache per function.
31+
constexpr unsigned MaxRCIdentityCacheSize = 64;
32+
3033
class DominanceAnalysis;
3134

3235
/// This class is a simple wrapper around an identity cache.
3336
class RCIdentityFunctionInfo {
3437
llvm::DenseSet<SILArgument *> VisitedArgs;
38+
// RC identity cache.
39+
llvm::DenseMap<SILValue, SILValue> RCCache;
3540
DominanceAnalysis *DA;
3641

3742
/// This number is arbitrary and conservative. At some point if compile time
@@ -50,6 +55,15 @@ class RCIdentityFunctionInfo {
5055
/// unchecked_trivial_bit_cast.
5156
void getRCUsers(SILValue V, llvm::SmallVectorImpl<SILInstruction *> &Users);
5257

58+
void handleDeleteNotification(ValueBase *V) {
59+
// Check the cache. If we don't find it, there is nothing to do.
60+
auto Iter = RCCache.find(SILValue(V));
61+
if (Iter == RCCache.end())
62+
return;
63+
// Then erase Iter from the cache.
64+
RCCache.erase(Iter);
65+
}
66+
5367
private:
5468
SILValue getRCIdentityRootInner(SILValue V, unsigned RecursionDepth);
5569
SILValue stripRCIdentityPreservingOps(SILValue V, unsigned RecursionDepth);
@@ -70,6 +84,18 @@ class RCIdentityAnalysis : public FunctionAnalysisBase<RCIdentityFunctionInfo> {
7084
RCIdentityAnalysis(const RCIdentityAnalysis &) = delete;
7185
RCIdentityAnalysis &operator=(const RCIdentityAnalysis &) = delete;
7286

87+
virtual void handleDeleteNotification(ValueBase *V) override {
88+
// If the parent function of this instruction was just turned into an
89+
// external declaration, bail. This happens during SILFunction destruction.
90+
SILFunction *F = V->getParentBB()->getParent();
91+
if (F->isExternalDeclaration()) {
92+
return;
93+
}
94+
get(F)->handleDeleteNotification(V);
95+
}
96+
97+
virtual bool needsNotifications() override { return true; }
98+
7399
static bool classof(const SILAnalysis *S) {
74100
return S->getKind() == AnalysisKind::RCIdentity;
75101
}

lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,14 +453,24 @@ SILValue RCIdentityFunctionInfo::getRCIdentityRootInner(SILValue V,
453453
}
454454

455455
SILValue RCIdentityFunctionInfo::getRCIdentityRoot(SILValue V) {
456+
// Do we have it in the RCCache ?
457+
auto Iter = RCCache.find(V);
458+
if (Iter != RCCache.end())
459+
return Iter->second;
460+
456461
SILValue Root = getRCIdentityRootInner(V, 0);
457462
VisitedArgs.clear();
458463

459464
// If we fail to find a root, return V.
460465
if (!Root)
461466
return V;
462467

463-
return Root;
468+
// Make sure the cache does not grow too big.
469+
if (RCCache.size() > MaxRCIdentityCacheSize)
470+
RCCache.clear();
471+
472+
// Return and cache it.
473+
return RCCache[V] = Root;
464474
}
465475

466476
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)