Skip to content

Commit 280f748

Browse files
committed
[AutoDiff] Enhance performance of custom derivatives lookup
In swiftlang#58965, lookup for custom derivatives in non-primary source files was introduced. It required traversing all delayed parsed function bodies of a file if the file was compiled with differential programming enabled (even for functions with no `@derivative` attribute). This patch introduces `CustomDerivativesLookupRequest` to address the issue. Resolves swiftlang#60102
1 parent 3334adb commit 280f748

File tree

5 files changed

+46
-24
lines changed

5 files changed

+46
-24
lines changed

include/swift/AST/Module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ class ModuleDecl
240240
: public DeclContext, public TypeDecl, public ASTAllocated<ModuleDecl> {
241241
friend class DirectOperatorLookupRequest;
242242
friend class DirectPrecedenceGroupLookupRequest;
243+
friend class CustomDerivativesLookupRequest;
243244

244245
/// The ABI name of the module, if it differs from the module name.
245246
mutable Identifier ModuleABIName;

include/swift/AST/NameLookupRequests.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,22 @@ class LookupIntrinsicRequest
969969
bool isCached() const { return true; }
970970
};
971971

972+
using CustomDerivativesLookupResult = SmallVector<AbstractFunctionDecl *, 0>;
973+
974+
class CustomDerivativesLookupRequest
975+
: public SimpleRequest<CustomDerivativesLookupRequest,
976+
CustomDerivativesLookupResult(ModuleDecl *),
977+
RequestFlags::Uncached /*TODO*/> {
978+
public:
979+
using SimpleRequest::SimpleRequest;
980+
981+
private:
982+
friend SimpleRequest;
983+
984+
CustomDerivativesLookupResult evaluate(Evaluator &evaluator,
985+
ModuleDecl *module) const;
986+
};
987+
972988
using ObjCCategoryNameMap =
973989
llvm::DenseMap<Identifier, llvm::TinyPtrVector<ExtensionDecl *>>;
974990

include/swift/AST/NameLookupTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,5 @@ SWIFT_REQUEST(NameLookup, LookupIntrinsicRequest,
118118
FuncDecl *(ModuleDecl *, Identifier), Cached, NoLocationInfo)
119119
SWIFT_REQUEST(NameLookup, ObjCCategoryNameMapRequest,
120120
ObjCCategoryNameMap(ClassDecl *, ExtensionDecl *), Cached, NoLocationInfo)
121+
SWIFT_REQUEST(NameLookup, CustomDerivativesLookupRequest,
122+
CustomDerivativesLookupResult(ModuleDecl *), Uncached, NoLocationInfo)

lib/AST/Module.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ class swift::SourceLookupCache {
166166
ValueDeclMap TopLevelValues;
167167
ValueDeclMap ClassMembers;
168168
bool MemberCachePopulated = false;
169+
CustomDerivativesLookupResult CustomDerivatives;
169170
DeclName UniqueMacroNamePlaceholder;
170171

171172
template<typename T>
@@ -175,7 +176,7 @@ class swift::SourceLookupCache {
175176

176177
template<typename Range>
177178
void addToUnqualifiedLookupCache(Range decls, bool onlyOperators);
178-
template<typename Range>
179+
template <typename Range>
179180
void addToMemberCache(Range decls);
180181

181182
using AuxiliaryDeclMap = llvm::DenseMap<DeclName, TinyPtrVector<MissingDecl *>>;
@@ -205,6 +206,8 @@ class swift::SourceLookupCache {
205206
/// guaranteed to be meaningful.
206207
void getPrecedenceGroups(SmallVectorImpl<PrecedenceGroupDecl *> &results);
207208

209+
CustomDerivativesLookupResult getCustomDerivativeDecls();
210+
208211
/// Look up an operator declaration.
209212
///
210213
/// \param name The operator name ("+", ">>", etc.)
@@ -275,6 +278,11 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range items,
275278
if (!onlyOperators && VD->getAttrs().hasAttribute<CustomAttr>()) {
276279
MayHaveAuxiliaryDecls.push_back(VD);
277280
}
281+
282+
if (!onlyOperators)
283+
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD))
284+
if (AFD->getAttrs().hasAttribute<DerivativeAttr>())
285+
CustomDerivatives.push_back(AFD);
278286
}
279287
}
280288

@@ -572,6 +580,10 @@ void SourceLookupCache::getOperatorDecls(
572580
results.append(ops.second.begin(), ops.second.end());
573581
}
574582

583+
CustomDerivativesLookupResult SourceLookupCache::getCustomDerivativeDecls() {
584+
return CustomDerivatives;
585+
}
586+
575587
void SourceLookupCache::lookupOperator(Identifier name, OperatorFixity fixity,
576588
TinyPtrVector<OperatorDecl *> &results) {
577589
auto ops = Operators.find(name);
@@ -1578,6 +1590,13 @@ void SourceFile::lookupOperatorDirect(
15781590
getCache().lookupOperator(name, fixity, results);
15791591
}
15801592

1593+
CustomDerivativesLookupResult
1594+
CustomDerivativesLookupRequest::evaluate(Evaluator &evaluator,
1595+
ModuleDecl *module) const {
1596+
assert(isParsedModule(module));
1597+
return module->getSourceLookupCache().getCustomDerivativeDecls();
1598+
}
1599+
15811600
void DirectPrecedenceGroupLookupRequest::writeDependencySink(
15821601
evaluator::DependencyCollector &reqTracker,
15831602
const TinyPtrVector<PrecedenceGroupDecl *> &groups) const {

lib/Sema/TypeChecker.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "swift/AST/Initializer.h"
3535
#include "swift/AST/ModuleLoader.h"
3636
#include "swift/AST/NameLookup.h"
37+
#include "swift/AST/NameLookupRequests.h"
3738
#include "swift/AST/PrettyStackTrace.h"
3839
#include "swift/AST/ProtocolConformance.h"
3940
#include "swift/AST/SourceFile.h"
@@ -404,34 +405,17 @@ void swift::loadDerivativeConfigurations(SourceFile &SF) {
404405
FrontendStatsTracer tracer(Ctx.Stats,
405406
"load-derivative-configurations");
406407

407-
class DerivativeFinder : public ASTWalker {
408-
public:
409-
DerivativeFinder() {}
410-
411-
MacroWalking getMacroWalkingBehavior() const override {
412-
return MacroWalking::Expansion;
413-
}
414-
415-
PreWalkAction walkToDeclPre(Decl *D) override {
416-
if (auto *afd = dyn_cast<AbstractFunctionDecl>(D)) {
417-
for (auto *derAttr : afd->getAttrs().getAttributes<DerivativeAttr>()) {
418-
// Resolve derivative function configurations from `@derivative`
419-
// attributes by type-checking them.
420-
(void)derAttr->getOriginalFunction(D->getASTContext());
421-
}
422-
}
423-
424-
return Action::Continue();
425-
}
426-
};
427-
428408
switch (SF.Kind) {
429409
case SourceFileKind::DefaultArgument:
430410
case SourceFileKind::Library:
431411
case SourceFileKind::MacroExpansion:
432412
case SourceFileKind::Main: {
433-
DerivativeFinder finder;
434-
SF.walkContext(finder);
413+
CustomDerivativesLookupRequest request(SF.getParentModule());
414+
CustomDerivativesLookupResult result =
415+
evaluateOrDefault(SF.getASTContext().evaluator, request, {});
416+
for (AbstractFunctionDecl *AFD : result)
417+
for (auto *derAttr : AFD->getAttrs().getAttributes<DerivativeAttr>())
418+
(void)derAttr->getOriginalFunction(SF.getASTContext());
435419
return;
436420
}
437421
case SourceFileKind::SIL:

0 commit comments

Comments
 (0)