mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
AST: Allow @inline(__always)/@inline(never) to be applied to properties and subscripts
Previously we only permitted it on the accessor itself, but there is no reason not to allow it on the storage declaration. Fixes <https://bugs.swift.org/browse/SR-3624> / <rdar://problem/31865137>.
This commit is contained in:
@@ -179,7 +179,7 @@ SIMPLE_DECL_ATTR(unsafe_no_objc_tagged_pointer, UnsafeNoObjCTaggedPointer,
|
||||
UserInaccessible,
|
||||
19)
|
||||
DECL_ATTR(inline, Inline,
|
||||
OnFunc | OnAccessor | OnConstructor,
|
||||
OnVar | OnSubscript | OnAbstractFunction,
|
||||
20)
|
||||
DECL_ATTR(_semantics, Semantics,
|
||||
OnAbstractFunction | OnSubscript |
|
||||
|
||||
@@ -528,26 +528,47 @@ IsSerialized_t SILDeclRef::isSerialized() const {
|
||||
return IsNotSerialized;
|
||||
}
|
||||
|
||||
/// \brief True if the function has noinline attribute.
|
||||
/// \brief True if the function has an @inline(never) attribute.
|
||||
bool SILDeclRef::isNoinline() const {
|
||||
if (!hasDecl())
|
||||
return false;
|
||||
if (auto InlineA = getDecl()->getAttrs().getAttribute<InlineAttr>())
|
||||
if (InlineA->getKind() == InlineKind::Never)
|
||||
|
||||
auto *decl = getDecl();
|
||||
if (auto *attr = decl->getAttrs().getAttribute<InlineAttr>())
|
||||
if (attr->getKind() == InlineKind::Never)
|
||||
return true;
|
||||
if (auto *semanticsA = getDecl()->getAttrs().getAttribute<SemanticsAttr>())
|
||||
if (semanticsA->Value.equals("keypath.entry"))
|
||||
|
||||
if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) {
|
||||
auto *storage = accessorDecl->getStorage();
|
||||
if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>())
|
||||
if (attr->getKind() == InlineKind::Never)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto *attr = decl->getAttrs().getAttribute<SemanticsAttr>())
|
||||
if (attr->Value.equals("keypath.entry"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief True if the function has noinline attribute.
|
||||
/// \brief True if the function has the @inline(__always) attribute.
|
||||
bool SILDeclRef::isAlwaysInline() const {
|
||||
if (!hasDecl())
|
||||
return false;
|
||||
if (auto InlineA = getDecl()->getAttrs().getAttribute<InlineAttr>())
|
||||
if (InlineA->getKind() == InlineKind::Always)
|
||||
|
||||
auto *decl = getDecl();
|
||||
if (auto attr = decl->getAttrs().getAttribute<InlineAttr>())
|
||||
if (attr->getKind() == InlineKind::Always)
|
||||
return true;
|
||||
|
||||
if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) {
|
||||
auto *storage = accessorDecl->getStorage();
|
||||
if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>())
|
||||
if (attr->getKind() == InlineKind::Always)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
// RUN: %target-swift-emit-silgen -module-name functions -Xllvm -sil-full-demangle -parse-stdlib -parse-as-library -enable-sil-ownership %s | %FileCheck %s
|
||||
|
||||
import Swift // just for Optional
|
||||
@@ -422,27 +421,6 @@ func applyTransparent(_ x: Bool) -> Bool {
|
||||
@inline(never)
|
||||
func noinline_callee() {}
|
||||
|
||||
// CHECK-LABEL: sil hidden [always_inline] @$s9functions20always_inline_calleeyyF : $@convention(thin) () -> ()
|
||||
@inline(__always)
|
||||
func always_inline_callee() {}
|
||||
|
||||
// CHECK-LABEL: sil [always_inline] @$s9functions27public_always_inline_calleeyyF : $@convention(thin) () -> ()
|
||||
@inline(__always)
|
||||
public func public_always_inline_callee() {}
|
||||
|
||||
protocol AlwaysInline {
|
||||
func alwaysInlined()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden [always_inline] @$s9functions19AlwaysInlinedMemberV06alwaysC0{{[_0-9a-zA-Z]*}}F : $@convention(method) (AlwaysInlinedMember) -> () {
|
||||
|
||||
// protocol witness for functions.AlwaysInline.alwaysInlined <A : functions.AlwaysInline>(functions.AlwaysInline.Self)() -> () in conformance functions.AlwaysInlinedMember : functions.AlwaysInline in functions
|
||||
// CHECK-LABEL: sil private [transparent] [thunk] [always_inline] @$s9functions19AlwaysInlinedMemberVAA0B6InlineA2aDP06alwaysC0{{[_0-9a-zA-Z]*}}FTW : $@convention(witness_method: AlwaysInline) (@in_guaranteed AlwaysInlinedMember) -> () {
|
||||
struct AlwaysInlinedMember : AlwaysInline {
|
||||
@inline(__always)
|
||||
func alwaysInlined() {}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden [Onone] @$s9functions10onone_funcyyF : $@convention(thin) () -> ()
|
||||
@_optimize(none)
|
||||
func onone_func() {}
|
||||
|
||||
@@ -129,3 +129,21 @@ private class PrivateDerivedFromPublic : PublicBase {}
|
||||
|
||||
// CHECK-LABEL: sil private @$s19inlinable_attribute21PrivateDerivedFromUFI{{.+}}LLC5horseAdA5HorseC_tcfc : $@convention(method) (@owned Horse, @owned PrivateDerivedFromUFI) -> @owned PrivateDerivedFromUFI
|
||||
private class PrivateDerivedFromUFI : UFIBase {}
|
||||
|
||||
// Make sure that nested functions are also serializable.
|
||||
|
||||
// CHECK-LABEL: sil [serialized] @$s19inlinable_attribute3basyyF
|
||||
@inlinable
|
||||
public func bas() {
|
||||
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyF3zimL_yyF
|
||||
func zim() {
|
||||
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyF3zimL_yyF4zangL_yyF
|
||||
func zang() { }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3bas{{[_0-9a-zA-Z]*}}U_
|
||||
let zung = {
|
||||
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyFyycfU_7zippityL_yyF
|
||||
func zippity() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
// RUN: %target-swift-emit-silgen -enable-sil-ownership -module-name main %s | %FileCheck %s
|
||||
internal func internalFunc() {}
|
||||
|
||||
// CHECK-LABEL: sil @$s4main3fooyyF
|
||||
public func foo() {
|
||||
// CHECK-LABEL: sil private [always_inline] @$s4main3foo{{[_0-9a-zA-Z]*}}zim
|
||||
@inline(__always)
|
||||
func zim() {
|
||||
// CHECK-LABEL: sil private @$s4main3fooyyF3zimL_yyF4zangL_yyF
|
||||
func zang() { internalFunc() }
|
||||
internalFunc()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil private @$s4main3foo{{[_0-9a-zA-Z]*}}U_
|
||||
let zung = {
|
||||
// CHECK-LABEL: sil private [always_inline] @$s4main3fooyyFyycfU_7zippityL_yyF
|
||||
@inline(__always)
|
||||
func zippity() { internalFunc() }
|
||||
internalFunc()
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden [always_inline] @$s4main3baryyF
|
||||
@inline(__always)
|
||||
internal func bar() {
|
||||
// CHECK-LABEL: sil private [always_inline] @$s4main3baryyF3zimL_yyF
|
||||
@inline(__always)
|
||||
func zim() {
|
||||
// CHECK-LABEL: sil private @$s4main3baryyF3zimL_yyF4zangL_yyF
|
||||
func zang() { internalFunc() }
|
||||
internalFunc()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil private @$s4main3bar{{[_0-9a-zA-Z]*}}U_
|
||||
let zung = {
|
||||
// CHECK-LABEL: sil private [always_inline] @$s4main3baryyFyycfU_7zippityL_yyF
|
||||
@inline(__always)
|
||||
func zippity() { internalFunc() }
|
||||
internalFunc()
|
||||
}
|
||||
}
|
||||
|
||||
public func publicFunc() {}
|
||||
|
||||
// CHECK-LABEL: sil [serialized] [always_inline] @$s4main3basyyF
|
||||
@inlinable @inline(__always)
|
||||
public func bas() {
|
||||
// CHECK-LABEL: sil shared [serialized] [always_inline] @$s4main3basyyF3zimL_yyF
|
||||
@inline(__always)
|
||||
func zim() {
|
||||
// CHECK-LABEL: sil shared [serialized] @$s4main3basyyF3zimL_yyF4zangL_yyF
|
||||
func zang() { publicFunc() }
|
||||
publicFunc()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil shared [serialized] @$s4main3bas{{[_0-9a-zA-Z]*}}U_
|
||||
let zung = {
|
||||
// CHECK-LABEL: sil shared [serialized] [always_inline] @$s4main3basyyFyycfU_7zippityL_yyF
|
||||
@inline(__always)
|
||||
func zippity() { publicFunc() }
|
||||
publicFunc()
|
||||
}
|
||||
}
|
||||
@@ -214,12 +214,12 @@ func func_type_attribute_with_space(x: @convention (c) () -> Int) {} // OK. Know
|
||||
var thinFunc : @thin () -> () // expected-error {{attribute is not supported}}
|
||||
|
||||
@inline(never) func nolineFunc() {}
|
||||
@inline(never) var noinlineVar : Int // expected-error {{'@inline(never)' attribute cannot be applied to this declaration}} {{1-16=}}
|
||||
@inline(never) var noinlineVar : Int { return 0 }
|
||||
@inline(never) class FooClass { // expected-error {{'@inline(never)' attribute cannot be applied to this declaration}} {{1-16=}}
|
||||
}
|
||||
|
||||
@inline(__always) func AlwaysInlineFunc() {}
|
||||
@inline(__always) var alwaysInlineVar : Int // expected-error {{'@inline(__always)' attribute cannot be applied to this declaration}} {{1-19=}}
|
||||
@inline(__always) var alwaysInlineVar : Int { return 0 }
|
||||
@inline(__always) class FooClass2 { // expected-error {{'@inline(__always)' attribute cannot be applied to this declaration}} {{1-19=}}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user