Skip to content

Commit 3c225d3

Browse files
authored
Merge pull request #27856 from jrose-apple/where-do-you-come-from-cottoneye-joe
OpaqueArchetypeSpecializer: inlinable functions are now in this module
2 parents 40e5924 + 6c1afdc commit 3c225d3

File tree

6 files changed

+94
-33
lines changed

6 files changed

+94
-33
lines changed

include/swift/AST/Types.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4876,7 +4876,7 @@ class OpaqueTypeArchetypeType final : public ArchetypeType,
48764876
BEGIN_CAN_TYPE_WRAPPER(OpaqueTypeArchetypeType, ArchetypeType)
48774877
END_CAN_TYPE_WRAPPER(OpaqueTypeArchetypeType, ArchetypeType)
48784878

4879-
enum OpaqueSubstitutionKind {
4879+
enum class OpaqueSubstitutionKind {
48804880
// Don't substitute the opaque type for the underlying type.
48814881
DontSubstitute,
48824882
// Substitute without looking at the type and context.
@@ -4885,7 +4885,7 @@ enum OpaqueSubstitutionKind {
48854885
AlwaysSubstitute,
48864886
// Substitute in the same module into a maximal resilient context.
48874887
// Can be done if the underlying type is accessible from the context we
4888-
// substitute into. Private types cannot be accesses from a different TU.
4888+
// substitute into. Private types cannot be accessed from a different TU.
48894889
SubstituteSameModuleMaximalResilience,
48904890
// Substitute in a different module from the opaque definining decl. Can only
48914891
// be done if the underlying type is public.
@@ -4898,9 +4898,9 @@ enum OpaqueSubstitutionKind {
48984898
/// to their underlying types.
48994899
class ReplaceOpaqueTypesWithUnderlyingTypes {
49004900
public:
4901-
DeclContext *inContext;
4901+
const DeclContext *inContext;
49024902
ResilienceExpansion contextExpansion;
4903-
ReplaceOpaqueTypesWithUnderlyingTypes(DeclContext *inContext,
4903+
ReplaceOpaqueTypesWithUnderlyingTypes(const DeclContext *inContext,
49044904
ResilienceExpansion contextExpansion)
49054905
: inContext(inContext), contextExpansion(contextExpansion) {}
49064906

lib/AST/Type.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,34 +2647,40 @@ ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution(
26472647
}
26482648

26492649
static Type
2650-
substOpaqueTypesWithUnderlyingTypes(Type ty, DeclContext *inContext,
2650+
substOpaqueTypesWithUnderlyingTypes(Type ty, const DeclContext *inContext,
26512651
ResilienceExpansion contextExpansion) {
26522652
ReplaceOpaqueTypesWithUnderlyingTypes replacer(inContext, contextExpansion);
26532653
return ty.subst(replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
26542654
}
26552655

2656-
bool canSubstituteTypeInto(Type ty, DeclContext *dc,
2657-
OpaqueSubstitutionKind kind) {
2656+
/// Checks that \p dc has access to \p ty for the purposes of an opaque
2657+
/// substitution described by \p kind.
2658+
///
2659+
/// This is purely an implementation detail check about whether type metadata
2660+
/// will be accessible. It's not intended to enforce any rules about what
2661+
/// opaque substitutions are or are not allowed.
2662+
static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
2663+
OpaqueSubstitutionKind kind) {
26582664
auto nominal = ty->getAnyNominal();
26592665
if (!nominal)
26602666
return true;
26612667

26622668
switch (kind) {
2663-
case DontSubstitute:
2669+
case OpaqueSubstitutionKind::DontSubstitute:
26642670
return false;
26652671

2666-
case AlwaysSubstitute:
2672+
case OpaqueSubstitutionKind::AlwaysSubstitute:
26672673
return true;
26682674

2669-
case SubstituteSameModuleMaximalResilience:
2675+
case OpaqueSubstitutionKind::SubstituteSameModuleMaximalResilience:
26702676
// In the same file any visibility is okay.
26712677
if (!dc->isModuleContext() &&
26722678
nominal->getDeclContext()->getParentSourceFile() ==
26732679
dc->getParentSourceFile())
26742680
return true;
26752681
return nominal->getEffectiveAccess() > AccessLevel::FilePrivate;
26762682

2677-
case SubstituteNonResilientModule:
2683+
case OpaqueSubstitutionKind::SubstituteNonResilientModule:
26782684
// Can't access types that are not public from a different module.
26792685
return nominal->getEffectiveAccess() > AccessLevel::Internal;
26802686
}
@@ -2729,7 +2735,7 @@ operator()(SubstitutableType *maybeOpaqueType) const {
27292735

27302736
static ProtocolConformanceRef
27312737
substOpaqueTypesWithUnderlyingTypes(ProtocolConformanceRef ref, Type origType,
2732-
DeclContext *inContext,
2738+
const DeclContext *inContext,
27332739
ResilienceExpansion contextExpansion) {
27342740
ReplaceOpaqueTypesWithUnderlyingTypes replacer(inContext, contextExpansion);
27352741
return ref.subst(origType, replacer, replacer,

lib/SIL/SILFunctionType.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2805,8 +2805,9 @@ static bool areABICompatibleParamsOrReturns(SILType a, SILType b,
28052805
if (inFunction) {
28062806
auto opaqueTypesSubsituted = aa;
28072807
auto *dc = inFunction->getDeclContext();
2808-
if (!dc)
2809-
dc = inFunction->getModule().getSwiftModule();
2808+
auto *currentModule = inFunction->getModule().getSwiftModule();
2809+
if (!dc || !dc->isChildContextOf(currentModule))
2810+
dc = currentModule;
28102811
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
28112812
dc, inFunction->getResilienceExpansion());
28122813
if (aa.getASTType()->hasOpaqueArchetype())

lib/SILOptimizer/Transforms/SpecializeOpaqueArchetypes.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,26 @@ llvm::cl::opt<bool>
3131

3232
using namespace swift;
3333

34+
static const DeclContext *
35+
getDeclContextIfInCurrentModule(const SILFunction &fn) {
36+
auto *dc = fn.getDeclContext();
37+
auto *currentModule = fn.getModule().getSwiftModule();
38+
if (dc && dc->isChildContextOf(currentModule))
39+
return dc;
40+
return currentModule;
41+
}
42+
3443
static Type substOpaqueTypesWithUnderlyingTypes(
3544
Type ty, SILFunction *context) {
36-
auto *dc = context->getDeclContext();
37-
if (!dc)
38-
dc = context->getModule().getSwiftModule();
39-
45+
auto *dc = getDeclContextIfInCurrentModule(*context);
4046
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
4147
dc, context->getResilienceExpansion());
4248
return ty.subst(replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
4349
}
4450

4551
static SubstitutionMap
4652
substOpaqueTypesWithUnderlyingTypes(SubstitutionMap map, SILFunction *context) {
47-
auto *dc = context->getDeclContext();
48-
if (!dc)
49-
dc = context->getModule().getSwiftModule();
53+
auto *dc = getDeclContextIfInCurrentModule(*context);
5054
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
5155
dc, context->getResilienceExpansion());
5256
return map.subst(replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
@@ -331,9 +335,7 @@ class OpaqueSpecializerCloner
331335
SILType &Sty = TypeCache[Ty];
332336
if (Sty)
333337
return Sty;
334-
auto *dc = Original.getDeclContext();
335-
if (!dc)
336-
dc = Original.getModule().getSwiftModule();
338+
auto *dc = getDeclContextIfInCurrentModule(Original);
337339

338340
// Apply the opaque types substitution.
339341
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
@@ -351,9 +353,7 @@ class OpaqueSpecializerCloner
351353

352354
ProtocolConformanceRef remapConformance(Type type,
353355
ProtocolConformanceRef conf) {
354-
auto *dc = Original.getDeclContext();
355-
if (!dc)
356-
dc = Original.getModule().getSwiftModule();
356+
auto *dc = getDeclContextIfInCurrentModule(Original);
357357
// Apply the opaque types substitution.
358358
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
359359
dc, Original.getResilienceExpansion());
@@ -504,14 +504,13 @@ class OpaqueArchetypeSpecializer : public SILFunctionTransform {
504504

505505
return ty.findIf([=](Type type) -> bool {
506506
if (auto opaqueTy = type->getAs<OpaqueTypeArchetypeType>()) {
507-
auto *dc = context->getDeclContext();
508-
if (!dc)
509-
dc = context->getModule().getSwiftModule();
510507
auto opaque = opaqueTy->getDecl();
511-
return ReplaceOpaqueTypesWithUnderlyingTypes::
508+
OpaqueSubstitutionKind subKind =
509+
ReplaceOpaqueTypesWithUnderlyingTypes::
512510
shouldPerformSubstitution(opaque,
513511
context->getModule().getSwiftModule(),
514512
context->getResilienceExpansion());
513+
return subKind != OpaqueSubstitutionKind::DontSubstitute;
515514
}
516515
return false;
517516
});

test/SILOptimizer/Inputs/specialize_opaque_type_archetypes_3.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,19 @@ public struct ResilientContainer {
4747
print(x)
4848
}
4949
}
50+
51+
public struct WrapperP2<Wrapped: ExternalP2>: ExternalP2 {
52+
public init(_ wrapped: Wrapped) {}
53+
public func myValue3() -> Int64 { 0 }
54+
}
55+
56+
public func externalResilientWrapper<Wrapped: ExternalP2>(_ wrapped: Wrapped) -> some ExternalP2 {
57+
return WrapperP2(wrapped)
58+
}
59+
60+
@inlinable
61+
@inline(never)
62+
public func inlinableExternalResilientWrapper<Wrapped: ExternalP2>(_ wrapped: Wrapped) -> some ExternalP2 {
63+
return WrapperP2(wrapped)
64+
}
65+

test/SILOptimizer/specialize_opaque_type_archetypes.swift

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
// RUN: %target-swift-frontend -disable-availability-checking %S/Inputs/specialize_opaque_type_archetypes_4.swift -I %t -enable-library-evolution -module-name External3 -emit-module -emit-module-path %t/External3.swiftmodule
55
// RUN: %target-swift-frontend -disable-availability-checking %S/Inputs/specialize_opaque_type_archetypes_3.swift -I %t -enable-library-evolution -module-name External2 -Osize -emit-module -o - | %target-sil-opt -module-name External2 | %FileCheck --check-prefix=RESILIENT %s
66
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -Osize -emit-sil -sil-verify-all %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
7-
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -Osize -emit-sil -sil-verify-all %s | %FileCheck %s
8-
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -enable-library-evolution -Osize -emit-sil -sil-verify-all %s | %FileCheck %s
7+
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -enable-library-evolution -Osize -emit-sil -sil-verify-all %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
98

109
import External
1110
import External2
@@ -546,3 +545,43 @@ func useAbstractFunction<T: P>(_ fn: (Int64) -> T) {}
546545
public func testThinToThick() {
547546
useAbstractFunction(bar)
548547
}
548+
549+
// CHECK-LABEL: sil @$s1A19rdar56410009_normalyyF
550+
public func rdar56410009_normal() {
551+
// CHECK: [[EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF
552+
// CHECK: = apply [[EXTERNAL_RESILIENT_WRAPPER]]<@_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸>({{%.+}}, {{%.+}}) : $@convention(thin) <τ_0_0 where τ_0_0 : ExternalP2> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF", 0) 🦸<τ_0_0>
553+
_ = externalResilientWrapper(externalResilient())
554+
} // CHECK: end sil function '$s1A19rdar56410009_normalyyF'
555+
556+
// CHECK-LABEL: sil @$s1A25rdar56410009_inlinedInneryyF
557+
public func rdar56410009_inlinedInner() {
558+
// CHECK: [[EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF
559+
// CHECK: = apply [[EXTERNAL_RESILIENT_WRAPPER]]<Int64>({{%.+}}, {{%.+}}) : $@convention(thin) <τ_0_0 where τ_0_0 : ExternalP2> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF", 0) 🦸<τ_0_0>
560+
_ = externalResilientWrapper(inlinableExternalResilient())
561+
} // CHECK: end sil function '$s1A25rdar56410009_inlinedInneryyF'
562+
563+
// CHECK-LABEL: sil @$s1A25rdar56410009_inlinedOuteryyF
564+
public func rdar56410009_inlinedOuter() {
565+
// CHECK: [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFAA08externalD0QryFQOyQo__Tg5
566+
// CHECK: = apply [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER]]({{%.+}}, {{%.+}}) : $@convention(thin) (@in_guaranteed @_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸) -> @out @_opaqueReturnTypeOf("$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlF", 0) 🦸<@_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸>
567+
_ = inlinableExternalResilientWrapper(externalResilient())
568+
} // CHECK: end sil function '$s1A25rdar56410009_inlinedOuteryyF'
569+
570+
// Specialized from above
571+
// CHECK-LABEL: sil shared [noinline] @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFAA08externalD0QryFQOyQo__Tg5
572+
// CHECK: [[WRAPPER_INIT:%.+]] = function_ref @$s9External29WrapperP2VyACyxGxcfC
573+
// CHECK: = apply [[WRAPPER_INIT]]<@_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸>({{%.+}}, {{%.+}}, {{%.+}}) : $@convention(method) <τ_0_0 where τ_0_0 : ExternalP2> (@in τ_0_0, @thin WrapperP2<τ_0_0>.Type) -> @out WrapperP2<τ_0_0>
574+
// CHECK: end sil function '$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFAA08externalD0QryFQOyQo__Tg5'
575+
576+
// Specialized from below
577+
// CHECK-LABEL: sil shared [noinline] @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFs5Int64V_Tg5
578+
// CHECK: [[WRAPPER_INIT:%.+]] = function_ref @$s9External29WrapperP2VyACyxGxcfC
579+
// CHECK: = apply [[WRAPPER_INIT]]<Int64>({{%.+}}, {{%.+}}, {{%.+}}) : $@convention(method) <τ_0_0 where τ_0_0 : ExternalP2> (@in τ_0_0, @thin WrapperP2<τ_0_0>.Type) -> @out WrapperP2<τ_0_0>
580+
// CHECK: end sil function '$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFs5Int64V_Tg5'
581+
582+
// CHECK-LABEL: sil @$s1A24rdar56410009_inlinedBothyyF
583+
public func rdar56410009_inlinedBoth() {
584+
// CHECK: [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFs5Int64V_Tg5
585+
// CHECK: = apply [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER]]({{%.+}}, {{%.+}}) : $@convention(thin) (Int64) -> @out @_opaqueReturnTypeOf("$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlF", 0) 🦸<Int64>
586+
_ = inlinableExternalResilientWrapper(inlinableExternalResilient())
587+
} // CHECK: end sil function '$s1A24rdar56410009_inlinedBothyyF'

0 commit comments

Comments
 (0)