Skip to content

Commit fc0844e

Browse files
committed
SIL optimization
1 parent 1a953eb commit fc0844e

File tree

6 files changed

+91
-9
lines changed

6 files changed

+91
-9
lines changed

lib/SILOptimizer/Transforms/EagerSpecializer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ static SILFunction *eagerSpecialize(SILOptFunctionBuilder &FuncBuilder,
794794
} else if (SA.isExported()) {
795795
NewFunc->setLinkage(NewFunc->isDefinition() ? SILLinkage::Public
796796
: SILLinkage::PublicExternal);
797+
NewFunc->setAvailabilityForLinkage(SA.getAvailability());
797798
}
798799

799800
return NewFunc;

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,6 +2485,19 @@ usePrespecialized(SILOptFunctionBuilder &funcBuilder, ApplySite apply,
24852485
!currentModule->isImportedAsSPI(spiGroup, funcModule))
24862486
continue;
24872487
}
2488+
// Check whether the availability of the specialization allows for using
2489+
// it. We check the deployment target or the current functions availability
2490+
// target depending which one is more recent.
2491+
auto specializationAvail = SA->getAvailability();
2492+
auto &ctxt = funcBuilder.getModule().getSwiftModule()->getASTContext();
2493+
auto deploymentAvail = AvailabilityContext::forDeploymentTarget(ctxt);
2494+
auto currentFnAvailability = apply.getFunction()->getAvailabilityForLinkage();
2495+
if (!currentFnAvailability.isAlwaysAvailable() &&
2496+
!deploymentAvail.isContainedIn(currentFnAvailability))
2497+
deploymentAvail = currentFnAvailability;
2498+
if (!deploymentAvail.isContainedIn(specializationAvail))
2499+
continue;
2500+
24882501
ReabstractionInfo reInfo(funcBuilder.getModule().getSwiftModule(),
24892502
funcBuilder.getModule().isWholeModule(), refF,
24902503
SA->getSpecializedSignature(),

test/SILOptimizer/Inputs/pre_specialized_module.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1+
@frozen
2+
public struct SomeData {
3+
public init() {}
4+
}
5+
16
@_specialize(exported: true, where T == Int)
27
@_specialize(exported: true, where T == Double)
8+
@_specialize(exported: true, availability: macOS 10.50, *; where T == SomeData)
39
public func publicPrespecialized<T>(_ t: T) {
410
}
511

12+
@_specialize(exported: true, where T == Int)
13+
@_specialize(exported: true, availability: macOS 10.50, *; where T == SomeData)
14+
@inlinable
15+
@inline(never)
16+
public func publicPrespecialized2<T>(_ t: T) { }
17+
618
@_specialize(exported: true, where T == Int)
719
@_specialize(exported: true, where T == Double)
820
@_alwaysEmitIntoClient
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import pre_specialized_module
2+
3+
@frozen
4+
public struct SomeOtherData {
5+
public init() {}
6+
}
7+
8+
@_specialize(exported: true, target: publicPrespecialized2(_:), availability: macOS 10.50, *; where T == SomeOtherData)
9+
public func pre_specialize_publicPrespecialized<T>(_ t: T) {
10+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -O -swift-version 5 -enable-library-evolution -emit-module -o /dev/null -emit-module-interface-path %t/pre_specialized_module.swiftinterface %S/Inputs/pre_specialized_module.swift -module-name pre_specialized_module
3+
// RUN: %target-swift-frontend -I %t -O -swift-version 5 -enable-library-evolution -emit-module -o /dev/null -emit-module-interface-path %t/pre_specialized_module2.swiftinterface %S/Inputs/pre_specialized_module2.swift -module-name pre_specialized_module2
4+
// RUN: %target-swift-frontend -I %t -O -emit-sil -target x86_64-apple-macos11 %s | %FileCheck %s --check-prefix=OPT --check-prefix=CHECK
5+
// RUN: %target-swift-frontend -I %t -O -emit-sil -target x86_64-apple-macosx10.9 %s | %FileCheck %s --check-prefix=NOOPT --check-prefix=CHECK
6+
7+
// REQUIRES: OS=macosx
8+
9+
import pre_specialized_module
10+
import pre_specialized_module2
11+
12+
// CHECK: sil @$s4main28usePrespecializedEntryPointsyyF : $@convention(thin) () -> () {
13+
// OPT: [[F1:%.*]] = function_ref @$s22pre_specialized_module21publicPrespecialized2yyxlFAA8SomeDataV_Ts5 : $@convention(thin) (SomeData) -> ()
14+
// OPT: apply [[F1]](
15+
// OPT: [[F2:%.*]] = function_ref @$s22pre_specialized_module21publicPrespecialized2yyxlF0a1_B8_module213SomeOtherDataV_Ts5 : $@convention(thin) (SomeOtherData) -> ()
16+
// OPT: apply [[F2]](
17+
// In the no prespecialization case we get regular generic specialization
18+
// because the function is inlinable.
19+
// NOOPT: [[F1:%.*]] = function_ref @$s22pre_specialized_module21publicPrespecialized2yyxlFAA8SomeDataV_Tg5Tf4d_n : $@convention(thin) () -> ()
20+
// NOOPT: apply [[F1]]()
21+
// NOOPT: [[F2:%.*]] = function_ref @$s22pre_specialized_module21publicPrespecialized2yyxlF0a1_B8_module213SomeOtherDataV_Tg5Tf4d_n : $@convention(thin) () -> ()
22+
// NOOPT: apply [[F2]]()
23+
// CHECK: } // end sil function '$s4main28usePrespecializedEntryPointsyyF'
24+
public func usePrespecializedEntryPoints() {
25+
publicPrespecialized2(SomeData())
26+
publicPrespecialized2(SomeOtherData())
27+
}

test/SILOptimizer/pre_specialize.swift

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module-path %t/pre_specialized_module.swiftmodule %S/Inputs/pre_specialized_module.swift
3-
// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT
4-
// RUN: %target-swift-frontend -I %t -Onone -emit-sil %s | %FileCheck %s --check-prefix=NONE
3+
// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT -check-prefix=OPT-%target-os
4+
// RUN: %target-swift-frontend -I %t -Onone -emit-sil %s | %FileCheck %s --check-prefix=NONE -check-prefix=NONE-%target-os
55

66

77
// RUN: %empty-directory(%t)
@@ -13,33 +13,41 @@
1313
// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT
1414

1515
// RUN: %empty-directory(%t)
16-
// RUN: %target-swift-frontend -O -swift-version 5 -enable-library-evolution -emit-module -o /dev/null -emit-module-interface-path %t/pre_specialized_module.swiftinterface %S/Inputs/pre_specialized_module.swift
16+
// RUN: %target-swift-frontend -O -swift-version 5 -enable-library-evolution -emit-module -o /dev/null -emit-module-interface-path %t/pre_specialized_module.swiftinterface %S/Inputs/pre_specialized_module.swift -module-name pre_specialized_module
1717
// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT
1818

1919
import pre_specialized_module
2020

2121
// Make sure we generate the public pre-specialized entry points.
2222

23-
// OPT: sil @$s14pre_specialize10testPublic1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
24-
// OPT: sil @$s14pre_specialize10testPublic1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
23+
// OPT-DAG: sil @$s14pre_specialize10testPublic1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
24+
// OPT-DAG: sil @$s14pre_specialize10testPublic1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
25+
// OPT-macosx-DAG: sil [available 10.5] @$s14pre_specialize10testPublic1tyx_tlFSd_Ts5 : $@convention(thin) (Double) -> () {
26+
// OPT-linux-gnu-DAG: sil @$s14pre_specialize10testPublic1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
2527

26-
// NONE: sil @$s14pre_specialize10testPublic1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
27-
// NONE: sil @$s14pre_specialize10testPublic1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
28+
// NONE-DAG: sil @$s14pre_specialize10testPublic1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
29+
// NONE-DAG: sil @$s14pre_specialize10testPublic1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
30+
// NONE-macosx-DAG: sil [available 10.5] @$s14pre_specialize10testPublic1tyx_tlFSd_Ts5 : $@convention(thin) (Double) -> () {
31+
// NONE-linux-gnu-DAG: sil @$s14pre_specialize10testPublic1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
2832

2933
@_specialize(exported: true, where T == Int)
3034
@_specialize(exported: true, where T == Float)
35+
@_specialize(exported: true, availability: macOS 10.5, *; where T == Double)
3136
public func testPublic<T>(t: T) {
3237
print(t)
3338
}
3439

35-
// OPT: sil @$s14pre_specialize18testEmitIntoClient1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
36-
// OPT: sil @$s14pre_specialize18testEmitIntoClient1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
40+
// OPT-macosx-DAG: sil [available 10.5] @$s14pre_specialize18testEmitIntoClient1tyx_tlFSd_Ts5 : $@convention(thin) (Double) -> () {
41+
// OPT-linux-gnu-DAG: sil @$s14pre_specialize18testEmitIntoClient1tyx_tlFSd_Ts5 : $@convention(thin) (Double) -> () {
42+
// OPT-DAG: sil @$s14pre_specialize18testEmitIntoClient1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
43+
// OPT-DAG: sil @$s14pre_specialize18testEmitIntoClient1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
3744

3845
// NONE: sil @$s14pre_specialize18testEmitIntoClient1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
3946
// NONE: sil @$s14pre_specialize18testEmitIntoClient1tyx_tlFSi_Ts5 : $@convention(thin) (Int) -> () {
4047

4148
@_specialize(exported: true, where T == Int)
4249
@_specialize(exported: true, where T == Float)
50+
@_specialize(exported: true, availability: macOS 10.5, *; where T == Double)
4351
@_alwaysEmitIntoClient
4452
internal func testEmitIntoClient<T>(t: T) {
4553
print(t)
@@ -50,6 +58,8 @@ internal func testEmitIntoClient<T>(t: T) {
5058
// OPT: apply [[F1]]
5159
// OPT: [[F2:%.*]] = function_ref @$s22pre_specialized_module20publicPrespecializedyyxlFSd_Ts5 : $@convention(thin) (Double) -> ()
5260
// OPT: apply [[F2]]
61+
// OPT-macosx: [[F6:%.*]] = function_ref @$s22pre_specialized_module20publicPrespecializedyyxlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
62+
// OPT-macosx: apply [[F6]]<SomeData>
5363
// OPT: [[F3:%.*]] = function_ref @$s22pre_specialized_module36internalEmitIntoClientPrespecializedyyxlFSi_Ts5 : $@convention(thin) (Int) -> ()
5464
// OPT: apply [[F3]]
5565
// OPT: [[F4:%.*]] = function_ref @$s22pre_specialized_module36internalEmitIntoClientPrespecializedyyxlFSd_Ts5 : $@convention(thin) (Double) -> ()
@@ -80,10 +90,19 @@ internal func testEmitIntoClient<T>(t: T) {
8090
public func usePrespecializedEntryPoints() {
8191
publicPrespecialized(1)
8292
publicPrespecialized(1.0)
93+
publicPrespecialized(SomeData())
8394
useInternalEmitIntoClientPrespecialized(2)
8495
useInternalEmitIntoClientPrespecialized(2.0)
8596
useInternalThing(2)
8697
}
98+
// OPT: sil [available 10.50] @$s14pre_specialize40usePrespecializedEntryPointsAvailabilityyyF : $@convention(thin) () -> () {
99+
// OPT: [[F1:%.*]] = function_ref @$s22pre_specialized_module20publicPrespecializedyyxlFAA8SomeDataV_Ts5 : $@convention(thin) (SomeData) -> ()
100+
// OPT: apply [[F1]](
101+
// OPT: } // end sil function '$s14pre_specialize40usePrespecializedEntryPointsAvailabilityyyF'
102+
@available(macOS 10.50, *)
103+
public func usePrespecializedEntryPointsAvailability() {
104+
publicPrespecialized(SomeData())
105+
}
87106
// OPT: sil [signature_optimized_thunk] [always_inline] @$s22pre_specialized_module16publicInlineableyyxlFSd_Ts5 : $@convention(thin) (Double) -> () {
88107
// NONE: sil @$s22pre_specialized_module16publicInlineableyyxlFSd_Ts5 : $@convention(thin) (Double) -> () {
89108
@_specialize(exported: true, target: publicInlineable(_:), where T == Double)

0 commit comments

Comments
 (0)