Skip to content

Commit 2460aa7

Browse files
committed
AST: Cache ProtocolDecl::getInheritedProtocols()
Fixes <rdar://problem/47371754>.
1 parent a9da2a5 commit 2460aa7

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

include/swift/AST/Decl.h

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ class alignas(1 << DeclAlignInBits) Decl {
488488
HasLazyConformances : 1
489489
);
490490

491-
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+2+8+16,
491+
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+2+1+8+16,
492492
/// Whether the \c RequiresClass bit is valid.
493493
RequiresClassValid : 1,
494494

@@ -514,6 +514,9 @@ class alignas(1 << DeclAlignInBits) Decl {
514514
/// The stage of the circularity check for this protocol.
515515
Circularity : 2,
516516

517+
/// Whether we've computed the inherited protocols list yet.
518+
InheritedProtocolsValid : 1,
519+
517520
: NumPadBits,
518521

519522
/// If this is a compiler-known protocol, this will be a KnownProtocolKind
@@ -3892,15 +3895,7 @@ struct SelfReferenceKind {
38923895
class ProtocolDecl final : public NominalTypeDecl {
38933896
SourceLoc ProtocolLoc;
38943897

3895-
/// The generic signature representing exactly the new requirements introduced
3896-
/// by this protocol.
3897-
const Requirement *RequirementSignature = nullptr;
3898-
3899-
bool requiresClassSlow();
3900-
3901-
bool existentialConformsToSelfSlow();
3902-
3903-
bool existentialTypeSupportedSlow(LazyResolver *resolver);
3898+
ArrayRef<ProtocolDecl *> InheritedProtocols;
39043899

39053900
struct {
39063901
/// The superclass decl and a bit to indicate whether the
@@ -3912,6 +3907,18 @@ class ProtocolDecl final : public NominalTypeDecl {
39123907
llvm::PointerIntPair<Type, 1, bool> SuperclassType;
39133908
} LazySemanticInfo;
39143909

3910+
/// The generic signature representing exactly the new requirements introduced
3911+
/// by this protocol.
3912+
const Requirement *RequirementSignature = nullptr;
3913+
3914+
bool requiresClassSlow();
3915+
3916+
bool existentialConformsToSelfSlow();
3917+
3918+
bool existentialTypeSupportedSlow(LazyResolver *resolver);
3919+
3920+
ArrayRef<ProtocolDecl *> getInheritedProtocolsSlow();
3921+
39153922
friend class SuperclassDeclRequest;
39163923
friend class SuperclassTypeRequest;
39173924
friend class TypeChecker;
@@ -3924,7 +3931,12 @@ class ProtocolDecl final : public NominalTypeDecl {
39243931
using Decl::getASTContext;
39253932

39263933
/// Retrieve the set of protocols inherited from this protocol.
3927-
llvm::TinyPtrVector<ProtocolDecl *> getInheritedProtocols() const;
3934+
ArrayRef<ProtocolDecl *> getInheritedProtocols() const {
3935+
if (Bits.ProtocolDecl.InheritedProtocolsValid)
3936+
return InheritedProtocols;
3937+
3938+
return const_cast<ProtocolDecl *>(this)->getInheritedProtocolsSlow();
3939+
}
39283940

39293941
/// Determine whether this protocol has a superclass.
39303942
bool hasSuperclass() const { return (bool)getSuperclassDecl(); }

lib/AST/Decl.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3856,16 +3856,19 @@ ProtocolDecl::ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc,
38563856
Bits.ProtocolDecl.ExistentialConformsToSelf = false;
38573857
Bits.ProtocolDecl.Circularity
38583858
= static_cast<unsigned>(CircularityCheck::Unchecked);
3859+
Bits.ProtocolDecl.InheritedProtocolsValid = 0;
38593860
Bits.ProtocolDecl.NumRequirementsInSignature = 0;
38603861
Bits.ProtocolDecl.HasMissingRequirements = false;
38613862
Bits.ProtocolDecl.KnownProtocol = 0;
3862-
setTrailingWhereClause(TrailingWhere);
3863+
setTrailingWhereClause(TrailingWhere);
38633864
}
38643865

3865-
llvm::TinyPtrVector<ProtocolDecl *>
3866-
ProtocolDecl::getInheritedProtocols() const {
3867-
llvm::TinyPtrVector<ProtocolDecl *> result;
3868-
SmallPtrSet<const ProtocolDecl *, 4> known;
3866+
ArrayRef<ProtocolDecl *>
3867+
ProtocolDecl::getInheritedProtocolsSlow() {
3868+
Bits.ProtocolDecl.InheritedProtocolsValid = true;
3869+
3870+
llvm::SmallVector<ProtocolDecl *, 2> result;
3871+
SmallPtrSet<const ProtocolDecl *, 2> known;
38693872
known.insert(this);
38703873
bool anyObject = false;
38713874
for (const auto found :
@@ -3877,7 +3880,9 @@ ProtocolDecl::getInheritedProtocols() const {
38773880
}
38783881
}
38793882

3880-
return result;
3883+
auto &ctx = getASTContext();
3884+
InheritedProtocols = ctx.AllocateCopy(result);
3885+
return InheritedProtocols;
38813886
}
38823887

38833888
llvm::TinyPtrVector<AssociatedTypeDecl *>

0 commit comments

Comments
 (0)