Skip to content

Commit c964e5b

Browse files
committed
---
yaml --- r: 346730 b: refs/heads/master c: a2df58e h: refs/heads/master
1 parent 0594d22 commit c964e5b

File tree

9 files changed

+144
-78
lines changed

9 files changed

+144
-78
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: e96ddfd9ad678aa489532864ce5aeed1b2398a55
2+
refs/heads/master: a2df58e779d7c909b2e701e190ba483efae4cbbb
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/lib/SIL/SILDeclRef.cpp

Lines changed: 93 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -444,83 +444,114 @@ bool SILDeclRef::isTransparent() const {
444444

445445
/// True if the function should have its body serialized.
446446
IsSerialized_t SILDeclRef::isSerialized() const {
447-
// Native-to-foreign thunks are only referenced from the Objective-C
448-
// method table.
449-
if (isForeign)
450-
return IsNotSerialized;
451-
452447
DeclContext *dc;
453-
if (auto closure = getAbstractClosureExpr())
448+
if (auto closure = getAbstractClosureExpr()) {
454449
dc = closure->getLocalContext();
455-
else {
456-
auto *d = getDecl();
457-
458-
// Default argument generators are serialized if the function was
459-
// type-checked in Swift 4 mode.
460-
if (kind == SILDeclRef::Kind::DefaultArgGenerator) {
461-
auto *afd = cast<AbstractFunctionDecl>(d);
462-
switch (afd->getDefaultArgumentResilienceExpansion()) {
463-
case ResilienceExpansion::Minimal:
464-
return IsSerialized;
465-
case ResilienceExpansion::Maximal:
466-
return IsNotSerialized;
467-
}
450+
451+
// Otherwise, ask the AST if we're inside an @inlinable context.
452+
if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal) {
453+
if (isForeign)
454+
return IsSerializable;
455+
456+
return IsSerialized;
468457
}
469458

470-
// 'read' and 'modify' accessors synthesized on-demand are serialized if
471-
// visible outside the module.
472-
if (auto fn = dyn_cast<FuncDecl>(d))
473-
if (!isClangImported() &&
474-
fn->hasForcedStaticDispatch() &&
475-
fn->getEffectiveAccess() >= AccessLevel::Public)
476-
return IsSerialized;
459+
return IsNotSerialized;
460+
}
477461

478-
dc = getDecl()->getInnermostDeclContext();
462+
if (isIVarInitializerOrDestroyer())
463+
return IsNotSerialized;
479464

480-
// Enum element constructors are serialized if the enum is
481-
// @usableFromInline or public.
482-
if (isEnumElement())
483-
if (d->getEffectiveAccess() >= AccessLevel::Public)
484-
return IsSerialized;
465+
auto *d = getDecl();
485466

486-
// Currying thunks are serialized if referenced from an inlinable
487-
// context -- Sema's semantic checks ensure the serialization of
488-
// such a thunk is valid, since it must in turn reference a public
489-
// symbol, or dispatch via class_method or witness_method.
490-
if (isCurried)
491-
if (d->getEffectiveAccess() >= AccessLevel::Public)
492-
return IsSerializable;
467+
// Default argument generators are serialized if the function was
468+
// type-checked in Swift 4 mode.
469+
if (isDefaultArgGenerator()) {
470+
auto *afd = cast<AbstractFunctionDecl>(d);
471+
switch (afd->getDefaultArgumentResilienceExpansion()) {
472+
case ResilienceExpansion::Minimal:
473+
return IsSerialized;
474+
case ResilienceExpansion::Maximal:
475+
return IsNotSerialized;
476+
}
477+
}
478+
479+
// Stored property initializers are inlinable if the type is explicitly
480+
// marked as @_fixed_layout.
481+
if (isStoredPropertyInitializer()) {
482+
auto *nominal = cast<NominalTypeDecl>(d->getDeclContext());
483+
auto scope =
484+
nominal->getFormalAccessScope(/*useDC=*/nullptr,
485+
/*treatUsableFromInlineAsPublic=*/true);
486+
if (!scope.isPublic())
487+
return IsNotSerialized;
488+
if (nominal->isFormallyResilient())
489+
return IsNotSerialized;
490+
return IsSerialized;
491+
}
493492

494-
if (isForeignToNativeThunk())
493+
// Note: if 'd' is a function, then 'dc' is the function itself, not
494+
// its parent context.
495+
dc = d->getInnermostDeclContext();
496+
497+
// Local functions are serializable if their parent function is
498+
// serializable.
499+
if (d->getDeclContext()->isLocalContext()) {
500+
if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal)
495501
return IsSerializable;
496502

497-
// The allocating entry point for designated initializers are serialized
498-
// if the class is @usableFromInline or public.
499-
if (kind == SILDeclRef::Kind::Allocator) {
500-
auto *ctor = cast<ConstructorDecl>(d);
501-
if (ctor->isDesignatedInit() &&
502-
ctor->getDeclContext()->getSelfClassDecl()) {
503-
if (ctor->getEffectiveAccess() >= AccessLevel::Public &&
504-
!ctor->hasClangNode())
505-
return IsSerialized;
506-
}
507-
}
503+
return IsNotSerialized;
504+
}
508505

509-
// Stored property initializers are inlinable if the type is explicitly
510-
// marked as @_fixed_layout.
511-
if (isStoredPropertyInitializer()) {
512-
auto *nominal = cast<NominalTypeDecl>(d->getDeclContext());
513-
auto scope =
514-
nominal->getFormalAccessScope(/*useDC=*/nullptr,
515-
/*treatUsableFromInlineAsPublic=*/true);
516-
if (!scope.isPublic())
517-
return IsNotSerialized;
518-
if (nominal->isFormallyResilient())
519-
return IsNotSerialized;
506+
// Anything else that is not public is not serializable.
507+
if (d->getEffectiveAccess() < AccessLevel::Public)
508+
return IsNotSerialized;
509+
510+
// 'read' and 'modify' accessors synthesized on-demand are serialized if
511+
// visible outside the module.
512+
if (auto fn = dyn_cast<FuncDecl>(d))
513+
if (!isClangImported() &&
514+
fn->hasForcedStaticDispatch())
520515
return IsSerialized;
516+
517+
// Enum element constructors are serializable if the enum is
518+
// @usableFromInline or public.
519+
if (isEnumElement())
520+
return IsSerializable;
521+
522+
// Currying thunks are serialized if referenced from an inlinable
523+
// context -- Sema's semantic checks ensure the serialization of
524+
// such a thunk is valid, since it must in turn reference a public
525+
// symbol, or dispatch via class_method or witness_method.
526+
if (isCurried)
527+
return IsSerializable;
528+
529+
if (isForeignToNativeThunk())
530+
return IsSerializable;
531+
532+
// The allocating entry point for designated initializers are serialized
533+
// if the class is @usableFromInline or public.
534+
if (kind == SILDeclRef::Kind::Allocator) {
535+
auto *ctor = cast<ConstructorDecl>(d);
536+
if (ctor->isDesignatedInit() &&
537+
ctor->getDeclContext()->getSelfClassDecl()) {
538+
if (!ctor->hasClangNode())
539+
return IsSerialized;
521540
}
522541
}
523542

543+
if (isForeign) {
544+
// @objc thunks for methods are not serializable since they're only
545+
// referenced from the method table.
546+
if (d->getDeclContext()->isTypeContext())
547+
return IsNotSerialized;
548+
549+
// @objc thunks for top-level functions are serializable since they're
550+
// referenced from @convention(c) conversions inside inlinable
551+
// functions.
552+
return IsSerializable;
553+
}
554+
524555
// Declarations imported from Clang modules are serialized if
525556
// referenced from an inlinable context.
526557
if (isClangImported())

trunk/test/ClangImporter/const_and_pure.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ func testit() {
88
normal_function()
99
}
1010

11-
// CHECK: sil [readnone] [clang const_function] @const_function : $@convention(c) () -> ()
12-
// CHECK: sil [readonly] [clang pure_function] @pure_function : $@convention(c) () -> ()
13-
// CHECK: sil [clang normal_function] @normal_function : $@convention(c) () -> ()
11+
// CHECK: sil [serializable] [readnone] [clang const_function] @const_function : $@convention(c) () -> ()
12+
// CHECK: sil [serializable] [readonly] [clang pure_function] @pure_function : $@convention(c) () -> ()
13+
// CHECK: sil [serializable] [clang normal_function] @normal_function : $@convention(c) () -> ()
1414

1515

trunk/test/ClangImporter/static_inline.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// RUN: %FileCheck < %t/static_inline.sil %s
77
// RUN: %target-swift-frontend -parse-as-library -module-name=static_inline -O -emit-ir %t/static_inline.sil -enable-objc-interop -import-objc-header %S/Inputs/static_inline.h | %FileCheck --check-prefix=CHECK-IR %s
88

9-
// CHECK: sil shared [clang c_inline_func] @c_inline_func : $@convention(c) (Int32) -> Int32
9+
// CHECK: sil shared [serializable] [clang c_inline_func] @c_inline_func : $@convention(c) (Int32) -> Int32
1010

1111
// CHECK-IR-LABEL: define{{.*}} i32 @"$s13static_inline6testit1xs5Int32VAE_tF"(i32)
1212
// CHECK-IR: = add {{.*}}, 27

trunk/test/SILGen/cdecl.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func orange(_ x: Int) -> Int {
2121
return x
2222
}
2323

24-
// CHECK-LABEL: sil [thunk] [ossa] @cauliflower : $@convention(c)
24+
// CHECK-LABEL: sil [serializable] [thunk] [ossa] @cauliflower : $@convention(c)
2525
// CHECK: function_ref @$s5cdecl8broccoli{{[_0-9a-zA-Z]*}}F
2626
// CHECK-LABEL: sil [ossa] @$s5cdecl8broccoli{{[_0-9a-zA-Z]*}}F
2727
@_cdecl("cauliflower")

trunk/test/SILGen/inlinable_attribute.swift

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class MyCls {
4343
case c(MySt)
4444
}
4545

46-
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s19inlinable_attribute6MyEnumO1cyAcA0C2StVcACmFTc : $@convention(thin) (@thin MyEnum.Type) -> @owned @callee_guaranteed (MySt) -> MyEnum
46+
// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s19inlinable_attribute6MyEnumO1cyAcA0C2StVcACmFTc : $@convention(thin) (@thin MyEnum.Type) -> @owned @callee_guaranteed (MySt) -> MyEnum
4747

4848
@inlinable public func referencesMyEnum() {
4949
_ = MyEnum.c
@@ -135,15 +135,50 @@ private class PrivateDerivedFromUFI : UFIBase {}
135135
// CHECK-LABEL: sil [serialized] [ossa] @$s19inlinable_attribute3basyyF
136136
@inlinable
137137
public func bas() {
138-
// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF
138+
// CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF
139139
func zim() {
140-
// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF4zangL_yyF
140+
// CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF4zangL_yyF
141141
func zang() { }
142142
}
143143

144144
// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3bas{{[_0-9a-zA-Z]*}}U_
145145
let zung = {
146-
// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3basyyFyycfU_7zippityL_yyF
146+
// CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute3basyyFyycfU_7zippityL_yyF
147147
func zippity() { }
148148
}
149149
}
150+
151+
// CHECK-LABEL: sil [ossa] @$s19inlinable_attribute6globalyS2iF : $@convention(thin) (Int) -> Int
152+
public func global(_ x: Int) -> Int { return x }
153+
154+
// CHECK-LABEL: sil [serialized] [ossa] @$s19inlinable_attribute16cFunctionPointeryyF : $@convention(thin) () -> ()
155+
@inlinable func cFunctionPointer() {
156+
// CHECK: function_ref @$s19inlinable_attribute6globalyS2iFTo
157+
let _: @convention(c) (Int) -> Int = global
158+
159+
// CHECK: function_ref @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_To
160+
let _: @convention(c) (Int) -> Int = { return $0 }
161+
162+
func local(_ x: Int) -> Int {
163+
return x
164+
}
165+
166+
// CHECK: function_ref @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iFTo
167+
let _: @convention(c) (Int) -> Int = local
168+
}
169+
170+
// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s19inlinable_attribute6globalyS2iFTo : $@convention(c) (Int) -> Int
171+
// CHECK: function_ref @$s19inlinable_attribute6globalyS2iF
172+
// CHECK: return
173+
174+
// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_ : $@convention(thin) (Int) -> Int {
175+
176+
// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_To : $@convention(c) (Int) -> Int {
177+
// CHECK: function_ref @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_
178+
// CHECK: return
179+
180+
// CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iF : $@convention(thin) (Int) -> Int {
181+
182+
// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iFTo : $@convention(c) (Int) -> Int {
183+
// CHECK: function_ref @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iF
184+
// CHECK: return

trunk/test/SILGen/objc_protocol_native_thunk.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Foundation
1111
func c(_: String) {}
1212
}
1313

14-
// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s{{.*}}1P{{.*}}1p{{.*}} : $@convention(method) <Self where Self : P> (@guaranteed String, @guaranteed Self) -> ()
14+
// CHECK-LABEL: sil shared [thunk] [ossa] @$s{{.*}}1P{{.*}}1p{{.*}} : $@convention(method) <Self where Self : P> (@guaranteed String, @guaranteed Self) -> ()
1515
func foo(x: Bool, y: C & P) -> (String) -> () {
1616
return x ? y.c : y.p
1717
}

trunk/test/SILGen/objc_protocols.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ func objc_generic_partial_apply<T : NSRuncing>(_ x: T) {
6363
}
6464
// CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlF'
6565

66-
// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK1]] :
66+
// CHECK: sil shared [thunk] [ossa] @[[THUNK1]] :
6767
// CHECK: bb0([[SELF:%.*]] : @guaranteed $Self):
6868
// CHECK: [[FN:%.*]] = function_ref @[[THUNK1_THUNK:\$s14objc_protocols9NSRuncingP5runceSo8NSObjectCyFTO]] :
6969
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
7070
// CHECK: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]]<Self>([[SELF_COPY]])
7171
// CHECK: return [[METHOD]]
7272
// CHECK: } // end sil function '[[THUNK1]]'
7373

74-
// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK1_THUNK]]
74+
// CHECK: sil shared [thunk] [ossa] @[[THUNK1_THUNK]]
7575
// CHECK: bb0([[SELF:%.*]] : @guaranteed $Self):
7676
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
7777
// CHECK: [[FN:%.*]] = objc_method [[SELF_COPY]] : $Self, #NSRuncing.runce!1.foreign
@@ -80,13 +80,13 @@ func objc_generic_partial_apply<T : NSRuncing>(_ x: T) {
8080
// CHECK: return [[RESULT]]
8181
// CHECK: } // end sil function '[[THUNK1_THUNK]]'
8282

83-
// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK2]] :
83+
// CHECK: sil shared [thunk] [ossa] @[[THUNK2]] :
8484
// CHECK: [[FN:%.*]] = function_ref @[[THUNK2_THUNK:\$s14objc_protocols9NSRuncingP5minceSo8NSObjectCyFZTO]]
8585
// CHECK: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]]<Self>(%0)
8686
// CHECK: return [[METHOD]]
8787
// CHECK: } // end sil function '[[THUNK2]]'
8888

89-
// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK2_THUNK]] :
89+
// CHECK: sil shared [thunk] [ossa] @[[THUNK2_THUNK]] :
9090
// CHECK: [[METATYPE:%.*]] = thick_to_objc_metatype %0
9191
// CHECK: [[FN:%.*]] = objc_method [[METATYPE]] : $@objc_metatype Self.Type, #NSRuncing.mince!1.foreign
9292
// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]<Self>([[METATYPE]])

trunk/validation-test/SIL/verify_all_overlays.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: for x in %platform-sdk-overlay-dir/*.swiftmodule; do [[ $(basename "$x") = Swift.swiftmodule ]] && continue; llvm-bcanalyzer $x | %FileCheck %s || echo "$x (bcanalyzer)" >> %t.txt; %target-sil-opt -sdk %sdk -enable-sil-verify-all $x > /dev/null || echo "$x (sil-opt)" >> %t/failures.txt; done
2+
// RUN: for x in %platform-sdk-overlay-dir/*.swiftmodule; do [[ $(basename "$x") = Swift.swiftmodule ]] && continue; llvm-bcanalyzer $x | %FileCheck %s || echo "$x (bcanalyzer)" >> %t/failures.txt; %target-sil-opt -sdk %sdk -enable-sil-verify-all $x > /dev/null || echo "$x (sil-opt)" >> %t/failures.txt; done
33
// RUN: not cat %t/failures.txt
44

55
// CHECK-NOT: Unknown

0 commit comments

Comments
 (0)