Merge pull request #21929 from slavapestov/cache-superclass-decl-request-5.0
AST: Cache SuperclassDeclRequest [5.0]
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index f8e96a1..206dcd9 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -3569,11 +3569,16 @@
void createObjCMethodLookup();
struct {
+ /// The superclass decl and a bit to indicate whether the
+ /// superclass was computed yet or not.
+ llvm::PointerIntPair<ClassDecl *, 1, bool> SuperclassDecl;
+
/// The superclass type and a bit to indicate whether the
/// superclass was computed yet or not.
- llvm::PointerIntPair<Type, 1, bool> Superclass;
+ llvm::PointerIntPair<Type, 1, bool> SuperclassType;
} LazySemanticInfo;
+ friend class SuperclassDeclRequest;
friend class SuperclassTypeRequest;
friend class TypeChecker;
@@ -3898,11 +3903,16 @@
bool existentialTypeSupportedSlow(LazyResolver *resolver);
struct {
+ /// The superclass decl and a bit to indicate whether the
+ /// superclass was computed yet or not.
+ llvm::PointerIntPair<ClassDecl *, 1, bool> SuperclassDecl;
+
/// The superclass type and a bit to indicate whether the
/// superclass was computed yet or not.
- llvm::PointerIntPair<Type, 1, bool> Superclass;
+ llvm::PointerIntPair<Type, 1, bool> SuperclassType;
} LazySemanticInfo;
+ friend class SuperclassDeclRequest;
friend class SuperclassTypeRequest;
friend class TypeChecker;
diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h
index 7f73230..5f7177a 100644
--- a/include/swift/AST/NameLookupRequests.h
+++ b/include/swift/AST/NameLookupRequests.h
@@ -133,7 +133,7 @@
/// Request the superclass declaration for the given class.
class SuperclassDeclRequest :
public SimpleRequest<SuperclassDeclRequest,
- CacheKind::Uncached, // FIXME: Cache these
+ CacheKind::SeparatelyCached,
ClassDecl *,
NominalTypeDecl *> {
public:
@@ -149,6 +149,8 @@
public:
// Caching
bool isCached() const { return true; }
+ Optional<ClassDecl *> getCachedResult() const;
+ void cacheResult(ClassDecl *value) const;
// Cycle handling
void diagnoseCycle(DiagnosticEngine &diags) const;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c92e02d..19f5f7e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3919,7 +3919,10 @@
void ProtocolDecl::setSuperclass(Type superclass) {
assert((!superclass || !superclass->hasArchetype())
&& "superclass must be interface type");
- LazySemanticInfo.Superclass.setPointerAndInt(superclass, true);
+ LazySemanticInfo.SuperclassType.setPointerAndInt(superclass, true);
+ LazySemanticInfo.SuperclassDecl.setPointerAndInt(
+ superclass ? superclass->getClassOrBoundGenericClass() : nullptr,
+ true);
}
bool ProtocolDecl::walkInheritedProtocols(
@@ -6437,7 +6440,10 @@
void ClassDecl::setSuperclass(Type superclass) {
assert((!superclass || !superclass->hasArchetype())
&& "superclass must be interface type");
- LazySemanticInfo.Superclass.setPointerAndInt(superclass, true);
+ LazySemanticInfo.SuperclassType.setPointerAndInt(superclass, true);
+ LazySemanticInfo.SuperclassDecl.setPointerAndInt(
+ superclass ? superclass->getClassOrBoundGenericClass() : nullptr,
+ true);
}
ClangNode Decl::getClangNodeImpl() const {
diff --git a/lib/AST/NameLookupRequests.cpp b/lib/AST/NameLookupRequests.cpp
index 245e6ca..0a82db6 100644
--- a/lib/AST/NameLookupRequests.cpp
+++ b/lib/AST/NameLookupRequests.cpp
@@ -74,6 +74,30 @@
//----------------------------------------------------------------------------//
// Superclass declaration computation.
//----------------------------------------------------------------------------//
+Optional<ClassDecl *> SuperclassDeclRequest::getCachedResult() const {
+ auto nominalDecl = std::get<0>(getStorage());
+
+ if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
+ if (classDecl->LazySemanticInfo.SuperclassDecl.getInt())
+ return classDecl->LazySemanticInfo.SuperclassDecl.getPointer();
+
+ if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
+ if (protocolDecl->LazySemanticInfo.SuperclassDecl.getInt())
+ return protocolDecl->LazySemanticInfo.SuperclassDecl.getPointer();
+
+ return None;
+}
+
+void SuperclassDeclRequest::cacheResult(ClassDecl *value) const {
+ auto nominalDecl = std::get<0>(getStorage());
+
+ if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
+ classDecl->LazySemanticInfo.SuperclassDecl.setPointerAndInt(value, true);
+
+ if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
+ protocolDecl->LazySemanticInfo.SuperclassDecl.setPointerAndInt(value, true);
+}
+
void SuperclassDeclRequest::diagnoseCycle(DiagnosticEngine &diags) const {
// FIXME: Improve this diagnostic.
auto subjectDecl = std::get<0>(getStorage());
@@ -87,7 +111,7 @@
}
//----------------------------------------------------------------------------//
-// Superclass declaration computation.
+// Extended nominal computation.
//----------------------------------------------------------------------------//
Optional<NominalTypeDecl *> ExtendedNominalRequest::getCachedResult() const {
// Note: if we fail to compute any nominal declaration, it's considered
diff --git a/lib/AST/TypeCheckRequests.cpp b/lib/AST/TypeCheckRequests.cpp
index 442adcb..466ff7c 100644
--- a/lib/AST/TypeCheckRequests.cpp
+++ b/lib/AST/TypeCheckRequests.cpp
@@ -125,12 +125,12 @@
auto nominalDecl = std::get<0>(getStorage());
if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
- if (classDecl->LazySemanticInfo.Superclass.getInt())
- return classDecl->LazySemanticInfo.Superclass.getPointer();
+ if (classDecl->LazySemanticInfo.SuperclassType.getInt())
+ return classDecl->LazySemanticInfo.SuperclassType.getPointer();
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
- if (protocolDecl->LazySemanticInfo.Superclass.getInt())
- return protocolDecl->LazySemanticInfo.Superclass.getPointer();
+ if (protocolDecl->LazySemanticInfo.SuperclassType.getInt())
+ return protocolDecl->LazySemanticInfo.SuperclassType.getPointer();
return None;
}
@@ -139,10 +139,10 @@
auto nominalDecl = std::get<0>(getStorage());
if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
- classDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
+ classDecl->LazySemanticInfo.SuperclassType.setPointerAndInt(value, true);
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
- protocolDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
+ protocolDecl->LazySemanticInfo.SuperclassType.setPointerAndInt(value, true);
}
//----------------------------------------------------------------------------//
diff --git a/test/Misc/stats_dir_tracer.swift b/test/Misc/stats_dir_tracer.swift
index 12795d8..90be632 100644
--- a/test/Misc/stats_dir_tracer.swift
+++ b/test/Misc/stats_dir_tracer.swift
@@ -2,9 +2,9 @@
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t %s -trace-stats-events
// RUN: %FileCheck -input-file %t/*.csv %s
-// CHECK: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumTypesDeserialized",[0-9]+,[0-9]+,"Call","\[.*stats_dir_tracer.swift.*\]"}}
-// CHECK: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumConstraintScopes",[0-9]+,[0-9]+,"Sequence","\[.*stats_dir_tracer.swift.*\]"}}
-// CHECK: {{[0-9]+,[0-9]+,"exit","SuperclassDeclRequest","Sema.SuperclassDeclRequest",[0-9]+,[0-9]+,"Bar","\[.*stats_dir_tracer.swift.*\]"}}
+// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumTypesDeserialized",[0-9]+,[0-9]+,"Call","\[.*stats_dir_tracer.swift.*\]"}}
+// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumConstraintScopes",[0-9]+,[0-9]+,"Sequence","\[.*stats_dir_tracer.swift.*\]"}}
+// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","SuperclassDeclRequest","Sema.SuperclassDeclRequest",[0-9]+,[0-9]+,"Bar","\[.*stats_dir_tracer.swift.*\]"}}
public func foo() {
print("hello")