Skip to content

Commit f1e3ef8

Browse files
committed
SILOptimizer: Compute ProtocolConformanceAnalysis cache lazily.
When serializing modules with `-experimental-skip-all-function-bodies`, this analysis was eagerly populating a cache that would go unused since there is no optimization to do. With `-experimental-lazy-typecheck`, this work would also trigger unnecessary typechecking requests. NFC.
1 parent de4370b commit f1e3ef8

File tree

2 files changed

+16
-13
lines changed

2 files changed

+16
-13
lines changed

include/swift/SILOptimizer/Analysis/ProtocolConformanceAnalysis.h

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ class ProtocolConformanceAnalysis : public SILAnalysis {
3939
SoleConformingTypeMap;
4040

4141
ProtocolConformanceAnalysis(SILModule *Mod)
42-
: SILAnalysis(SILAnalysisKind::ProtocolConformance), M(Mod) {
43-
init();
44-
}
42+
: SILAnalysis(SILAnalysisKind::ProtocolConformance), M(Mod) {}
4543

4644
~ProtocolConformanceAnalysis();
4745

@@ -66,14 +64,15 @@ class ProtocolConformanceAnalysis : public SILAnalysis {
6664
virtual void invalidateFunctionTables() override {}
6765

6866
/// Get the nominal types that implement a protocol.
69-
ArrayRef<NominalTypeDecl *> getConformances(const ProtocolDecl *P) const {
70-
auto ConformsListIt = ProtocolConformanceCache.find(P);
71-
return ConformsListIt != ProtocolConformanceCache.end()
67+
ArrayRef<NominalTypeDecl *> getConformances(const ProtocolDecl *P) {
68+
populateConformanceCacheIfNecessary();
69+
auto ConformsListIt = ProtocolConformanceCache->find(P);
70+
return ConformsListIt != ProtocolConformanceCache->end()
7271
? ArrayRef<NominalTypeDecl *>(ConformsListIt->second.begin(),
7372
ConformsListIt->second.end())
7473
: ArrayRef<NominalTypeDecl *>();
7574
}
76-
75+
7776
/// Traverse ProtocolConformanceMapCache recursively to determine sole
7877
/// conforming concrete type.
7978
NominalTypeDecl *findSoleConformingType(ProtocolDecl *Protocol);
@@ -83,17 +82,17 @@ class ProtocolConformanceAnalysis : public SILAnalysis {
8382
bool getSoleConformingType(ProtocolDecl *Protocol, ClassHierarchyAnalysis *CHA, CanType &ConcreteType);
8483

8584
private:
86-
/// Compute inheritance properties.
87-
void init();
88-
8985
/// The module.
9086
SILModule *M;
9187

9288
/// A cache that maps a protocol to its conformances.
93-
ProtocolConformanceMap ProtocolConformanceCache;
89+
llvm::Optional<ProtocolConformanceMap> ProtocolConformanceCache;
9490

9591
/// A cache that holds SoleConformingType for protocols.
9692
SoleConformingTypeMap SoleConformingTypeCache;
93+
94+
/// Populates `ProtocolConformanceCache` if necessary.
95+
void populateConformanceCacheIfNecessary();
9796
};
9897

9998
} // namespace swift

lib/SILOptimizer/Analysis/ProtocolConformanceAnalysis.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ class NominalTypeWalker : public ASTWalker {
7070
};
7171
} // end anonymous namespace
7272

73-
void ProtocolConformanceAnalysis::init() {
73+
void ProtocolConformanceAnalysis::populateConformanceCacheIfNecessary() {
74+
if (ProtocolConformanceCache.has_value())
75+
return;
76+
77+
ProtocolConformanceCache.emplace();
7478

7579
// We only do this in Whole-Module compilation mode.
7680
if (!M->isWholeModule())
@@ -84,7 +88,7 @@ void ProtocolConformanceAnalysis::init() {
8488

8589
/// This operation is quadratic and should only be performed
8690
/// in whole module compilation!
87-
NominalTypeWalker Walker(ProtocolConformanceCache);
91+
NominalTypeWalker Walker(*ProtocolConformanceCache);
8892
for (auto *D : Decls) {
8993
D->walk(Walker);
9094
}

0 commit comments

Comments
 (0)