Skip to content

Eliminate "sorting" of DeclContext-local protocols / conformances. #22659

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,17 +541,13 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
///
/// \param diagnostics If non-null, will be populated with the set of
/// diagnostics that should be emitted for this declaration context.
///
/// \param sorted Whether to sort the results in a canonical order.
///
/// FIXME: This likely makes more sense on IterableDeclContext or
/// something similar.
SmallVector<ProtocolDecl *, 2>
getLocalProtocols(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All,
SmallVectorImpl<ConformanceDiagnostic> *diagnostics
= nullptr,
bool sorted = false) const;
= nullptr) const;

/// Retrieve the set of protocol conformances associated with this
/// declaration context.
Expand All @@ -561,16 +557,13 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
/// \param diagnostics If non-null, will be populated with the set of
/// diagnostics that should be emitted for this declaration context.
///
/// \param sorted Whether to sort the results in a canonical order.
///
/// FIXME: This likely makes more sense on IterableDeclContext or
/// something similar.
SmallVector<ProtocolConformance *, 2>
getLocalConformances(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All,
SmallVectorImpl<ConformanceDiagnostic> *diagnostics
= nullptr,
bool sorted = false) const;
= nullptr) const;

/// Retrieve the syntactic depth of this declaration context, i.e.,
/// the number of non-module-scoped contexts.
Expand Down
17 changes: 2 additions & 15 deletions lib/AST/ProtocolConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1381,8 +1381,7 @@ NominalTypeDecl::getSatisfiedProtocolRequirementsForMember(
SmallVector<ProtocolDecl *, 2>
DeclContext::getLocalProtocols(
ConformanceLookupKind lookupKind,
SmallVectorImpl<ConformanceDiagnostic> *diagnostics,
bool sorted) const
SmallVectorImpl<ConformanceDiagnostic> *diagnostics) const
{
SmallVector<ProtocolDecl *, 2> result;

Expand All @@ -1401,19 +1400,13 @@ DeclContext::getLocalProtocols(
nullptr,
diagnostics);

// Sort if required.
if (sorted) {
llvm::array_pod_sort(result.begin(), result.end(), TypeDecl::compare);
}

return result;
}

SmallVector<ProtocolConformance *, 2>
DeclContext::getLocalConformances(
ConformanceLookupKind lookupKind,
SmallVectorImpl<ConformanceDiagnostic> *diagnostics,
bool sorted) const
SmallVectorImpl<ConformanceDiagnostic> *diagnostics) const
{
SmallVector<ProtocolConformance *, 2> result;

Expand All @@ -1439,12 +1432,6 @@ DeclContext::getLocalConformances(
&result,
diagnostics);

// If requested, sort the results.
if (sorted) {
llvm::array_pod_sort(result.begin(), result.end(),
&ConformanceLookupTable::compareProtocolConformances);
}

return result;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ namespace {
llvm::SmallSetVector<ProtocolDecl *, 2> protocols;
for (auto conformance : dc->getLocalConformances(
ConformanceLookupKind::OnlyExplicit,
nullptr, /*sorted=*/true)) {
nullptr)) {
ProtocolDecl *proto = conformance->getProtocol();
getObjCProtocols(proto, protocols);
}
Expand Down
3 changes: 1 addition & 2 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,8 +880,7 @@ IRGenModule::getConstantReferenceForProtocolDescriptor(ProtocolDecl *proto) {

void IRGenModule::addLazyConformances(DeclContext *dc) {
for (const ProtocolConformance *conf :
dc->getLocalConformances(ConformanceLookupKind::All,
nullptr, /*sorted=*/true)) {
dc->getLocalConformances(ConformanceLookupKind::All, nullptr)) {
IRGen.addLazyWitnessTable(conf);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,7 @@ void SILGenModule::emitExternalDefinition(Decl *d) {
// Emit witness tables.
auto nom = cast<NominalTypeDecl>(d);
for (auto c : nom->getLocalConformances(ConformanceLookupKind::All,
nullptr, /*sorted=*/true)) {
nullptr)) {
auto *proto = c->getProtocol();
if (Lowering::TypeConverter::protocolRequiresWitnessTable(proto) &&
isa<NormalProtocolConformance>(c) &&
Expand Down
5 changes: 2 additions & 3 deletions lib/SILGen/SILGenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,8 +968,7 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
// Emit witness tables for conformances of concrete types. Protocol types
// are existential and do not have witness tables.
for (auto *conformance : theType->getLocalConformances(
ConformanceLookupKind::All,
nullptr, /*sorted=*/true)) {
ConformanceLookupKind::All, nullptr)) {
if (conformance->isComplete() &&
isa<NormalProtocolConformance>(conformance))
SGM.getWitnessTable(conformance);
Expand Down Expand Up @@ -1070,7 +1069,7 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
// extension.
for (auto *conformance : e->getLocalConformances(
ConformanceLookupKind::All,
nullptr, /*sorted=*/true)) {
nullptr)) {
if (conformance->isComplete() &&
isa<NormalProtocolConformance>(conformance))
SGM.getWitnessTable(conformance);
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5020,8 +5020,7 @@ void TypeChecker::checkConformancesInContext(DeclContext *dc,
// Check each of the conformances associated with this context.
SmallVector<ConformanceDiagnostic, 4> diagnostics;
auto conformances = dc->getLocalConformances(ConformanceLookupKind::All,
&diagnostics,
/*sorted=*/true);
&diagnostics);

// The conformance checker bundle that checks all conformances in the context.
MultiConformanceChecker groupChecker(*this);
Expand Down
12 changes: 4 additions & 8 deletions lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2771,8 +2771,7 @@ void Serializer::writeDecl(const Decl *D) {
(void)addDeclRef(baseNominal);

auto conformances = extension->getLocalConformances(
ConformanceLookupKind::All,
nullptr, /*sorted=*/true);
ConformanceLookupKind::All, nullptr);

SmallVector<TypeID, 8> inheritedAndDependencyTypes;
for (auto inherited : extension->getInherited()) {
Expand Down Expand Up @@ -3027,8 +3026,7 @@ void Serializer::writeDecl(const Decl *D) {
auto contextID = addDeclContextRef(theStruct->getDeclContext());

auto conformances = theStruct->getLocalConformances(
ConformanceLookupKind::All,
nullptr, /*sorted=*/true);
ConformanceLookupKind::All, nullptr);

SmallVector<TypeID, 4> inheritedTypes;
for (auto inherited : theStruct->getInherited()) {
Expand Down Expand Up @@ -3065,8 +3063,7 @@ void Serializer::writeDecl(const Decl *D) {
auto contextID = addDeclContextRef(theEnum->getDeclContext());

auto conformances = theEnum->getLocalConformances(
ConformanceLookupKind::All,
nullptr, /*sorted=*/true);
ConformanceLookupKind::All, nullptr);

SmallVector<TypeID, 4> inheritedAndDependencyTypes;
for (auto inherited : theEnum->getInherited()) {
Expand Down Expand Up @@ -3120,8 +3117,7 @@ void Serializer::writeDecl(const Decl *D) {
auto contextID = addDeclContextRef(theClass->getDeclContext());

auto conformances = theClass->getLocalConformances(
ConformanceLookupKind::All,
nullptr, /*sorted=*/true);
ConformanceLookupKind::All, nullptr);

SmallVector<TypeID, 4> inheritedTypes;
for (auto inherited : theClass->getInherited()) {
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/deserialize-clang-importer-witness-tables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public func foo(line: String) {
// from the default argument expression passed to `RegEx(pattern:options:)`
// below. Ensure that a local copy of the definition was deserialized
// and lowered to IR.
// CHECK-LABEL: define {{.*}} i8** @"$sSo26NSRegularExpressionOptionsVABSQSCWl"()
// CHECK-LABEL: define {{.*}} void @"$sSo26NSRegularExpressionOptionsVs10SetAlgebraSCsACPxycfCTW"
// CHECK-LABEL: define {{.*}} i8** @"$sSo26NSRegularExpressionOptionsVABSQSCWl"()
let versionRegex = try! RegEx(pattern: "Apple")
_ = versionRegex.firstMatch(in: line)
}
12 changes: 6 additions & 6 deletions test/SILGen/synthesized_conformance_class.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ final class Final<T> {
// CHECK: deinit
// CHECK: enum CodingKeys : CodingKey {
// CHECK: case x
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Final<T>.CodingKeys, _ b: Final<T>.CodingKeys) -> Bool
// CHECK: var hashValue: Int { get }
// CHECK: func hash(into hasher: inout Hasher)
// CHECK: var stringValue: String { get }
// CHECK: init?(stringValue: String)
// CHECK: var intValue: Int? { get }
// CHECK: init?(intValue: Int)
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Final<T>.CodingKeys, _ b: Final<T>.CodingKeys) -> Bool
// CHECK: var hashValue: Int { get }
// CHECK: func hash(into hasher: inout Hasher)
// CHECK: }
// CHECK: }

Expand All @@ -30,13 +30,13 @@ class Nonfinal<T> {
// CHECK: deinit
// CHECK: enum CodingKeys : CodingKey {
// CHECK: case x
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Nonfinal<T>.CodingKeys, _ b: Nonfinal<T>.CodingKeys) -> Bool
// CHECK: var hashValue: Int { get }
// CHECK: func hash(into hasher: inout Hasher)
// CHECK: var stringValue: String { get }
// CHECK: init?(stringValue: String)
// CHECK: var intValue: Int? { get }
// CHECK: init?(intValue: Int)
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Nonfinal<T>.CodingKeys, _ b: Nonfinal<T>.CodingKeys) -> Bool
// CHECK: var hashValue: Int { get }
// CHECK: func hash(into hasher: inout Hasher)
// CHECK: }
// CHECK: }

Expand Down
8 changes: 4 additions & 4 deletions test/SILGen/synthesized_conformance_struct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ struct Struct<T> {
// CHECK: init(x: T)
// CHECK: enum CodingKeys : CodingKey {
// CHECK: case x
// CHECK: var stringValue: String { get }
// CHECK: init?(stringValue: String)
// CHECK: var intValue: Int? { get }
// CHECK: init?(intValue: Int)
// CHECK-FRAGILE: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Struct<T>.CodingKeys, _ b: Struct<T>.CodingKeys) -> Bool
// CHECK-RESILIENT: static func == (a: Struct<T>.CodingKeys, b: Struct<T>.CodingKeys) -> Bool
// CHECK: var hashValue: Int { get }
// CHECK: func hash(into hasher: inout Hasher)
// CHECK: var stringValue: String { get }
// CHECK: init?(stringValue: String)
// CHECK: var intValue: Int? { get }
// CHECK: init?(intValue: Int)
// CHECK: }
// CHECK: }
// CHECK-LABEL: extension Struct : Equatable where T : Equatable {
Expand Down
8 changes: 4 additions & 4 deletions test/api-digester/Outputs/cake-abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1203,8 +1203,8 @@
"conformances": [
{
"kind": "Conformance",
"name": "Comparable",
"printedName": "Comparable"
"name": "FixedWidthInteger",
"printedName": "FixedWidthInteger"
},
{
"kind": "Conformance",
Expand Down Expand Up @@ -1318,8 +1318,8 @@
},
{
"kind": "Conformance",
"name": "FixedWidthInteger",
"printedName": "FixedWidthInteger"
"name": "Comparable",
"printedName": "Comparable"
},
{
"kind": "Conformance",
Expand Down
8 changes: 4 additions & 4 deletions test/api-digester/Outputs/cake.json
Original file line number Diff line number Diff line change
Expand Up @@ -1092,8 +1092,8 @@
"conformances": [
{
"kind": "Conformance",
"name": "Comparable",
"printedName": "Comparable"
"name": "FixedWidthInteger",
"printedName": "FixedWidthInteger"
},
{
"kind": "Conformance",
Expand Down Expand Up @@ -1216,8 +1216,8 @@
},
{
"kind": "Conformance",
"name": "FixedWidthInteger",
"printedName": "FixedWidthInteger"
"name": "Comparable",
"printedName": "Comparable"
},
{
"kind": "Conformance",
Expand Down