-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Cache ConformanceAccessPaths in GSB::EquivalenceClass for big wins #18597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -829,6 +829,10 @@ ConformanceAccessPath GenericSignature::getConformanceAccessPath( | |
type, | ||
ArchetypeResolutionKind::CompleteWellFormed); | ||
|
||
auto cached = equivClass->conformanceAccessPathCache.find(protocol); | ||
if (cached != equivClass->conformanceAccessPathCache.end()) | ||
return cached->second; | ||
|
||
// Dig out the conformance of this type to the given protocol, because we | ||
// want its requirement source. | ||
auto conforms = equivClass->conformsTo.find(protocol); | ||
|
@@ -840,11 +844,12 @@ ConformanceAccessPath GenericSignature::getConformanceAccessPath( | |
|
||
// Local function to construct the conformance access path from the | ||
// requirement. | ||
std::function<void(ArrayRef<Requirement>, const RequirementSource *, | ||
ProtocolDecl *, Type, ProtocolDecl *)> buildPath; | ||
buildPath = [&](ArrayRef<Requirement> reqs, const RequirementSource *source, | ||
ProtocolDecl *conformingProto, Type rootType, | ||
ProtocolDecl *requirementSignatureProto) { | ||
llvm::function_ref<void(ArrayRef<Requirement>, const RequirementSource *, | ||
ProtocolDecl *, Type, ProtocolDecl *)> buildPath; | ||
auto buildPathLambda = [&](ArrayRef<Requirement> reqs, | ||
const RequirementSource *source, | ||
ProtocolDecl *conformingProto, Type rootType, | ||
ProtocolDecl *requirementSignatureProto) { | ||
// Each protocol requirement is a step along the path. | ||
if (source->isProtocolRequirement()) { | ||
// If we're expanding for a protocol that had no requirement signature | ||
|
@@ -976,6 +981,7 @@ ConformanceAccessPath GenericSignature::getConformanceAccessPath( | |
// Add the root of the path, which starts at this explicit requirement. | ||
path.path.push_back({rootType, conformingProto}); | ||
}; | ||
buildPath = buildPathLambda; | ||
|
||
// Canonicalize the root type. | ||
auto source = getBestRequirementSource(conforms->second); | ||
|
@@ -985,6 +991,7 @@ ConformanceAccessPath GenericSignature::getConformanceAccessPath( | |
buildPath(getRequirements(), source, protocol, rootType, nullptr); | ||
|
||
// Return the path; we're done! | ||
equivClass->conformanceAccessPathCache[protocol] = path; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're caching these instead of building them on-demand, can we reasonably return them by reference? Or make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That seems sensible too. |
||
return path; | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the purpose of binding
buildPath
specifically as afunction_ref
here.Oh, I guess it uses itself recursively? Well,
function_ref
is better thanstd::function
, at least....should this just be hoisted to file scope? This function is huge, and it mostly relies on its parameters, not captures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would probably work too. I didn't want to modify code I didn't understand too much, but the allocation was bothering me.