From 8702bf9e934be03f5e55d67417f0c8fe4ec1b0af Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Mon, 27 Apr 2020 12:25:01 -0700 Subject: [PATCH 1/2] Update code to print conformances if SILPrintGenericSpecializationInfo is true --- include/swift/AST/ProtocolConformanceRef.h | 2 ++ lib/AST/ASTDumper.cpp | 7 +++++++ lib/SIL/IR/SILPrinter.cpp | 11 +++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/swift/AST/ProtocolConformanceRef.h b/include/swift/AST/ProtocolConformanceRef.h index cd11577c060b6..e155092f58db6 100644 --- a/include/swift/AST/ProtocolConformanceRef.h +++ b/include/swift/AST/ProtocolConformanceRef.h @@ -134,6 +134,8 @@ class ProtocolConformanceRef { void dump(llvm::raw_ostream &out, unsigned indent = 0, bool details = true) const; + void print(llvm::raw_ostream &out) const; + bool operator==(ProtocolConformanceRef other) const { return Union == other.Union; } diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index d396bc51d4cd3..6505633a3b5d3 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3331,6 +3331,13 @@ void ProtocolConformanceRef::dump(llvm::raw_ostream &out, unsigned indent, dumpProtocolConformanceRefRec(*this, out, indent, visited); } + +void ProtocolConformanceRef::print(llvm::raw_ostream &out) const { + llvm::SmallPtrSet visited; + dumpProtocolConformanceRefRec(*this, out, 0, visited); + +} + void ProtocolConformance::dump() const { auto &out = llvm::errs(); dump(out); diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index 5cc11c627d055..8bb72433624b5 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -375,7 +375,7 @@ static void printGenericSpecializationInfo( raw_ostream &OS, StringRef Kind, StringRef Name, const GenericSpecializationInformation *SpecializationInfo, SubstitutionMap Subs = { }) { - if (!SpecializationInfo) + if (!SpecializationInfo && Subs.empty()) return; auto PrintSubstitutions = [&](SubstitutionMap Subs) { @@ -384,6 +384,11 @@ static void printGenericSpecializationInfo( [&](Type type) { OS << type; }, [&] { OS << ", "; }); OS << '>'; + OS << " conformances <"; + interleave(Subs.getConformances(), + [&](ProtocolConformanceRef conf) { conf.print(OS); }, + [&] { OS << ", ";}); + OS << '>'; }; OS << "// Generic specialization information for " << Kind << " " << Name; @@ -716,7 +721,9 @@ class SILPrinter : public SILInstructionVisitor { Ctx.printInstructionCallBack(&I); if (SILPrintGenericSpecializationInfo) { if (auto AI = ApplySite::isa(const_cast(&I))) - if (AI.getSpecializationInfo() && AI.getCalleeFunction()) + if ((AI.getSpecializationInfo() || + !AI.getSubstitutionMap().empty()) && + AI.getCalleeFunction()) printGenericSpecializationInfo( PrintState.OS, "call-site", AI.getCalleeFunction()->getName(), AI.getSpecializationInfo(), AI.getSubstitutionMap()); From 01cf738ba8ff9c047da8158e83711772a07dba3d Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Mon, 27 Apr 2020 09:24:15 -0700 Subject: [PATCH 2/2] [5.3] SILCombine: Fix update of substitution map when substituting opened opaque archetypes When performing the substitution of the 'concrete' type that happens to be an opened archetype we need to force the substitution to actually call the conformance remapping function. rdar://62202282 SR-12571 --- include/swift/AST/Type.h | 3 + lib/AST/ProtocolConformance.cpp | 3 +- .../SILCombiner/SILCombinerApplyVisitors.cpp | 3 +- .../sil_combine_concrete_existential.sil | 91 ++++++++++++++++++- 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h index f57c4f8c16ebe..2691d18d461c4 100644 --- a/include/swift/AST/Type.h +++ b/include/swift/AST/Type.h @@ -148,6 +148,9 @@ enum class SubstFlags { DesugarMemberTypes = 0x02, /// Substitute types involving opaque type archetypes. SubstituteOpaqueArchetypes = 0x04, + /// Force substitution of opened archetypes. Normally -- without these flag -- + /// opened archetype conformances are not substituted. + ForceSubstituteOpenedExistentials = 0x08, }; /// Options for performing substitutions into a type. diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp index fdff7adbdefff..74d1d01d9856a 100644 --- a/lib/AST/ProtocolConformance.cpp +++ b/lib/AST/ProtocolConformance.cpp @@ -122,7 +122,8 @@ ProtocolConformanceRef::subst(Type origType, // Opened existentials trivially conform and do not need to go through // substitution map lookup. - if (substType->isOpenedExistential()) + if (substType->isOpenedExistential() && + !options.contains(SubstFlags::ForceSubstituteOpenedExistentials)) return *this; auto *proto = getRequirement(); diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp index 634468033871e..7539481abbe45 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp @@ -859,7 +859,8 @@ SILInstruction *SILCombiner::createApplyWithConcreteType( return CEI.lookupExistentialConformance(proto); } return ProtocolConformanceRef(proto); - }); + }, + SubstFlags::ForceSubstituteOpenedExistentials); } // We need to make sure that we can a) update Apply to use the new args and b) diff --git a/test/SILOptimizer/sil_combine_concrete_existential.sil b/test/SILOptimizer/sil_combine_concrete_existential.sil index fd829d619821b..5264b38cc73ca 100644 --- a/test/SILOptimizer/sil_combine_concrete_existential.sil +++ b/test/SILOptimizer/sil_combine_concrete_existential.sil @@ -1,4 +1,5 @@ -// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all %s -sil-combine | %FileCheck %s +// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all %s -sil-combine -sil-print-generic-specialization-info | %FileCheck %s +// RUN: %target-swift-frontend -O %s -emit-ir // These tests exercise the same SILCombine optimization as // existential_type_propagation.sil, but cover additional corner @@ -615,3 +616,91 @@ bb0(%0 : $*τ_0_0, %1 : $*τ_0_2, %2 : $*τ_0_1): dealloc_stack %5 : $*P1 return %25 : $() } + + +public class MyObject { + deinit + init() +} + +public protocol SubscriptionViewControllerDelegate { } + +public class SubscriptionViewController { + deinit + init() +} + +public protocol ResourceKitProtocol : MyObject { } + +public protocol ResourceKitDelegate { + func subscriptionViewController(for resourceKit: ResourceKitProtocol) +} + +class ViewController : ResourceKitDelegate { + func subscriptionViewController(for resourceKit: ResourceKitProtocol) + deinit + init() +} + +class SubscriptionViewControllerBuilder { + @_hasStorage final let delegate: SubscriptionViewControllerDelegate { get } + init(delegate: SubscriptionViewControllerDelegate) + deinit +} + +extension MyObject : SubscriptionViewControllerDelegate { } + +// Make sure that we correctly update the substitution map of the apply. +// To satisfy ``τ_0_0 : SubscriptionViewControllerDelegate`` the updated +// substitution map of +// apply %10<$@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol> +// needs to contain the concrete conformance +// ``(normal_conformance type=NSObject protocol=SubscriptionViewControllerDelegate)`` +// not ``(abstract_conformance protocol=SubscriptionViewControllerDelegate)`` + +sil @callee2 : $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder + +// CHECK: sil @test_opend_archeype_concrete_conformance_substitution : $@convention(method) (@guaranteed ResourceKitProtocol, @guaranteed ViewController) -> () { +// CHECK: bb0([[ARG:%.*]] : $ResourceKitProtocol, [[ARG2:%.*]] : $ViewController): +// CHECK: [[T1:%.*]] = metatype $@thick SubscriptionViewControllerBuilder.Type +// CHECK: [[T2:%.*]] = open_existential_ref [[ARG]] : $ResourceKitProtocol to $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol +// CHECK: [[T3:%.*]] = alloc_stack $SubscriptionViewControllerDelegate +// CHECK: [[T4:%.*]] = init_existential_addr [[T3]] : $*SubscriptionViewControllerDelegate, $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol +// CHECK: store [[T2]] to [[T4]] : $*@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol +// CHECK: [[T5:%.*]] = function_ref @callee2 : $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder +// CHECK: [[T6:%.*]] = alloc_stack $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol +// CHECK: copy_addr [[T4]] to [initialization] [[T6]] : $*@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol +// CHECK: Generic specialization information for call-site callee2 conformances <(inherited_conformance type=ResourceKitProtocol protocol=SubscriptionViewControllerDelegate +// CHECK: (normal_conformance type=MyObject protocol=SubscriptionViewControllerDelegate))>: +// CHECK: apply [[T5]]<@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol>([[T6]], [[T1]]) + +sil @test_opend_archeype_concrete_conformance_substitution : $@convention(method) (@guaranteed ResourceKitProtocol, @guaranteed ViewController) -> () { +bb0(%0 : $ResourceKitProtocol, %1 : $ViewController): + %4 = metatype $@thick SubscriptionViewControllerBuilder.Type + %5 = open_existential_ref %0 : $ResourceKitProtocol to $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol + %6 = alloc_stack $SubscriptionViewControllerDelegate + %7 = init_existential_addr %6 : $*SubscriptionViewControllerDelegate, $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol + strong_retain %5 : $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol + store %5 to %7 : $*@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol + %10 = function_ref @callee2: $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder + %11 = open_existential_addr mutable_access %6 : $*SubscriptionViewControllerDelegate to $*@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate + %12 = alloc_stack $@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate + copy_addr %11 to [initialization] %12 : $*@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate + %14 = apply %10<@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate>(%12, %4) : $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder + destroy_addr %6 : $*SubscriptionViewControllerDelegate + dealloc_stack %12 : $*@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate + dealloc_stack %6 : $*SubscriptionViewControllerDelegate + strong_release %14 : $SubscriptionViewControllerBuilder + %19 = tuple () + return %19 : $() +} + +sil_vtable SubscriptionViewControllerBuilder {} +sil_vtable SubscriptionViewController {} +sil_vtable ViewController {} +sil_vtable CCCC {} +sil_vtable CC {} +sil_vtable C {} +sil_vtable C_PQ {} +sil_vtable CDefaultStatic {} +sil_vtable MyObject {}