Merge remote-tracking branch 'origin/main' into rebranch

This commit is contained in:
swift-ci
2022-08-09 20:55:09 -07:00
12 changed files with 68 additions and 81 deletions

View File

@@ -49,7 +49,7 @@ thunk helpers" sometimes seen in Swift backtraces come from.)
Broadly, an "access path" is a list of "accesses" which must be chained together
to compute some output from an input. For instance, the generics system has a
type called a `ConformanceAccessPath` which explains how to, for example,
type called a `ConformancePath` which explains how to, for example,
walk from `T: Collection` to `T: Sequence` to `T.Iterator: IteratorProtocol`.
There are several different kinds of "access path" in different parts of the compiler,
but they all follow this basic theme.

View File

@@ -25,7 +25,7 @@ class NamedDecl;
namespace swift {
class AbstractClosureExpr;
class ConformanceAccessPath;
class ConformancePath;
class RootProtocolConformance;
namespace Mangle {
@@ -560,7 +560,7 @@ protected:
void appendConcreteProtocolConformance(
const ProtocolConformance *conformance,
GenericSignature sig);
void appendDependentProtocolConformance(const ConformanceAccessPath &path,
void appendDependentProtocolConformance(const ConformancePath &path,
GenericSignature sig);
void appendOpParamForLayoutConstraint(LayoutConstraint Layout);

View File

@@ -70,7 +70,7 @@ namespace rewriting {
/// \c Sequence conformance of \c C (because \c Collection inherits
/// \c Sequence). Finally, it extracts the conformance of the associated type
/// \c Iterator to \c IteratorProtocol from the \c Sequence protocol.
class ConformanceAccessPath {
class ConformancePath {
public:
/// An entry in the conformance access path, which is described by the
/// dependent type on which the conformance is stated as the protocol to
@@ -80,7 +80,7 @@ public:
private:
ArrayRef<Entry> path;
ConformanceAccessPath(ArrayRef<Entry> path) : path(path) {}
ConformancePath(ArrayRef<Entry> path) : path(path) {}
friend class GenericSignatureImpl;
friend class rewriting::RequirementMachine;
@@ -398,20 +398,20 @@ public:
/// signature.
bool isValidTypeParameter(Type type) const;
/// Retrieve the conformance access path used to extract the conformance of
/// Retrieve the conformance path used to extract the conformance of
/// interface \c type to the given \c protocol.
///
/// \param type The interface type whose conformance access path is to be
/// \param type The type parameter whose conformance path is to be
/// queried.
/// \param protocol A protocol to which \c type conforms.
///
/// \returns the conformance access path that starts at a requirement of
/// \returns the conformance path that starts at a requirement of
/// this generic signature and ends at the conformance that makes \c type
/// conform to \c protocol.
///
/// \seealso ConformanceAccessPath
ConformanceAccessPath getConformanceAccessPath(Type type,
ProtocolDecl *protocol) const;
/// \seealso ConformancePath
ConformancePath getConformancePath(Type type,
ProtocolDecl *protocol) const;
/// Lookup a nested type with the given name within this type parameter.
TypeDecl *lookupNestedType(Type type, Identifier name) const;

View File

@@ -230,16 +230,8 @@ FRONTEND_STATISTIC(Sema, NumRequirementMachineCompletionSteps)
/// Number of new rules added by concrete term unification.
FRONTEND_STATISTIC(Sema, NumRequirementMachineUnifiedConcreteTerms)
/// Number of generic signature builders constructed. Rough proxy for
/// amount of work the GSB does analyzing type signatures.
FRONTEND_STATISTIC(Sema, NumGenericSignatureBuilders)
/// Number of steps in the GSB's redundant requirements algorithm, which is in
/// the worst-case exponential.
FRONTEND_STATISTIC(Sema, NumRedundantRequirementSteps)
/// Number of conformance access paths we had to compute.
FRONTEND_STATISTIC(Sema, NumConformanceAccessPathsRecorded)
/// Number of conformance paths we had to compute.
FRONTEND_STATISTIC(Sema, NumConformancePathsRecorded)
/// Number of lazy requirement signatures registered.
FRONTEND_STATISTIC(Sema, NumLazyRequirementSignatures)

View File

@@ -3357,9 +3357,9 @@ void ASTMangler::appendProtocolConformanceRef(
}
/// Retrieve the index of the conformance requirement indicated by the
/// conformance access path entry within the given set of requirements.
/// conformance path entry within the given set of requirements.
static unsigned conformanceRequirementIndex(
const ConformanceAccessPath::Entry &entry,
const ConformancePath::Entry &entry,
ArrayRef<Requirement> requirements) {
unsigned result = 0;
for (const auto &req : requirements) {
@@ -3377,7 +3377,7 @@ static unsigned conformanceRequirementIndex(
}
void ASTMangler::appendDependentProtocolConformance(
const ConformanceAccessPath &path,
const ConformancePath &path,
GenericSignature sig) {
ProtocolDecl *currentProtocol = nullptr;
for (const auto &entry : path) {
@@ -3441,19 +3441,19 @@ void ASTMangler::appendAnyProtocolConformance(
if (conformingType->isTypeParameter()) {
assert(genericSig && "Need a generic signature to resolve conformance");
auto path = genericSig->getConformanceAccessPath(conformingType,
conformance.getAbstract());
auto path = genericSig->getConformancePath(conformingType,
conformance.getAbstract());
appendDependentProtocolConformance(path, genericSig);
} else if (auto opaqueType = conformingType->getAs<OpaqueTypeArchetypeType>()) {
GenericSignature opaqueSignature =
opaqueType->getDecl()->getOpaqueInterfaceGenericSignature();
ConformanceAccessPath conformanceAccessPath =
opaqueSignature->getConformanceAccessPath(
ConformancePath conformancePath =
opaqueSignature->getConformancePath(
opaqueType->getInterfaceType(),
conformance.getAbstract());
// Append the conformance access path with the signature of the opaque type.
appendDependentProtocolConformance(conformanceAccessPath, opaqueSignature);
// Append the conformance path with the signature of the opaque type.
appendDependentProtocolConformance(conformancePath, opaqueSignature);
appendType(conformingType, genericSig);
appendOperator("HO");
} else {

View File

@@ -29,7 +29,7 @@
using namespace swift;
void ConformanceAccessPath::print(raw_ostream &out) const {
void ConformancePath::print(raw_ostream &out) const {
llvm::interleave(
begin(), end(),
[&](const Entry &entry) {
@@ -39,7 +39,7 @@ void ConformanceAccessPath::print(raw_ostream &out) const {
[&] { out << " -> "; });
}
void ConformanceAccessPath::dump() const {
void ConformancePath::dump() const {
print(llvm::errs());
llvm::errs() << "\n";
}
@@ -475,10 +475,10 @@ CanGenericSignature::getGenericParams() const {
return {base, params.size()};
}
ConformanceAccessPath
GenericSignatureImpl::getConformanceAccessPath(Type type,
ProtocolDecl *protocol) const {
return getRequirementMachine()->getConformanceAccessPath(type, protocol);
ConformancePath
GenericSignatureImpl::getConformancePath(Type type,
ProtocolDecl *protocol) const {
return getRequirementMachine()->getConformancePath(type, protocol);
}
TypeDecl *

View File

@@ -28,7 +28,7 @@
// arbitrary type, not just a type parameter, and recursively transfozms the
// type parameters it contains, if any.
//
// Also, getConformanceAccessPath() is another one-off operation.
// Also, getConformancePath() is another one-off operation.
//
//===----------------------------------------------------------------------===//
@@ -469,7 +469,7 @@ bool RequirementMachine::isValidTypeParameter(Type type) const {
return (prefix == term);
}
/// Retrieve the conformance access path used to extract the conformance of
/// Retrieve the conformance path used to extract the conformance of
/// interface \c type to the given \c protocol.
///
/// \param type The interface type whose conformance access path is to be
@@ -480,10 +480,10 @@ bool RequirementMachine::isValidTypeParameter(Type type) const {
/// this generic signature and ends at the conformance that makes \c type
/// conform to \c protocol.
///
/// \seealso ConformanceAccessPath
ConformanceAccessPath
RequirementMachine::getConformanceAccessPath(Type type,
ProtocolDecl *protocol) {
/// \seealso ConformancePath
ConformancePath
RequirementMachine::getConformancePath(Type type,
ProtocolDecl *protocol) {
assert(type->isTypeParameter());
auto mutTerm = Context.getMutableTermForType(type->getCanonicalType(),
@@ -505,9 +505,9 @@ RequirementMachine::getConformanceAccessPath(Type type,
auto term = Term::get(mutTerm, Context);
// Check if we've already cached the result before doing anything else.
auto found = ConformanceAccessPaths.find(
auto found = ConformancePaths.find(
std::make_pair(term, protocol));
if (found != ConformanceAccessPaths.end()) {
if (found != ConformancePaths.end()) {
return found->second;
}
@@ -516,25 +516,25 @@ RequirementMachine::getConformanceAccessPath(Type type,
FrontendStatsTracer tracer(Stats, "get-conformance-access-path");
auto recordPath = [&](Term term, ProtocolDecl *proto,
ConformanceAccessPath path) {
ConformancePath path) {
// Add the path to the buffer.
CurrentConformanceAccessPaths.emplace_back(term, path);
CurrentConformancePaths.emplace_back(term, path);
// Add the path to the map.
auto key = std::make_pair(term, proto);
auto inserted = ConformanceAccessPaths.insert(
auto inserted = ConformancePaths.insert(
std::make_pair(key, path));
assert(inserted.second);
(void) inserted;
if (Stats)
++Stats->getFrontendCounters().NumConformanceAccessPathsRecorded;
++Stats->getFrontendCounters().NumConformancePathsRecorded;
};
// 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
// add them to the buffer.
if (ConformanceAccessPaths.empty()) {
if (ConformancePaths.empty()) {
for (const auto &req : Sig.getRequirements()) {
// We only care about conformance requirements.
if (req.getKind() != RequirementKind::Conformance)
@@ -543,9 +543,9 @@ RequirementMachine::getConformanceAccessPath(Type type,
auto rootType = CanType(req.getFirstType());
auto *rootProto = req.getProtocolDecl();
ConformanceAccessPath::Entry root(rootType, rootProto);
ArrayRef<ConformanceAccessPath::Entry> path(root);
ConformanceAccessPath result(ctx.AllocateCopy(path));
ConformancePath::Entry root(rootType, rootProto);
ArrayRef<ConformancePath::Entry> path(root);
ConformancePath result(ctx.AllocateCopy(path));
auto mutTerm = Context.getMutableTermForType(rootType, nullptr);
System.simplify(mutTerm);
@@ -555,17 +555,17 @@ RequirementMachine::getConformanceAccessPath(Type type,
}
}
// We enumerate conformance access paths in shortlex order until we find the
// We enumerate conformance paths in shortlex order until we find the
// path whose corresponding type reduces to the one we are looking for.
while (true) {
auto found = ConformanceAccessPaths.find(
auto found = ConformancePaths.find(
std::make_pair(term, protocol));
if (found != ConformanceAccessPaths.end()) {
if (found != ConformancePaths.end()) {
return found->second;
}
if (CurrentConformanceAccessPaths.empty()) {
llvm::errs() << "Failed to find conformance access path for ";
if (CurrentConformancePaths.empty()) {
llvm::errs() << "Failed to find conformance path for ";
llvm::errs() << type << " (" << term << ")" << " : ";
llvm::errs() << protocol->getName() << ":\n";
type.dump(llvm::errs());
@@ -574,18 +574,18 @@ RequirementMachine::getConformanceAccessPath(Type type,
abort();
}
// The buffer consists of all conformance access paths of length N.
// The buffer consists of all conformance paths of length N.
// Swap it out with an empty buffer, and fill it with all paths of
// length N+1.
std::vector<std::pair<Term, ConformanceAccessPath>> oldPaths;
std::swap(CurrentConformanceAccessPaths, oldPaths);
std::vector<std::pair<Term, ConformancePath>> oldPaths;
std::swap(CurrentConformancePaths, oldPaths);
for (const auto &pair : oldPaths) {
const auto &lastElt = pair.second.back();
auto *lastProto = lastElt.second;
// A copy of the current path, populated as needed.
SmallVector<ConformanceAccessPath::Entry, 4> entries;
SmallVector<ConformancePath::Entry, 4> entries;
auto reqs = lastProto->getRequirementSignature().getRequirements();
for (const auto &req : reqs) {
@@ -607,7 +607,7 @@ RequirementMachine::getConformanceAccessPath(Type type,
// don't add it to the buffer. Note that because we iterate over
// conformance access paths in shortlex order, the existing
// conformance access path is shorter than the one we found just now.
if (ConformanceAccessPaths.count(
if (ConformancePaths.count(
std::make_pair(nextTerm, nextProto)))
continue;
@@ -620,7 +620,7 @@ RequirementMachine::getConformanceAccessPath(Type type,
// Add the next entry.
entries.emplace_back(nextSubjectType, nextProto);
ConformanceAccessPath result = ctx.AllocateCopy(entries);
ConformancePath result = ctx.AllocateCopy(entries);
entries.pop_back();
recordPath(nextTerm, nextProto, result);

View File

@@ -565,8 +565,8 @@ void RequirementMachine::dump(llvm::raw_ostream &out) const {
System.dump(out);
Map.dump(out);
out << "Conformance access paths: {\n";
for (auto pair : ConformanceAccessPaths) {
out << "Conformance paths: {\n";
for (auto pair : ConformancePaths) {
out << "- " << pair.first.first << " : ";
out << pair.first.second->getName() << " => ";
pair.second.print(out);

View File

@@ -71,16 +71,15 @@ class RequirementMachine final {
UnifiedStatsReporter *Stats;
/// All conformance access paths computed so far.
/// All conformance paths computed so far.
llvm::DenseMap<std::pair<Term, ProtocolDecl *>,
ConformanceAccessPath> ConformanceAccessPaths;
ConformancePath> ConformancePaths;
/// Conformance access paths computed during the last round. All elements
/// have the same length. If a conformance access path of greater length
/// is requested, we refill CurrentConformanceAccessPaths with all paths of
/// length N+1, and add them to the ConformanceAccessPaths map.
std::vector<std::pair<Term, ConformanceAccessPath>>
CurrentConformanceAccessPaths;
/// is requested, we refill CurrentConformancePaths with all paths of
/// length N+1, and add them to the ConformancePaths map.
std::vector<std::pair<Term, ConformancePath>> CurrentConformancePaths;
explicit RequirementMachine(RewriteContext &rewriteCtx);
@@ -158,8 +157,7 @@ public:
Type getReducedType(Type type,
TypeArrayView<GenericTypeParamType> genericParams) const;
bool isValidTypeParameter(Type type) const;
ConformanceAccessPath getConformanceAccessPath(Type type,
ProtocolDecl *protocol);
ConformancePath getConformancePath(Type type, ProtocolDecl *protocol);
TypeDecl *lookupNestedType(Type depType, Identifier name) const;
llvm::DenseMap<const ProtocolDecl *, RequirementSignature>

View File

@@ -482,7 +482,7 @@ RequirementMachine::computeMinimalGenericSignature(
auto sig = GenericSignature::get(getGenericParams(), reqs);
// Remember the signature for generic signature queries. In particular,
// getConformanceAccessPath() needs the current requirement machine's
// getConformancePath() needs the current requirement machine's
// generic signature.
Sig = sig.getCanonicalSignature();

View File

@@ -367,11 +367,10 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const {
return ProtocolConformanceRef::forMissingOrInvalid(substType, proto);
}
auto accessPath =
genericSig->getConformanceAccessPath(type, proto);
auto path = genericSig->getConformancePath(type, proto);
ProtocolConformanceRef conformance;
for (const auto &step : accessPath) {
for (const auto &step : path) {
// For the first step, grab the initial conformance.
if (conformance.isInvalid()) {
if (auto initialConformance = getSignatureConformance(

View File

@@ -191,8 +191,7 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF,
auto environment = archetype->getGenericEnvironment();
// Otherwise, ask the generic signature for the environment for the best
// path to the conformance.
// Otherwise, ask the generic signature for the best path to the conformance.
// TODO: this isn't necessarily optimal if the direct conformance isn't
// concretely available; we really ought to be comparing the full paths
// to this conformance from concrete sources.
@@ -200,8 +199,7 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF,
auto signature = environment->getGenericSignature().getCanonicalSignature();
auto archetypeDepType = archetype->getInterfaceType();
auto astPath = signature->getConformanceAccessPath(archetypeDepType,
protocol);
auto astPath = signature->getConformancePath(archetypeDepType, protocol);
auto i = astPath.begin(), e = astPath.end();
assert(i != e && "empty path!");