[AST] Use cached deserialized decl in getOpaqueResultTypeDecl

Mangling and looking up the opaque result type decl
for serialized decls is a fairly expensive
operation. Instead, fallthrough to the request
which will have a cached value set by deserialization.
This shaves ~30ms off the cached completion for:

```swift
import SwiftUI

struct V: View {
  var body: some View {
    Table(#^CC^#
  }
}
```
This commit is contained in:
Hamish Knight
2024-11-04 11:29:55 +00:00
parent 43839ac5fd
commit 152812cc86
7 changed files with 69 additions and 46 deletions

View File

@@ -3887,21 +3887,6 @@ TypeRepr *ValueDecl::getOpaqueResultTypeRepr() const {
}
OpaqueTypeDecl *ValueDecl::getOpaqueResultTypeDecl() const {
if (getOpaqueResultTypeRepr() == nullptr) {
if (!isa<VarDecl>(this) &&
!isa<FuncDecl>(this) &&
!isa<SubscriptDecl>(this))
return nullptr;
auto file = cast<FileUnit>(getDeclContext()->getModuleScopeContext());
// Don't look up when the decl is from source, otherwise a cycle will happen.
if (file->getKind() == FileUnitKind::SerializedAST) {
Mangle::ASTMangler mangler;
auto name = mangler.mangleOpaqueTypeDecl(this);
return file->lookupOpaqueResultType(name);
}
return nullptr;
}
return evaluateOrDefault(getASTContext().evaluator,
OpaqueResultTypeRequest{const_cast<ValueDecl *>(this)},
nullptr);

View File

@@ -385,6 +385,28 @@ void DynamicallyReplacedDeclRequest::cacheResult(ValueDecl *result) const {
decl->getASTContext().evaluator.cacheNonEmptyOutput(*this, std::move(result));
}
//----------------------------------------------------------------------------//
// OpaqueResultTypeRequest caching.
//----------------------------------------------------------------------------//
std::optional<OpaqueTypeDecl *>
OpaqueResultTypeRequest::getCachedResult() const {
auto *decl = std::get<0>(getStorage());
if (decl->LazySemanticInfo.noOpaqueResultType)
return std::optional(nullptr);
return decl->getASTContext().evaluator.getCachedNonEmptyOutput(*this);
}
void OpaqueResultTypeRequest::cacheResult(OpaqueTypeDecl *result) const {
auto *decl = std::get<0>(getStorage());
if (!result) {
decl->LazySemanticInfo.noOpaqueResultType = 1;
return;
}
decl->getASTContext().evaluator.cacheNonEmptyOutput(*this, std::move(result));
}
//----------------------------------------------------------------------------//
// ApplyAccessNoteRequest computation.
//----------------------------------------------------------------------------//