Skip to content

Commit 2b6ba28

Browse files
committed
Serialize decls with _specialize(exported:true, target: somefunc(_:), ...) in a list for fast lookup
rdar://71430641
1 parent f4e74f7 commit 2b6ba28

File tree

13 files changed

+98
-40
lines changed

13 files changed

+98
-40
lines changed

include/swift/AST/FileUnit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ class FileUnit : public DeclContext {
183183
/// The order of the results is not guaranteed to be meaningful.
184184
virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {}
185185

186+
virtual void
187+
getExportedPrespecializations(SmallVectorImpl<Decl *> &results) const {}
188+
186189
/// Finds top-level decls in this file filtered by their attributes.
187190
///
188191
/// This does a simple local lookup, not recursively looking through imports.

include/swift/AST/Module.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ class ModuleDecl : public DeclContext, public TypeDecl {
632632
/// The order of the results is not guaranteed to be meaningful.
633633
void getTopLevelDecls(SmallVectorImpl<Decl*> &Results) const;
634634

635+
void getExportedPrespecializations(SmallVectorImpl<Decl *> &results) const;
636+
635637
/// Finds top-level decls of this module filtered by their attributes.
636638
///
637639
/// This does a simple local lookup, not recursively looking through imports.

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,9 @@ class SerializedASTFile final : public LoadedFile {
398398

399399
virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
400400

401+
virtual void getExportedPrespecializations(
402+
SmallVectorImpl<Decl *> &results) const override;
403+
401404
virtual void
402405
getTopLevelDeclsWhereAttributesMatch(
403406
SmallVectorImpl<Decl*> &Results,

lib/AST/Module.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,11 @@ void ModuleDecl::getTopLevelDecls(SmallVectorImpl<Decl*> &Results) const {
792792
FORWARD(getTopLevelDecls, (Results));
793793
}
794794

795+
void ModuleDecl::getExportedPrespecializations(
796+
SmallVectorImpl<Decl *> &Results) const {
797+
FORWARD(getExportedPrespecializations, (Results));
798+
}
799+
795800
void ModuleDecl::getTopLevelDeclsWhereAttributesMatch(
796801
SmallVectorImpl<Decl*> &Results,
797802
llvm::function_ref<bool(DeclAttributes)> matchAttributes) const {

lib/SILGen/SILGen.cpp

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,37 +2089,32 @@ swift::performASTLowering(FileUnit &sf, Lowering::TypeConverter &tc,
20892089

20902090
static void transferSpecializeAttributeTargets(SILGenModule &SGM, SILModule &M,
20912091
Decl *d) {
2092-
if (auto *asd = dyn_cast<AbstractStorageDecl>(d)) {
2093-
for (auto ad : asd->getAllAccessors()) {
2094-
transferSpecializeAttributeTargets(SGM, M, ad);
2092+
auto *vd = cast<AbstractFunctionDecl>(d);
2093+
for (auto *A : vd->getAttrs().getAttributes<SpecializeAttr>()) {
2094+
auto *SA = cast<SpecializeAttr>(A);
2095+
// Filter _spi.
2096+
auto spiGroups = SA->getSPIGroups();
2097+
auto hasSPIGroup = !spiGroups.empty();
2098+
if (hasSPIGroup) {
2099+
if (vd->getModuleContext() != M.getSwiftModule() &&
2100+
!M.getSwiftModule()->isImportedAsSPI(SA, vd)) {
2101+
continue;
2102+
}
20952103
}
2096-
} else if (auto *vd = dyn_cast<AbstractFunctionDecl>(d)) {
2097-
for (auto *A : vd->getAttrs().getAttributes<SpecializeAttr>()) {
2098-
auto *SA = cast<SpecializeAttr>(A);
2099-
// Filter _spi.
2100-
auto spiGroups = SA->getSPIGroups();
2101-
auto hasSPIGroup = !spiGroups.empty();
2104+
if (auto *targetFunctionDecl = SA->getTargetFunctionDecl(vd)) {
2105+
auto target = SILDeclRef(targetFunctionDecl);
2106+
auto targetSILFunction = SGM.getFunction(target, NotForDefinition);
2107+
auto kind = SA->getSpecializationKind() ==
2108+
SpecializeAttr::SpecializationKind::Full
2109+
? SILSpecializeAttr::SpecializationKind::Full
2110+
: SILSpecializeAttr::SpecializationKind::Partial;
2111+
Identifier spiGroupIdent;
21022112
if (hasSPIGroup) {
2103-
if (vd->getModuleContext() != M.getSwiftModule() &&
2104-
!M.getSwiftModule()->isImportedAsSPI(SA, vd)) {
2105-
continue;
2106-
}
2107-
}
2108-
if (auto *targetFunctionDecl = SA->getTargetFunctionDecl(vd)) {
2109-
auto target = SILDeclRef(targetFunctionDecl);
2110-
auto targetSILFunction = SGM.getFunction(target, NotForDefinition);
2111-
auto kind = SA->getSpecializationKind() ==
2112-
SpecializeAttr::SpecializationKind::Full
2113-
? SILSpecializeAttr::SpecializationKind::Full
2114-
: SILSpecializeAttr::SpecializationKind::Partial;
2115-
Identifier spiGroupIdent;
2116-
if (hasSPIGroup) {
2117-
spiGroupIdent = spiGroups[0];
2118-
}
2119-
targetSILFunction->addSpecializeAttr(SILSpecializeAttr::create(
2120-
M, SA->getSpecializedSignature(), SA->isExported(), kind, nullptr,
2121-
spiGroupIdent, vd->getModuleContext()));
2113+
spiGroupIdent = spiGroups[0];
21222114
}
2115+
targetSILFunction->addSpecializeAttr(SILSpecializeAttr::create(
2116+
M, SA->getSpecializedSignature(), SA->isExported(), kind, nullptr,
2117+
spiGroupIdent, vd->getModuleContext()));
21232118
}
21242119
}
21252120
}
@@ -2143,14 +2138,11 @@ void SILGenModule::visitImportDecl(ImportDecl *import) {
21432138
if (module->isNonSwiftModule())
21442139
return;
21452140

2146-
SmallVector<Decl*, 16> topLevelDecls;
2147-
module->getTopLevelDecls(topLevelDecls);
2148-
for (auto *t : topLevelDecls) {
2149-
if (auto *vd = dyn_cast<AbstractFunctionDecl>(t)) {
2141+
SmallVector<Decl*, 16> prespecializations;
2142+
module->getExportedPrespecializations(prespecializations);
2143+
for (auto *p : prespecializations) {
2144+
if (auto *vd = dyn_cast<AbstractFunctionDecl>(p)) {
21502145
transferSpecializeAttributeTargets(*this, M, vd);
2151-
} else if (auto *extension = dyn_cast<ExtensionDecl>(t)) {
2152-
for (auto *d : extension->getMembers())
2153-
transferSpecializeAttributeTargets(*this, M, d);
21542146
}
21552147
}
21562148
}

lib/Serialization/ModuleFile.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,20 @@ void ModuleFile::getTopLevelDecls(
866866
}
867867
}
868868

869+
void ModuleFile::getExportedPrespecializations(
870+
SmallVectorImpl<Decl *> &results) {
871+
for (DeclID entry : Core->ExportedPrespecializationDecls) {
872+
Expected<Decl *> declOrError = getDeclChecked(entry);
873+
if (!declOrError) {
874+
if (!getContext().LangOpts.EnableDeserializationRecovery)
875+
fatal(declOrError.takeError());
876+
consumeError(declOrError.takeError());
877+
continue;
878+
}
879+
results.push_back(declOrError.get());
880+
}
881+
}
882+
869883
void ModuleFile::getOperatorDecls(SmallVectorImpl<OperatorDecl *> &results) {
870884
PrettyStackTraceModuleFile stackEntry(*this);
871885
if (!Core->OperatorDecls)

lib/Serialization/ModuleFile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,8 @@ class ModuleFile
611611
SmallVectorImpl<Decl*> &Results,
612612
llvm::function_ref<bool(DeclAttributes)> matchAttributes = nullptr);
613613

614+
void getExportedPrespecializations(SmallVectorImpl<Decl *> &results);
615+
614616
/// Adds all operators to the given vector.
615617
void getOperatorDecls(SmallVectorImpl<OperatorDecl *> &Results);
616618

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,9 @@ bool ModuleFileSharedCore::readIndexBlock(llvm::BitstreamCursor &cursor) {
685685
case index_block::ORDERED_TOP_LEVEL_DECLS:
686686
allocateBuffer(OrderedTopLevelDecls, scratch);
687687
break;
688+
case index_block::EXPORTED_PRESPECIALIZATION_DECLS:
689+
allocateBuffer(ExportedPrespecializationDecls, scratch);
690+
break;
688691
case index_block::LOCAL_TYPE_DECLS:
689692
LocalTypeDecls = readLocalDeclTable(scratch, blobData);
690693
break;

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ class ModuleFileSharedCore {
263263
std::unique_ptr<SerializedObjCMethodTable> ObjCMethods;
264264

265265
ArrayRef<serialization::DeclID> OrderedTopLevelDecls;
266+
ArrayRef<serialization::DeclID> ExportedPrespecializationDecls;
266267

267268
class DeclCommentTableInfo;
268269
using SerializedDeclCommentTable =

lib/Serialization/ModuleFormat.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 588; // change type of get_async_continuation[_addr]
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 589; // cache prespecialization decls.
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -2016,7 +2016,8 @@ namespace index_block {
20162016

20172017
SUBSTITUTION_MAP_OFFSETS,
20182018
CLANG_TYPE_OFFSETS,
2019-
LastRecordKind = CLANG_TYPE_OFFSETS,
2019+
EXPORTED_PRESPECIALIZATION_DECLS,
2020+
LastRecordKind = EXPORTED_PRESPECIALIZATION_DECLS,
20202021
};
20212022

20222023
constexpr const unsigned RecordIDFieldWidth = 5;

0 commit comments

Comments
 (0)