Skip to content

Commit f80d072

Browse files
authored
Merge pull request #64210 from eeckstein/always-inline-closures
SILGen: Closures within @inline(__always) functions should be always inlined, too
2 parents b0bd756 + 7a2a402 commit f80d072

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,10 +931,20 @@ bool SILDeclRef::isNoinline() const {
931931

932932
/// True if the function has the @inline(__always) attribute.
933933
bool SILDeclRef::isAlwaysInline() const {
934-
if (!hasDecl())
934+
swift::Decl *decl = nullptr;
935+
if (hasDecl()) {
936+
decl = getDecl();
937+
} else if (auto *ce = getAbstractClosureExpr()) {
938+
// Closures within @inline(__always) functions should be always inlined, too.
939+
// Note that this is different from @inline(never), because closures inside
940+
// @inline(never) _can_ be inlined within the inline-never function.
941+
decl = ce->getParent()->getInnermostDeclarationDeclContext();
942+
if (!decl)
943+
return false;
944+
} else {
935945
return false;
946+
}
936947

937-
auto *decl = getDecl();
938948
if (auto attr = decl->getAttrs().getAttribute<InlineAttr>())
939949
if (attr->getKind() == InlineKind::Always)
940950
return true;

test/SILGen/inline_always.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
@inline(__always)
55
func always_inline_callee() {}
66

7+
// CHECK-LABEL: sil hidden [always_inline] [ossa] @$s13inline_always11testClosureyyF
8+
@inline(__always)
9+
func testClosure() {
10+
// CHECK-LABEL: sil private [always_inline] [ossa] @$s13inline_always11testClosureyyFyycfU_
11+
_ = { }
12+
}
13+
714
protocol AlwaysInline {
815
func alwaysInlined()
916
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-swift-frontend %s -O -module-name=test -emit-sil | %FileCheck %s
2+
3+
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
4+
5+
public protocol P {
6+
func takePointer<T>(_ p: UnsafePointer<T>)
7+
}
8+
9+
extension P {
10+
@inline(__always)
11+
func genericFunc<T>(_ x: inout T) {
12+
withUnsafePointer(to: &x) {
13+
takePointer($0)
14+
}
15+
}
16+
}
17+
18+
// CHECK-LABEL: sil {{.*}}@$s4test6testityyAA1P_pF
19+
// CHECK-NOT: function_ref
20+
// CHECK: witness_method
21+
// CHECK: } // end sil function '$s4test6testityyAA1P_pF'
22+
public func testit(_ p: P) {
23+
var x = 0
24+
p.genericFunc(&x)
25+
}
26+

0 commit comments

Comments
 (0)