Skip to content

Commit b72f0c9

Browse files
authored
Merge pull request swiftlang#69757 from tshortli/refactor-lazy-type-refinement-contexts
Sema: Expand TypeRefinementContexts lazily for unparsed function bodies
2 parents 8b7a46e + 2aed784 commit b72f0c9

11 files changed

+393
-155
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4541,23 +4541,26 @@ class InitAccessorReferencedVariablesRequest
45414541
bool isCached() const { return true; }
45424542
};
45434543

4544-
/// Expand the children of the type refinement context for the given
4545-
/// declaration.
4544+
/// Expand the children of the given type refinement context.
45464545
class ExpandChildTypeRefinementContextsRequest
45474546
: public SimpleRequest<ExpandChildTypeRefinementContextsRequest,
4548-
bool(Decl *, TypeRefinementContext *),
4549-
RequestFlags::Cached> {
4547+
std::vector<TypeRefinementContext *>(
4548+
TypeRefinementContext *),
4549+
RequestFlags::SeparatelyCached> {
45504550
public:
45514551
using SimpleRequest::SimpleRequest;
45524552

45534553
private:
45544554
friend SimpleRequest;
45554555

4556-
bool evaluate(Evaluator &evaluator, Decl *decl,
4557-
TypeRefinementContext *parentTRC) const;
4556+
std::vector<TypeRefinementContext *>
4557+
evaluate(Evaluator &evaluator, TypeRefinementContext *parentTRC) const;
45584558

45594559
public:
4560+
// Separate caching.
45604561
bool isCached() const { return true; }
4562+
llvm::Optional<std::vector<TypeRefinementContext *>> getCachedResult() const;
4563+
void cacheResult(std::vector<TypeRefinementContext *> children) const;
45614564
};
45624565

45634566
class SerializeAttrGenericSignatureRequest

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,8 @@ SWIFT_REQUEST(TypeChecker, InitAccessorReferencedVariablesRequest,
513513
ArrayRef<Identifier>),
514514
Cached, NoLocationInfo)
515515
SWIFT_REQUEST(TypeChecker, ExpandChildTypeRefinementContextsRequest,
516-
bool(Decl *, TypeRefinementContext *),
517-
Cached, NoLocationInfo)
516+
std::vector<TypeRefinementContext *>(TypeRefinementContext *),
517+
SeparatelyCached, NoLocationInfo)
518518
SWIFT_REQUEST(TypeChecker, SerializeAttrGenericSignatureRequest,
519519
GenericSignature(Decl *, SpecializeAttr *),
520520
SeparatelyCached, NoLocationInfo)

include/swift/AST/TypeRefinementContext.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
9797
};
9898

9999
private:
100+
friend class ExpandChildTypeRefinementContextsRequest;
100101

101102
/// Represents the AST node that introduced a refinement context.
102103
class IntroNode {
@@ -179,6 +180,11 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
179180

180181
std::vector<TypeRefinementContext *> Children;
181182

183+
struct {
184+
/// Whether this node has child nodes that have not yet been expanded.
185+
unsigned needsExpansion : 1;
186+
} LazyInfo = {};
187+
182188
TypeRefinementContext(ASTContext &Ctx, IntroNode Node,
183189
TypeRefinementContext *Parent, SourceRange SrcRange,
184190
const AvailabilityContext &Info,
@@ -240,6 +246,13 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
240246
TypeRefinementContext *Parent,
241247
const AvailabilityContext &Info);
242248

249+
Decl *getDeclOrNull() const {
250+
auto IntroReason = getReason();
251+
if (IntroReason == Reason::Decl || IntroReason == Reason::DeclImplicit)
252+
return getIntroductionNode().getAsDecl();
253+
return nullptr;
254+
}
255+
243256
/// Returns the reason this context was introduced.
244257
Reason getReason() const;
245258

@@ -288,7 +301,13 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
288301
/// Returns the inner-most TypeRefinementContext descendant of this context
289302
/// for the given source location.
290303
TypeRefinementContext *findMostRefinedSubContext(SourceLoc Loc,
291-
SourceManager &SM);
304+
ASTContext &Ctx);
305+
306+
bool getNeedsExpansion() const { return LazyInfo.needsExpansion; }
307+
308+
void setNeedsExpansion(bool needsExpansion) {
309+
LazyInfo.needsExpansion = needsExpansion;
310+
}
292311

293312
SWIFT_DEBUG_DUMPER(dump(SourceManager &SrcMgr));
294313
void dump(raw_ostream &OS, SourceManager &SrcMgr) const;
@@ -300,6 +319,10 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
300319
void simple_display(llvm::raw_ostream &out,
301320
const TypeRefinementContext *trc);
302321

322+
inline SourceLoc extractNearestSourceLoc(const TypeRefinementContext *TRC) {
323+
return TRC->getIntroductionLoc();
324+
}
325+
303326
} // end namespace swift
304327

305328
#endif

lib/AST/TypeRefinementContext.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ TypeRefinementContext::createRoot(SourceFile *SF,
5757
auto charRange = Ctx.SourceMgr.getRangeForBuffer(*SF->getBufferID());
5858
range = SourceRange(charRange.getStart(), charRange.getEnd());
5959
parentContext = parentTRC->findMostRefinedSubContext(
60-
parentExpansion.getStartLoc(), Ctx.SourceMgr);
60+
parentExpansion.getStartLoc(), Ctx);
6161
availabilityContext = parentContext->getAvailabilityInfo();
6262
}
6363
}
@@ -186,29 +186,20 @@ static bool rangeContainsTokenLocWithGeneratedSource(
186186

187187
TypeRefinementContext *
188188
TypeRefinementContext::findMostRefinedSubContext(SourceLoc Loc,
189-
SourceManager &SM) {
189+
ASTContext &Ctx) {
190190
assert(Loc.isValid());
191-
191+
192192
if (SrcRange.isValid() &&
193-
!rangeContainsTokenLocWithGeneratedSource(SM, SrcRange, Loc))
193+
!rangeContainsTokenLocWithGeneratedSource(Ctx.SourceMgr, SrcRange, Loc))
194194
return nullptr;
195195

196-
// If this context is for a declaration, ensure that we've expanded the
197-
// children of the declaration.
198-
if (Node.getReason() == Reason::Decl ||
199-
Node.getReason() == Reason::DeclImplicit) {
200-
if (auto decl = Node.getAsDecl()) {
201-
ASTContext &ctx = decl->getASTContext();
202-
(void)evaluateOrDefault(
203-
ctx.evaluator, ExpandChildTypeRefinementContextsRequest{decl, this},
204-
false);
205-
}
206-
}
196+
auto expandedChildren = evaluateOrDefault(
197+
Ctx.evaluator, ExpandChildTypeRefinementContextsRequest{this}, {});
207198

208199
// For the moment, we perform a linear search here, but we can and should
209200
// do something more efficient.
210-
for (TypeRefinementContext *Child : Children) {
211-
if (auto *Found = Child->findMostRefinedSubContext(Loc, SM)) {
201+
for (TypeRefinementContext *Child : expandedChildren) {
202+
if (auto *Found = Child->findMostRefinedSubContext(Loc, Ctx)) {
212203
return Found;
213204
}
214205
}
@@ -433,3 +424,18 @@ void swift::simple_display(
433424
llvm::raw_ostream &out, const TypeRefinementContext *trc) {
434425
out << "TRC @" << trc;
435426
}
427+
428+
llvm::Optional<std::vector<TypeRefinementContext *>>
429+
ExpandChildTypeRefinementContextsRequest::getCachedResult() const {
430+
auto *TRC = std::get<0>(getStorage());
431+
if (TRC->getNeedsExpansion())
432+
return llvm::None;
433+
return TRC->Children;
434+
}
435+
436+
void ExpandChildTypeRefinementContextsRequest::cacheResult(
437+
std::vector<TypeRefinementContext *> children) const {
438+
auto *TRC = std::get<0>(getStorage());
439+
TRC->Children = children;
440+
TRC->setNeedsExpansion(false);
441+
}

0 commit comments

Comments
 (0)