mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
GSB: Add a counter and clean up getConformanceAccessPath() a bit
This commit is contained in:
@@ -224,6 +224,9 @@ FRONTEND_STATISTIC(Sema, NumAccessorBodiesSynthesized)
|
|||||||
/// amount of work the GSB does analyzing type signatures.
|
/// amount of work the GSB does analyzing type signatures.
|
||||||
FRONTEND_STATISTIC(Sema, NumGenericSignatureBuilders)
|
FRONTEND_STATISTIC(Sema, NumGenericSignatureBuilders)
|
||||||
|
|
||||||
|
/// Number of conformance access paths we had to compute.
|
||||||
|
FRONTEND_STATISTIC(Sema, NumConformanceAccessPathsRecorded)
|
||||||
|
|
||||||
/// Number of lazy requirement signatures registered.
|
/// Number of lazy requirement signatures registered.
|
||||||
FRONTEND_STATISTIC(Sema, NumLazyRequirementSignatures)
|
FRONTEND_STATISTIC(Sema, NumLazyRequirementSignatures)
|
||||||
|
|
||||||
|
|||||||
@@ -4145,7 +4145,25 @@ GenericSignatureBuilder::getConformanceAccessPath(Type type,
|
|||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontendStatsTracer(Context.Stats, "get-conformance-access-path");
|
auto *Stats = Context.Stats;
|
||||||
|
|
||||||
|
FrontendStatsTracer(Stats, "get-conformance-access-path");
|
||||||
|
|
||||||
|
auto recordPath = [&](CanType type, ProtocolDecl *proto,
|
||||||
|
ConformanceAccessPath path) {
|
||||||
|
// Add the path to the buffer.
|
||||||
|
Impl->CurrentConformanceAccessPaths.emplace_back(type, path);
|
||||||
|
|
||||||
|
// Add the path to the map.
|
||||||
|
auto key = std::make_pair(type, proto);
|
||||||
|
auto inserted = Impl->ConformanceAccessPaths.insert(
|
||||||
|
std::make_pair(key, path));
|
||||||
|
assert(inserted.second);
|
||||||
|
(void) inserted;
|
||||||
|
|
||||||
|
if (Stats)
|
||||||
|
++Stats->getFrontendCounters().NumConformanceAccessPathsRecorded;
|
||||||
|
};
|
||||||
|
|
||||||
// If this is the first time we're asked to look up a conformance access path,
|
// If this is the first time we're asked to look up a conformance access path,
|
||||||
// visit all of the root conformance requirements in our generic signature and
|
// visit all of the root conformance requirements in our generic signature and
|
||||||
@@ -4163,19 +4181,12 @@ GenericSignatureBuilder::getConformanceAccessPath(Type type,
|
|||||||
ArrayRef<ConformanceAccessPath::Entry> path(root);
|
ArrayRef<ConformanceAccessPath::Entry> path(root);
|
||||||
ConformanceAccessPath result(Context.AllocateCopy(path));
|
ConformanceAccessPath result(Context.AllocateCopy(path));
|
||||||
|
|
||||||
// Add the path to the buffer.
|
recordPath(rootType, rootProto, result);
|
||||||
Impl->CurrentConformanceAccessPaths.emplace_back(rootType, result);
|
|
||||||
|
|
||||||
// Add the path to the map.
|
|
||||||
auto key = std::make_pair(rootType, rootProto);
|
|
||||||
auto inserted = Impl->ConformanceAccessPaths.insert(
|
|
||||||
std::make_pair(key, result));
|
|
||||||
assert(inserted.second);
|
|
||||||
(void) inserted;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We keep going until we find the path we are looking for.
|
// We enumerate conformance access paths in lexshort order until we find the
|
||||||
|
// path whose corresponding type canonicalizes to the one we are looking for.
|
||||||
while (true) {
|
while (true) {
|
||||||
auto found = Impl->ConformanceAccessPaths.find(
|
auto found = Impl->ConformanceAccessPaths.find(
|
||||||
std::make_pair(canType, protocol));
|
std::make_pair(canType, protocol));
|
||||||
@@ -4185,11 +4196,13 @@ GenericSignatureBuilder::getConformanceAccessPath(Type type,
|
|||||||
|
|
||||||
assert(Impl->CurrentConformanceAccessPaths.size() > 0);
|
assert(Impl->CurrentConformanceAccessPaths.size() > 0);
|
||||||
|
|
||||||
// Refill the buffer.
|
// The buffer consists of all conformance access paths of length N.
|
||||||
std::vector<std::pair<CanType, ConformanceAccessPath>> morePaths;
|
// Swap it out with an empty buffer, and fill it with all paths of
|
||||||
|
// length N+1.
|
||||||
|
std::vector<std::pair<CanType, ConformanceAccessPath>> oldPaths;
|
||||||
|
std::swap(Impl->CurrentConformanceAccessPaths, oldPaths);
|
||||||
|
|
||||||
// From each path in the buffer, compute all paths of length plus one.
|
for (const auto &pair : oldPaths) {
|
||||||
for (const auto &pair : Impl->CurrentConformanceAccessPaths) {
|
|
||||||
const auto &lastElt = pair.second.back();
|
const auto &lastElt = pair.second.back();
|
||||||
auto *lastProto = lastElt.second;
|
auto *lastProto = lastElt.second;
|
||||||
|
|
||||||
@@ -4213,12 +4226,12 @@ GenericSignatureBuilder::getConformanceAccessPath(Type type,
|
|||||||
if (!nextCanType->isTypeParameter())
|
if (!nextCanType->isTypeParameter())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check if we already have a conformance access path for this anchor.
|
|
||||||
auto key = std::make_pair(nextCanType, nextProto);
|
|
||||||
|
|
||||||
// If we've already seen a path for this conformance, skip it and
|
// If we've already seen a path for this conformance, skip it and
|
||||||
// don't add it to the buffer.
|
// don't add it to the buffer. Note that because we iterate over
|
||||||
if (Impl->ConformanceAccessPaths.count(key))
|
// conformance access paths in lexshort order, the existing
|
||||||
|
// conformance access path is shorter than the one we found just now.
|
||||||
|
if (Impl->ConformanceAccessPaths.count(
|
||||||
|
std::make_pair(nextCanType, nextProto)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (entries.empty()) {
|
if (entries.empty()) {
|
||||||
@@ -4233,18 +4246,9 @@ GenericSignatureBuilder::getConformanceAccessPath(Type type,
|
|||||||
ConformanceAccessPath result = Context.AllocateCopy(entries);
|
ConformanceAccessPath result = Context.AllocateCopy(entries);
|
||||||
entries.pop_back();
|
entries.pop_back();
|
||||||
|
|
||||||
// Add the path to the buffer.
|
recordPath(nextCanType, nextProto, result);
|
||||||
morePaths.emplace_back(nextCanType, result);
|
|
||||||
|
|
||||||
// Add the path to the map.
|
|
||||||
auto inserted = Impl->ConformanceAccessPaths.insert(
|
|
||||||
std::make_pair(key, result));
|
|
||||||
assert(inserted.second);
|
|
||||||
(void) inserted;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::swap(morePaths, Impl->CurrentConformanceAccessPaths);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user