Skip to content

Commit 664e7cc

Browse files
committed
[Availability] Make _stdlib_isOSVersionAtLeast() no longer inlinable
To make it possible to change the implementation of _stdlib_isOSVersionAtLeast(), remove the @inlinable attribute from it. Since it is currently inlinable and calls the helper function _swift_stdlib_operatingSystemVersion(), we’ll have to keep the helper around as ABI. This change causes a minor pessimization where the LLVM optimizer can no longer reason that, for example, a successful check for 10.12 availability means that a later check for 10.11 will always succeed. I don't expect this pessimization to be a problem, but if needed we could write a custom SIL optimizer pass to claw back the performance. <rdar://problem/59447474>
1 parent d58bf54 commit 664e7cc

File tree

4 files changed

+18
-12
lines changed

4 files changed

+18
-12
lines changed

lib/IRGen/AllocStackHoisting.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,6 @@ bool indicatesDynamicAvailabilityCheckUse(SILInstruction *I) {
355355
auto *FunRef = Apply->getReferencedFunctionOrNull();
356356
if (!FunRef)
357357
return false;
358-
if (FunRef->getName().equals("_swift_stdlib_operatingSystemVersion"))
359-
return true;
360358
return false;
361359
}
362360

stdlib/public/core/Availability.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import SwiftShims
1818
/// This is a magic entry point known to the compiler. It is called in
1919
/// generated code for API availability checking.
2020
@_semantics("availability.osversion")
21-
@inlinable
21+
@_effects(readnone)
2222
public func _stdlib_isOSVersionAtLeast(
2323
_ major: Builtin.Word,
2424
_ minor: Builtin.Word,
@@ -28,9 +28,6 @@ public func _stdlib_isOSVersionAtLeast(
2828
if Int(major) == 9999 {
2929
return true._value
3030
}
31-
// The call to _swift_stdlib_operatingSystemVersion is used as an indicator
32-
// that this function was called by a compiler optimization pass. If it is
33-
// replaced that pass needs to be updated.
3431
let runningVersion = _swift_stdlib_operatingSystemVersion()
3532

3633
let result =

stdlib/public/stubs/Availability.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ static os_system_version_s getOSVersion() {
4343

4444
/// Return the version of the operating system currently running for use in
4545
/// API availability queries.
46+
///
47+
/// This is ABI and cannot be removed. Even though _stdlib_isOSVersionAtLeast()
48+
/// is no longer inlinable, is previously was and so calls to this method
49+
/// have been inlined into shipped apps.
4650
_SwiftNSOperatingSystemVersion swift::_swift_stdlib_operatingSystemVersion() {
4751
os_system_version_s version = SWIFT_LAZY_CONSTANT(getOSVersion());
4852

test/IRGen/availability.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Foundation
1515

1616
// OPT-LABEL: define{{.*}} @{{.*}}dontHoist
1717
// OPT-NOT: S10Foundation11MeasurementVySo17NSUnitTemperature
18-
// OPT: call {{.*}} @_swift_stdlib_operatingSystemVersion(
18+
// OPT: call {{.*}} @"$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF"(
1919
// OPT: s10Foundation11MeasurementVySo17NSUnitTemperature
2020

2121
public func dontHoist() {
@@ -28,8 +28,15 @@ public func dontHoist() {
2828
}
2929

3030

31+
// Now that _isOSVersionAtLeast is no longer inlinable, we do still
32+
// mark it as _effects(readnone).
33+
// This means that unlike in the past the optimizer can now only coalesce
34+
// availability checks with the same availability. It does not determine,
35+
// for example, that a check for iOS 10 is sufficient to guarantee that a check
36+
// for iOS 9 will also succeed.
37+
3138
// With optimizations on, multiple #availability checks should generate only
32-
// a single call into _swift_stdlib_operatingSystemVersion.
39+
// a single call into _isOSVersionAtLeast.
3340

3441
// CHECK-LABEL: define{{.*}} @{{.*}}multipleAvailabilityChecks
3542
// CHECK: call swiftcc i1 @"$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF"(
@@ -38,17 +45,17 @@ public func dontHoist() {
3845
// CHECK: ret void
3946

4047
// OPT-LABEL: define{{.*}} @{{.*}}multipleAvailabilityChecks
41-
// OPT: call {{.*}} @_swift_stdlib_operatingSystemVersion
42-
// OPT-NOT: call {{.*}} @_swift_stdlib_operatingSystemVersion
48+
// OPT: call {{.*}} @"$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF"
49+
// OPT-NOT: call {{.*}} @"$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF"
4350
// OPT: ret void
4451
public func multipleAvailabilityChecks() {
4552
if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
4653
print("test one")
4754
}
48-
if #available(OSX 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *) {
55+
if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
4956
print("test two")
5057
}
51-
if #available(OSX 10.10, iOS 8.0, watchOS 1.0, tvOS 8.0, *) {
58+
if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
5259
print("test three")
5360
}
5461
}

0 commit comments

Comments
 (0)