Skip to content

Commit eef3efb

Browse files
committed
AST: Cache ProtocolDecl::getInheritedProtocols()
Fixes <rdar://problem/47371754>.
1 parent 4681b9b commit eef3efb

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
@@ -493,7 +493,7 @@ class alignas(1 << DeclAlignInBits) Decl {
493493
HasLazyConformances : 1
494494
);
495495

496-
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+2+8+16,
496+
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+2+1+8+16,
497497
/// Whether the \c RequiresClass bit is valid.
498498
RequiresClassValid : 1,
499499

@@ -519,6 +519,9 @@ class alignas(1 << DeclAlignInBits) Decl {
519519
/// The stage of the circularity check for this protocol.
520520
Circularity : 2,
521521

522+
/// Whether we've computed the inherited protocols list yet.
523+
InheritedProtocolsValid : 1,
524+
522525
: NumPadBits,
523526

524527
/// If this is a compiler-known protocol, this will be a KnownProtocolKind
@@ -3893,15 +3896,7 @@ struct SelfReferenceKind {
38933896
class ProtocolDecl final : public NominalTypeDecl {
38943897
SourceLoc ProtocolLoc;
38953898

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

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

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

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

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

lib/AST/Decl.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3909,16 +3909,19 @@ ProtocolDecl::ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc,
39093909
Bits.ProtocolDecl.ExistentialConformsToSelf = false;
39103910
Bits.ProtocolDecl.Circularity
39113911
= static_cast<unsigned>(CircularityCheck::Unchecked);
3912+
Bits.ProtocolDecl.InheritedProtocolsValid = 0;
39123913
Bits.ProtocolDecl.NumRequirementsInSignature = 0;
39133914
Bits.ProtocolDecl.HasMissingRequirements = false;
39143915
Bits.ProtocolDecl.KnownProtocol = 0;
3915-
setTrailingWhereClause(TrailingWhere);
3916+
setTrailingWhereClause(TrailingWhere);
39163917
}
39173918

3918-
llvm::TinyPtrVector<ProtocolDecl *>
3919-
ProtocolDecl::getInheritedProtocols() const {
3920-
llvm::TinyPtrVector<ProtocolDecl *> result;
3921-
SmallPtrSet<const ProtocolDecl *, 4> known;
3919+
ArrayRef<ProtocolDecl *>
3920+
ProtocolDecl::getInheritedProtocolsSlow() {
3921+
Bits.ProtocolDecl.InheritedProtocolsValid = true;
3922+
3923+
llvm::SmallVector<ProtocolDecl *, 2> result;
3924+
SmallPtrSet<const ProtocolDecl *, 2> known;
39223925
known.insert(this);
39233926
bool anyObject = false;
39243927
for (const auto found :
@@ -3930,7 +3933,9 @@ ProtocolDecl::getInheritedProtocols() const {
39303933
}
39313934
}
39323935

3933-
return result;
3936+
auto &ctx = getASTContext();
3937+
InheritedProtocols = ctx.AllocateCopy(result);
3938+
return InheritedProtocols;
39343939
}
39353940

39363941
llvm::TinyPtrVector<AssociatedTypeDecl *>

0 commit comments

Comments
 (0)