Skip to content

Commit a8d1910

Browse files
committed
AST: Cache SuperclassDeclRequest
This fixes a significant build time regression since 4.2. Fixes <rdar://problem/47305605>.
1 parent 51c9ba7 commit a8d1910

File tree

6 files changed

+57
-15
lines changed

6 files changed

+57
-15
lines changed

include/swift/AST/Decl.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3562,11 +3562,16 @@ class ClassDecl final : public NominalTypeDecl {
35623562
void createObjCMethodLookup();
35633563

35643564
struct {
3565+
/// The superclass decl and a bit to indicate whether the
3566+
/// superclass was computed yet or not.
3567+
llvm::PointerIntPair<ClassDecl *, 1, bool> SuperclassDecl;
3568+
35653569
/// The superclass type and a bit to indicate whether the
35663570
/// superclass was computed yet or not.
3567-
llvm::PointerIntPair<Type, 1, bool> Superclass;
3571+
llvm::PointerIntPair<Type, 1, bool> SuperclassType;
35683572
} LazySemanticInfo;
35693573

3574+
friend class SuperclassDeclRequest;
35703575
friend class SuperclassTypeRequest;
35713576
friend class TypeChecker;
35723577

@@ -3899,11 +3904,16 @@ class ProtocolDecl final : public NominalTypeDecl {
38993904
bool existentialTypeSupportedSlow(LazyResolver *resolver);
39003905

39013906
struct {
3907+
/// The superclass decl and a bit to indicate whether the
3908+
/// superclass was computed yet or not.
3909+
llvm::PointerIntPair<ClassDecl *, 1, bool> SuperclassDecl;
3910+
39023911
/// The superclass type and a bit to indicate whether the
39033912
/// superclass was computed yet or not.
3904-
llvm::PointerIntPair<Type, 1, bool> Superclass;
3913+
llvm::PointerIntPair<Type, 1, bool> SuperclassType;
39053914
} LazySemanticInfo;
39063915

3916+
friend class SuperclassDeclRequest;
39073917
friend class SuperclassTypeRequest;
39083918
friend class TypeChecker;
39093919

include/swift/AST/NameLookupRequests.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ class UnderlyingTypeDeclsReferencedRequest :
133133
/// Request the superclass declaration for the given class.
134134
class SuperclassDeclRequest :
135135
public SimpleRequest<SuperclassDeclRequest,
136-
CacheKind::Uncached, // FIXME: Cache these
136+
CacheKind::SeparatelyCached,
137137
ClassDecl *,
138138
NominalTypeDecl *> {
139139
public:
@@ -149,6 +149,8 @@ class SuperclassDeclRequest :
149149
public:
150150
// Caching
151151
bool isCached() const { return true; }
152+
Optional<ClassDecl *> getCachedResult() const;
153+
void cacheResult(ClassDecl *value) const;
152154

153155
// Cycle handling
154156
void diagnoseCycle(DiagnosticEngine &diags) const;

lib/AST/Decl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3973,7 +3973,10 @@ ClassDecl *ProtocolDecl::getSuperclassDecl() const {
39733973
void ProtocolDecl::setSuperclass(Type superclass) {
39743974
assert((!superclass || !superclass->hasArchetype())
39753975
&& "superclass must be interface type");
3976-
LazySemanticInfo.Superclass.setPointerAndInt(superclass, true);
3976+
LazySemanticInfo.SuperclassType.setPointerAndInt(superclass, true);
3977+
LazySemanticInfo.SuperclassDecl.setPointerAndInt(
3978+
superclass ? superclass->getClassOrBoundGenericClass() : nullptr,
3979+
true);
39773980
}
39783981

39793982
bool ProtocolDecl::walkInheritedProtocols(
@@ -6478,7 +6481,10 @@ ClassDecl *ClassDecl::getSuperclassDecl() const {
64786481
void ClassDecl::setSuperclass(Type superclass) {
64796482
assert((!superclass || !superclass->hasArchetype())
64806483
&& "superclass must be interface type");
6481-
LazySemanticInfo.Superclass.setPointerAndInt(superclass, true);
6484+
LazySemanticInfo.SuperclassType.setPointerAndInt(superclass, true);
6485+
LazySemanticInfo.SuperclassDecl.setPointerAndInt(
6486+
superclass ? superclass->getClassOrBoundGenericClass() : nullptr,
6487+
true);
64826488
}
64836489

64846490
ClangNode Decl::getClangNodeImpl() const {

lib/AST/NameLookupRequests.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,30 @@ void UnderlyingTypeDeclsReferencedRequest::noteCycleStep(
7474
//----------------------------------------------------------------------------//
7575
// Superclass declaration computation.
7676
//----------------------------------------------------------------------------//
77+
Optional<ClassDecl *> SuperclassDeclRequest::getCachedResult() const {
78+
auto nominalDecl = std::get<0>(getStorage());
79+
80+
if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
81+
if (classDecl->LazySemanticInfo.SuperclassDecl.getInt())
82+
return classDecl->LazySemanticInfo.SuperclassDecl.getPointer();
83+
84+
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
85+
if (protocolDecl->LazySemanticInfo.SuperclassDecl.getInt())
86+
return protocolDecl->LazySemanticInfo.SuperclassDecl.getPointer();
87+
88+
return None;
89+
}
90+
91+
void SuperclassDeclRequest::cacheResult(ClassDecl *value) const {
92+
auto nominalDecl = std::get<0>(getStorage());
93+
94+
if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
95+
classDecl->LazySemanticInfo.SuperclassDecl.setPointerAndInt(value, true);
96+
97+
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
98+
protocolDecl->LazySemanticInfo.SuperclassDecl.setPointerAndInt(value, true);
99+
}
100+
77101
void SuperclassDeclRequest::diagnoseCycle(DiagnosticEngine &diags) const {
78102
// FIXME: Improve this diagnostic.
79103
auto subjectDecl = std::get<0>(getStorage());
@@ -87,7 +111,7 @@ void SuperclassDeclRequest::noteCycleStep(DiagnosticEngine &diags) const {
87111
}
88112

89113
//----------------------------------------------------------------------------//
90-
// Superclass declaration computation.
114+
// Extended nominal computation.
91115
//----------------------------------------------------------------------------//
92116
Optional<NominalTypeDecl *> ExtendedNominalRequest::getCachedResult() const {
93117
// Note: if we fail to compute any nominal declaration, it's considered

lib/AST/TypeCheckRequests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ Optional<Type> SuperclassTypeRequest::getCachedResult() const {
125125
auto nominalDecl = std::get<0>(getStorage());
126126

127127
if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
128-
if (classDecl->LazySemanticInfo.Superclass.getInt())
129-
return classDecl->LazySemanticInfo.Superclass.getPointer();
128+
if (classDecl->LazySemanticInfo.SuperclassType.getInt())
129+
return classDecl->LazySemanticInfo.SuperclassType.getPointer();
130130

131131
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
132-
if (protocolDecl->LazySemanticInfo.Superclass.getInt())
133-
return protocolDecl->LazySemanticInfo.Superclass.getPointer();
132+
if (protocolDecl->LazySemanticInfo.SuperclassType.getInt())
133+
return protocolDecl->LazySemanticInfo.SuperclassType.getPointer();
134134

135135
return None;
136136
}
@@ -139,10 +139,10 @@ void SuperclassTypeRequest::cacheResult(Type value) const {
139139
auto nominalDecl = std::get<0>(getStorage());
140140

141141
if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
142-
classDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
142+
classDecl->LazySemanticInfo.SuperclassType.setPointerAndInt(value, true);
143143

144144
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
145-
protocolDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
145+
protocolDecl->LazySemanticInfo.SuperclassType.setPointerAndInt(value, true);
146146
}
147147

148148
//----------------------------------------------------------------------------//

test/Misc/stats_dir_tracer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t %s -trace-stats-events
33
// RUN: %FileCheck -input-file %t/*.csv %s
44

5-
// CHECK: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumTypesDeserialized",[0-9]+,[0-9]+,"Call","\[.*stats_dir_tracer.swift.*\]"}}
6-
// CHECK: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumConstraintScopes",[0-9]+,[0-9]+,"Sequence","\[.*stats_dir_tracer.swift.*\]"}}
7-
// CHECK: {{[0-9]+,[0-9]+,"exit","SuperclassDeclRequest","Sema.SuperclassDeclRequest",[0-9]+,[0-9]+,"Bar","\[.*stats_dir_tracer.swift.*\]"}}
5+
// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumTypesDeserialized",[0-9]+,[0-9]+,"Call","\[.*stats_dir_tracer.swift.*\]"}}
6+
// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumConstraintScopes",[0-9]+,[0-9]+,"Sequence","\[.*stats_dir_tracer.swift.*\]"}}
7+
// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","SuperclassDeclRequest","Sema.SuperclassDeclRequest",[0-9]+,[0-9]+,"Bar","\[.*stats_dir_tracer.swift.*\]"}}
88

99
public func foo() {
1010
print("hello")

0 commit comments

Comments
 (0)