Skip to content

Commit 6282cf8

Browse files
committed
[Stdlib performance] Make integer conversion operations transparent
The integer conversion operations were inlinable, but aren't getting inlined in debug builds, which results in unreasonably poor performance. Mark them as transparent so we don't end up with unspecialized generic code in the hot path. Fixes #78501
1 parent c08a1ee commit 6282cf8

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

stdlib/public/core/Integers.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,8 +3040,7 @@ extension UnsignedInteger where Self: FixedWidthInteger {
30403040
/// - Parameter source: A value to convert to this type of integer. The value
30413041
/// passed as `source` must be representable in this type.
30423042
@_semantics("optimize.sil.specialize.generic.partial.never")
3043-
@inlinable // FIXME(inline-always)
3044-
@inline(__always)
3043+
@_transparent
30453044
public init<T: BinaryInteger>(_ source: T) {
30463045
// This check is potentially removable by the optimizer
30473046
if T.isSigned {
@@ -3056,8 +3055,7 @@ extension UnsignedInteger where Self: FixedWidthInteger {
30563055
}
30573056

30583057
@_semantics("optimize.sil.specialize.generic.partial.never")
3059-
@inlinable // FIXME(inline-always)
3060-
@inline(__always)
3058+
@_transparent
30613059
public init?<T: BinaryInteger>(exactly source: T) {
30623060
// This check is potentially removable by the optimizer
30633061
if T.isSigned && source < (0 as T) {
@@ -3255,8 +3253,7 @@ extension SignedInteger where Self: FixedWidthInteger {
32553253
/// - Parameter source: A value to convert to this type of integer. The value
32563254
/// passed as `source` must be representable in this type.
32573255
@_semantics("optimize.sil.specialize.generic.partial.never")
3258-
@inlinable // FIXME(inline-always)
3259-
@inline(__always)
3256+
@_transparent
32603257
public init<T: BinaryInteger>(_ source: T) {
32613258
// This check is potentially removable by the optimizer
32623259
if T.isSigned && source.bitWidth > Self.bitWidth {
@@ -3273,8 +3270,7 @@ extension SignedInteger where Self: FixedWidthInteger {
32733270
}
32743271

32753272
@_semantics("optimize.sil.specialize.generic.partial.never")
3276-
@inlinable // FIXME(inline-always)
3277-
@inline(__always)
3273+
@_transparent
32783274
public init?<T: BinaryInteger>(exactly source: T) {
32793275
// This check is potentially removable by the optimizer
32803276
if T.isSigned && source.bitWidth > Self.bitWidth && source < Self.min {

test/IRGen/integer_conversion.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s
2+
// RUN: %target-swift-frontend -primary-file %s -O -emit-ir | %FileCheck %s
3+
// REQUIRES: CPU=x86_64 || CPU=arm64
4+
5+
// https://github.com/swiftlang/swift/issues/78501
6+
public struct PcgRandom {
7+
private var state: UInt64 = 0;
8+
9+
// CHECK-LABEL: define{{.*}}swiftcc i32 @"$s18integer_conversion9PcgRandomV6next32s6UInt32VyF"
10+
public mutating func next32() -> UInt32 {
11+
// CHECK-NOT: sSUss17FixedWidthIntegerRzrlEyxqd__cSzRd__lufC
12+
// CHECK-NOT: sSZss17FixedWidthIntegerRzrlEyxqd__cSzRd__lufC
13+
// CHECK: ret i32
14+
let oldstate : UInt64 = state
15+
state = oldstate &* 6364136223846793005 &+ 1;
16+
let shifted = oldstate >> 18
17+
let xor = shifted ^ oldstate
18+
let xorshifted64 = xor >> 27
19+
let xorshifted = UInt32((xorshifted64 << 32) >> 32)
20+
let rot : UInt32 = UInt32(oldstate >> 59)
21+
let nrot : UInt32 = UInt32(bitPattern: -Int32(rot))
22+
return (xorshifted >> rot) | (xorshifted << (nrot & 31))
23+
}
24+
25+
init() {}
26+
}

0 commit comments

Comments
 (0)