Skip to content

Commit 4780b0b

Browse files
committed
AST: Introduce @_inlineable attribute
This attribute causes a function's body to be serialized, but unlike @_transparent and @inline(__always), does not force it to be inlined.
1 parent f63dff1 commit 4780b0b

File tree

7 files changed

+59
-16
lines changed

7 files changed

+59
-16
lines changed

include/swift/AST/Attr.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,13 @@ SIMPLE_DECL_ATTR(nonobjc, NonObjC,
164164
SIMPLE_DECL_ATTR(_fixed_layout, FixedLayout,
165165
OnVar | OnClass | OnStruct | OnEnum | UserInaccessible, 31)
166166

167+
SIMPLE_DECL_ATTR(_inlineable, Inlineable,
168+
OnVar | OnSubscript | OnFunc | OnConstructor | OnDestructor |
169+
UserInaccessible, 32)
170+
167171
DECL_ATTR(_specialize, Specialize,
168172
OnConstructor | OnFunc | AllowMultipleAttributes | LongAttribute
169-
| UserInaccessible, 32)
173+
| UserInaccessible, 33)
170174

171175
// Non-serialized attributes.
172176

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 281; // Last change: complete witnesses
57+
const uint16_t VERSION_MINOR = 282; // Last change: @_inlineable
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;

lib/AST/DeclContext.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -503,21 +503,31 @@ bool DeclContext::isValidGenericContext() const {
503503
/// are used.
504504
ResilienceExpansion DeclContext::getResilienceExpansion() const {
505505
for (const auto *dc = this; dc->isLocalContext(); dc = dc->getParent()) {
506-
if (auto *func = dyn_cast<AbstractFunctionDecl>(dc)) {
506+
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(dc)) {
507507
// If the function is not externally visible, we will not be serializing
508508
// its body.
509-
if (!func->getDeclContext()->isLocalContext() &&
510-
func->getEffectiveAccess() < Accessibility::Public)
509+
if (!AFD->getDeclContext()->isLocalContext() &&
510+
AFD->getEffectiveAccess() < Accessibility::Public)
511511
break;
512512

513513
// Bodies of public transparent and always-inline functions are
514514
// serialized, so use conservative access patterns.
515-
if (func->isTransparent())
515+
if (AFD->isTransparent())
516516
return ResilienceExpansion::Minimal;
517517

518-
if (auto attr = func->getAttrs().getAttribute<InlineAttr>())
518+
if (AFD->getAttrs().hasAttribute<InlineableAttr>())
519+
return ResilienceExpansion::Minimal;
520+
521+
if (auto attr = AFD->getAttrs().getAttribute<InlineAttr>())
519522
if (attr->getKind() == InlineKind::Always)
520523
return ResilienceExpansion::Minimal;
524+
525+
// If a property or subscript is @_fragile, the accessors are
526+
// @_fragile also.
527+
if (auto FD = dyn_cast<FuncDecl>(AFD))
528+
if (auto *ASD = FD->getAccessorStorageDecl())
529+
if (ASD->getAttrs().getAttribute<InlineableAttr>())
530+
return ResilienceExpansion::Minimal;
521531
}
522532
}
523533

lib/Sema/TypeCheckAttr.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
5757
IGNORED_ATTR(FixedLayout)
5858
IGNORED_ATTR(Infix)
5959
IGNORED_ATTR(Inline)
60+
IGNORED_ATTR(Inlineable)
6061
IGNORED_ATTR(NSApplicationMain)
6162
IGNORED_ATTR(NSCopying)
6263
IGNORED_ATTR(NonObjC)
@@ -688,18 +689,18 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
688689

689690
IGNORED_ATTR(AutoClosure)
690691
IGNORED_ATTR(Alignment)
691-
IGNORED_ATTR(SILGenName)
692+
IGNORED_ATTR(Convenience)
692693
IGNORED_ATTR(Dynamic)
694+
IGNORED_ATTR(Effects)
693695
IGNORED_ATTR(Exported)
694-
IGNORED_ATTR(Convenience)
696+
IGNORED_ATTR(FixedLayout)
695697
IGNORED_ATTR(GKInspectable)
696698
IGNORED_ATTR(IBDesignable)
697699
IGNORED_ATTR(IBInspectable)
698700
IGNORED_ATTR(IBOutlet) // checked early.
699701
IGNORED_ATTR(Indirect)
700702
IGNORED_ATTR(Inline)
701-
IGNORED_ATTR(Effects)
702-
IGNORED_ATTR(FixedLayout)
703+
IGNORED_ATTR(Inlineable)
703704
IGNORED_ATTR(Lazy) // checked early.
704705
IGNORED_ATTR(LLDBDebuggerFunction)
705706
IGNORED_ATTR(Mutating)
@@ -716,6 +717,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
716717
IGNORED_ATTR(Override)
717718
IGNORED_ATTR(RawDocComment)
718719
IGNORED_ATTR(Semantics)
720+
IGNORED_ATTR(SILGenName)
719721
IGNORED_ATTR(Transparent)
720722
IGNORED_ATTR(SynthesizedProtocol)
721723
IGNORED_ATTR(RequiresStoredPropertyInits)

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5864,6 +5864,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
58645864
UNINTERESTING_ATTR(IBOutlet)
58655865
UNINTERESTING_ATTR(Indirect)
58665866
UNINTERESTING_ATTR(Inline)
5867+
UNINTERESTING_ATTR(Inlineable)
58675868
UNINTERESTING_ATTR(Effects)
58685869
UNINTERESTING_ATTR(FixedLayout)
58695870
UNINTERESTING_ATTR(Lazy)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-swift-frontend -emit-silgen -emit-verbose-sil %s | %FileCheck %s
2+
3+
// CHECK-LABEL: sil [fragile] @_TF20inlineable_attribute15fragileFunctionFT_T_ : $@convention(thin) () -> ()
4+
@_inlineable public func fragileFunction() {
5+
6+
}
7+
8+
public struct MySt {
9+
// CHECK-LABEL: sil [fragile] @_TFV20inlineable_attribute4MySt6methodfT_T_ : $@convention(method) (MySt) -> ()
10+
@_inlineable public func method() {}
11+
12+
// CHECK-LABEL: sil [fragile] @_TFV20inlineable_attribute4MyStg8propertySi : $@convention(method) (MySt) -> Int
13+
@_inlineable public var property: Int {
14+
return 5
15+
}
16+
17+
// CHECK-LABEL: sil [fragile] @_TFV20inlineable_attribute4MyStg9subscriptFSiSi : $@convention(method) (Int, MySt) -> Int
18+
@_inlineable public subscript(x: Int) -> Int {
19+
return x
20+
}
21+
}
22+
23+
public class MyCls {
24+
// CHECK-LABEL: sil [fragile] @_TFC20inlineable_attribute5MyClsD : $@convention(method) (@owned MyCls) -> ()
25+
@_inlineable deinit {}
26+
}

test/SILGen/transparent_attribute.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ func useTransparentFuncWithDefaultArgument() -> Int {
88
return transparentFuncWithDefaultArgument();
99

1010
// CHECK-LABEL: sil hidden @_TF21transparent_attribute37useTransparentFuncWithDefaultArgumentFT_Si
11-
// CHECK: apply {{.*}} line:10:44
12-
// CHECK: apply {{.*}} line:10:10
11+
// CHECK: apply {{.*}} line:8:44
12+
// CHECK: apply {{.*}} line:8:10
1313
// CHECK: return
1414

1515
}
@@ -21,9 +21,9 @@ func useTransparentFuncWithoutDefaultArgument() -> Int {
2121
return transparentFuncWithoutDefaultArgument();
2222

2323
// CHECK-LABEL: sil hidden @_TF21transparent_attribute40useTransparentFuncWithoutDefaultArgumentFT_Si
24-
// CHECK: apply {{.*}} line:23:47
24+
// CHECK: apply {{.*}} line:21:47
2525
// CHECK-NOT: transparent
26-
// CHECK: apply {{.*}} line:23:10
26+
// CHECK: apply {{.*}} line:21:10
2727
// CHECK: return
2828

2929
}
@@ -40,7 +40,7 @@ func testStructWithTranspConstructor() -> StructWithTranspConstructor {
4040

4141
// testStructWithTranspConstructor
4242
// CHECK-APPLY: _T21transparent_attribute31testStructWithTranspConstructorFT_VS_27StructWithTranspConstructor
43-
// CHECK: apply {{.*}} line:38:10
43+
// CHECK: apply {{.*}} line:36:10
4444

4545
}
4646

0 commit comments

Comments
 (0)