Skip to content

Commit 603a5df

Browse files
committed
[AST] Use DenseMap for the cache
1 parent 9a2c62d commit 603a5df

File tree

3 files changed

+151
-121
lines changed

3 files changed

+151
-121
lines changed

include/swift/AST/ASTContext.h

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
#ifndef SWIFT_AST_ASTCONTEXT_H
1818
#define SWIFT_AST_ASTCONTEXT_H
1919

20-
#include "llvm/Support/DataTypes.h"
2120
#include "swift/AST/ClangModuleLoader.h"
2221
#include "swift/AST/Evaluator.h"
22+
#include "swift/AST/GenericSignature.h"
2323
#include "swift/AST/Identifier.h"
2424
#include "swift/AST/SearchPathOptions.h"
2525
#include "swift/AST/Type.h"
@@ -28,13 +28,14 @@
2828
#include "swift/Basic/Malloc.h"
2929
#include "llvm/ADT/ArrayRef.h"
3030
#include "llvm/ADT/DenseMap.h"
31-
#include "llvm/ADT/MapVector.h"
3231
#include "llvm/ADT/IntrusiveRefCntPtr.h"
32+
#include "llvm/ADT/MapVector.h"
3333
#include "llvm/ADT/PointerIntPair.h"
3434
#include "llvm/ADT/SetVector.h"
3535
#include "llvm/ADT/StringMap.h"
3636
#include "llvm/ADT/TinyPtrVector.h"
3737
#include "llvm/Support/Allocator.h"
38+
#include "llvm/Support/DataTypes.h"
3839
#include <functional>
3940
#include <memory>
4041
#include <utility>
@@ -870,25 +871,19 @@ class ASTContext final {
870871
void getVisibleTopLevelModuleNames(SmallVectorImpl<Identifier> &names) const;
871872

872873
struct OverrideSignatureKey {
873-
StringRef baseMethodSigString;
874-
StringRef derivedClassSigString;
874+
GenericSignature *baseMethodSig;
875+
GenericSignature *derivedClassSig;
875876
Type superclassTy;
876877

877-
OverrideSignatureKey(StringRef baseMethodSig, StringRef derivedClassSig,
878-
Type derivedClassSuperclassType)
879-
: baseMethodSigString(baseMethodSig),
880-
derivedClassSigString(derivedClassSig),
881-
superclassTy(derivedClassSuperclassType) {}
882-
883-
bool isEqual(const OverrideSignatureKey other) {
884-
return baseMethodSigString == other.baseMethodSigString &&
885-
derivedClassSigString == other.derivedClassSigString &&
886-
superclassTy.getString() == other.superclassTy.getString();
878+
OverrideSignatureKey(GenericSignature *baseMethodSignature,
879+
GenericSignature *derivedClassSignature,
880+
Type superclassType)
881+
: baseMethodSig(baseMethodSignature),
882+
derivedClassSig(derivedClassSignature), superclassTy(superclassType) {
887883
}
888884
};
889885

890-
std::vector<std::pair<OverrideSignatureKey, GenericSignature *>>
891-
overrideSigCache;
886+
llvm::DenseMap<OverrideSignatureKey, GenericSignature *> overrideSigCache;
892887

893888
private:
894889
/// Register the given generic signature builder to be used as the canonical
@@ -919,6 +914,9 @@ class ASTContext final {
919914
CanGenericSignature getExistentialSignature(CanType existential,
920915
ModuleDecl *mod);
921916

917+
GenericSignature *getOverrideGenericSignature(ValueDecl *base,
918+
ValueDecl *derived);
919+
922920
/// Whether our effective Swift version is at least 'major'.
923921
///
924922
/// This is usually the check you want; for example, when introducing
@@ -956,4 +954,39 @@ class ASTContext final {
956954

957955
} // end namespace swift
958956

957+
namespace llvm {
958+
template <> struct DenseMapInfo<swift::ASTContext::OverrideSignatureKey> {
959+
using OverrideSignatureKey = swift::ASTContext::OverrideSignatureKey;
960+
using Type = swift::Type;
961+
using GenericSignature = swift::GenericSignature;
962+
963+
static bool isEqual(const OverrideSignatureKey lhs,
964+
const OverrideSignatureKey rhs) {
965+
return lhs.baseMethodSig == rhs.baseMethodSig &&
966+
lhs.derivedClassSig == rhs.derivedClassSig &&
967+
lhs.superclassTy.getString() == rhs.superclassTy.getString();
968+
}
969+
970+
static inline OverrideSignatureKey getEmptyKey() {
971+
return OverrideSignatureKey(DenseMapInfo<GenericSignature *>::getEmptyKey(),
972+
DenseMapInfo<GenericSignature *>::getEmptyKey(),
973+
DenseMapInfo<Type>::getEmptyKey());
974+
}
975+
976+
static inline OverrideSignatureKey getTombstoneKey() {
977+
return OverrideSignatureKey(
978+
DenseMapInfo<GenericSignature *>::getTombstoneKey(),
979+
DenseMapInfo<GenericSignature *>::getTombstoneKey(),
980+
DenseMapInfo<Type>::getTombstoneKey());
981+
}
982+
983+
static unsigned getHashValue(const OverrideSignatureKey &Val) {
984+
return hash_combine(
985+
DenseMapInfo<GenericSignature *>::getHashValue(Val.baseMethodSig),
986+
DenseMapInfo<GenericSignature *>::getHashValue(Val.derivedClassSig),
987+
DenseMapInfo<Type>::getHashValue(Val.superclassTy));
988+
}
989+
};
990+
} // namespace llvm
991+
959992
#endif

lib/AST/ASTContext.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4340,6 +4340,107 @@ CanGenericSignature ASTContext::getExistentialSignature(CanType existential,
43404340
return genericSig;
43414341
}
43424342

4343+
GenericSignature *ASTContext::getOverrideGenericSignature(ValueDecl *base,
4344+
ValueDecl *derived) {
4345+
auto baseGenericCtx = base->getAsGenericContext();
4346+
auto &ctx = base->getASTContext();
4347+
4348+
if (!baseGenericCtx) {
4349+
return nullptr;
4350+
}
4351+
4352+
auto baseClass = base->getDeclContext()->getSelfClassDecl();
4353+
4354+
if (!baseClass) {
4355+
return nullptr;
4356+
}
4357+
4358+
auto derivedClass = derived->getDeclContext()->getSelfClassDecl();
4359+
auto *baseClassSig = baseClass->getGenericSignature();
4360+
4361+
if (!derivedClass) {
4362+
return nullptr;
4363+
}
4364+
4365+
if (derivedClass->getSuperclass().isNull()) {
4366+
return nullptr;
4367+
}
4368+
4369+
if (derivedClass->getGenericSignature() == nullptr &&
4370+
!baseGenericCtx->isGeneric()) {
4371+
return nullptr;
4372+
}
4373+
4374+
auto subMap = derivedClass->getSuperclass()->getContextSubstitutionMap(
4375+
derivedClass->getModuleContext(), baseClass);
4376+
4377+
if (baseGenericCtx->getGenericSignature() == nullptr) {
4378+
return nullptr;
4379+
}
4380+
unsigned derivedDepth = 0;
4381+
4382+
auto key = OverrideSignatureKey(baseGenericCtx->getGenericSignature(),
4383+
derivedClass->getGenericSignature(),
4384+
derivedClass->getSuperclass());
4385+
4386+
if (overrideSigCache.count(key) == 1) {
4387+
return overrideSigCache.lookup(key);
4388+
}
4389+
4390+
if (auto *derivedSig = derivedClass->getGenericSignature())
4391+
derivedDepth = derivedSig->getGenericParams().back()->getDepth() + 1;
4392+
4393+
GenericSignatureBuilder builder(ctx);
4394+
builder.addGenericSignature(derivedClass->getGenericSignature());
4395+
4396+
if (auto derivedGenericCtx = derived->getAsGenericContext()) {
4397+
if (derivedGenericCtx->isGeneric()) {
4398+
for (auto param : *derivedGenericCtx->getGenericParams()) {
4399+
builder.addGenericParameter(param);
4400+
}
4401+
}
4402+
}
4403+
4404+
auto source =
4405+
GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
4406+
4407+
unsigned baseDepth = 0;
4408+
4409+
if (baseClassSig) {
4410+
baseDepth = baseClassSig->getGenericParams().back()->getDepth() + 1;
4411+
}
4412+
4413+
auto substFn = [&](SubstitutableType *type) -> Type {
4414+
auto *gp = cast<GenericTypeParamType>(type);
4415+
4416+
if (gp->getDepth() < baseDepth) {
4417+
return Type(gp).subst(subMap);
4418+
}
4419+
4420+
return CanGenericTypeParamType::get(
4421+
gp->getDepth() - baseDepth + derivedDepth, gp->getIndex(), ctx);
4422+
};
4423+
4424+
auto lookupConformanceFn =
4425+
[&](CanType depTy, Type substTy,
4426+
ProtocolDecl *proto) -> Optional<ProtocolConformanceRef> {
4427+
if (auto conf = subMap.lookupConformance(depTy, proto))
4428+
return conf;
4429+
4430+
return ProtocolConformanceRef(proto);
4431+
};
4432+
4433+
for (auto reqt : baseGenericCtx->getGenericSignature()->getRequirements()) {
4434+
if (auto substReqt = reqt.subst(substFn, lookupConformanceFn)) {
4435+
builder.addRequirement(*substReqt, source, nullptr);
4436+
}
4437+
}
4438+
4439+
auto *genericSig = std::move(builder).computeGenericSignature(SourceLoc());
4440+
overrideSigCache.insert(std::make_pair(key, genericSig));
4441+
return genericSig;
4442+
}
4443+
43434444
SILLayout *SILLayout::get(ASTContext &C,
43444445
CanGenericSignature Generics,
43454446
ArrayRef<SILField> Fields) {

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 1 addition & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -931,110 +931,6 @@ static void checkOverrideAccessControl(ValueDecl *baseDecl, ValueDecl *decl,
931931
}
932932
}
933933

934-
static GenericSignature *getOverrideGenericSignature(ValueDecl *base,
935-
ValueDecl *derived) {
936-
auto baseGenericCtx = base->getAsGenericContext();
937-
auto &ctx = base->getASTContext();
938-
939-
if (!baseGenericCtx) {
940-
return nullptr;
941-
}
942-
943-
auto baseClass = base->getDeclContext()->getSelfClassDecl();
944-
945-
if (!baseClass) {
946-
return nullptr;
947-
}
948-
949-
auto derivedClass = derived->getDeclContext()->getSelfClassDecl();
950-
auto *baseClassSig = baseClass->getGenericSignature();
951-
952-
if (!derivedClass) {
953-
return nullptr;
954-
}
955-
956-
if (derivedClass->getSuperclass().isNull()) {
957-
return nullptr;
958-
}
959-
960-
if (derivedClass->getGenericSignature() == nullptr &&
961-
!baseGenericCtx->isGeneric()) {
962-
return nullptr;
963-
}
964-
965-
auto subMap = derivedClass->getSuperclass()->getContextSubstitutionMap(
966-
derivedClass->getModuleContext(), baseClass);
967-
968-
if (baseGenericCtx->getGenericSignature() == nullptr) {
969-
return nullptr;
970-
}
971-
unsigned derivedDepth = 0;
972-
973-
auto key = swift::ASTContext::OverrideSignatureKey(
974-
baseGenericCtx->getGenericSignature()->getAsString(),
975-
derivedClass->getGenericSignature()->getAsString(),
976-
derivedClass->getSuperclass());
977-
978-
for (auto pair : ctx.overrideSigCache) {
979-
if (pair.first.isEqual(key)) {
980-
return pair.second;
981-
}
982-
}
983-
984-
if (auto *derivedSig = derivedClass->getGenericSignature())
985-
derivedDepth = derivedSig->getGenericParams().back()->getDepth() + 1;
986-
987-
GenericSignatureBuilder builder(ctx);
988-
builder.addGenericSignature(derivedClass->getGenericSignature());
989-
990-
if (auto derivedGenericCtx = derived->getAsGenericContext()) {
991-
if (derivedGenericCtx->isGeneric()) {
992-
for (auto param : *derivedGenericCtx->getGenericParams()) {
993-
builder.addGenericParameter(param);
994-
}
995-
}
996-
}
997-
998-
auto source =
999-
GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
1000-
1001-
unsigned baseDepth = 0;
1002-
1003-
if (baseClassSig) {
1004-
baseDepth = baseClassSig->getGenericParams().back()->getDepth() + 1;
1005-
}
1006-
1007-
auto substFn = [&](SubstitutableType *type) -> Type {
1008-
auto *gp = cast<GenericTypeParamType>(type);
1009-
1010-
if (gp->getDepth() < baseDepth) {
1011-
return Type(gp).subst(subMap);
1012-
}
1013-
1014-
return CanGenericTypeParamType::get(
1015-
gp->getDepth() - baseDepth + derivedDepth, gp->getIndex(), ctx);
1016-
};
1017-
1018-
auto lookupConformanceFn =
1019-
[&](CanType depTy, Type substTy,
1020-
ProtocolDecl *proto) -> Optional<ProtocolConformanceRef> {
1021-
if (auto conf = subMap.lookupConformance(depTy, proto))
1022-
return conf;
1023-
1024-
return ProtocolConformanceRef(proto);
1025-
};
1026-
1027-
for (auto reqt : baseGenericCtx->getGenericSignature()->getRequirements()) {
1028-
if (auto substReqt = reqt.subst(substFn, lookupConformanceFn)) {
1029-
builder.addRequirement(*substReqt, source, nullptr);
1030-
}
1031-
}
1032-
1033-
auto *genericSig = std::move(builder).computeGenericSignature(SourceLoc());
1034-
ctx.overrideSigCache.push_back(std::make_pair(key, genericSig));
1035-
return genericSig;
1036-
}
1037-
1038934
bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
1039935
OverrideCheckingAttempt attempt) {
1040936
auto &diags = ctx.Diags;
@@ -1057,7 +953,7 @@ bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
1057953

1058954
if (baseGenericCtx && derivedGenericCtx) {
1059955
// If the generic signatures are different, then complain
1060-
if (auto newSig = getOverrideGenericSignature(baseDecl, decl)) {
956+
if (auto newSig = ctx.getOverrideGenericSignature(baseDecl, decl)) {
1061957
if (auto derivedSig = derivedGenericCtx->getGenericSignature()) {
1062958
auto requirementsSatisfied =
1063959
derivedSig->requirementsNotSatisfiedBy(newSig).empty();

0 commit comments

Comments
 (0)