Skip to content

Commit 6f5bb10

Browse files
authored
Merge pull request #73645 from eeckstein/pointer-keypath-opt
Improve debug performance of `UnsafePointer.pointer(to:)`
2 parents f984eff + 15acfbb commit 6f5bb10

File tree

4 files changed

+68
-9
lines changed

4 files changed

+68
-9
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyKeyPath.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fileprivate func allUsesRemovable(instruction: Instruction) -> Bool {
3434
switch use.instruction {
3535
case is UpcastInst,
3636
is DestroyValueInst,
37+
is StrongReleaseInst,
3738
is BeginBorrowInst,
3839
is EndBorrowInst,
3940
is MoveValueInst,

stdlib/public/core/UnsafePointer.swift

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -444,16 +444,14 @@ extension UnsafePointer {
444444
/// - Returns: A pointer to the stored property represented
445445
/// by the key path, or `nil`.
446446
@_alwaysEmitIntoClient
447-
#if $Embedded
448447
@_transparent
449-
#endif
450448
public func pointer<Property>(
451449
to property: KeyPath<Pointee, Property>
452450
) -> UnsafePointer<Property>? {
453451
guard let o = property._storedInlineOffset else { return nil }
454452
_internalInvariant(o >= 0)
455453
_debugPrecondition(
456-
o == 0 || UnsafeRawPointer(self) < UnsafeRawPointer(bitPattern: 0 &- o)!,
454+
!UInt(bitPattern: self).addingReportingOverflow(UInt(bitPattern: o)).overflow,
457455
"Overflow in pointer arithmetic"
458456
)
459457
return .init(Builtin.gepRaw_Word(_rawValue, o._builtinWordValue))
@@ -1332,16 +1330,14 @@ extension UnsafeMutablePointer {
13321330
/// - Returns: A pointer to the stored property represented
13331331
/// by the key path, or `nil`.
13341332
@_alwaysEmitIntoClient
1335-
#if $Embedded
13361333
@_transparent
1337-
#endif
13381334
public func pointer<Property>(
13391335
to property: KeyPath<Pointee, Property>
13401336
) -> UnsafePointer<Property>? {
13411337
guard let o = property._storedInlineOffset else { return nil }
13421338
_internalInvariant(o >= 0)
13431339
_debugPrecondition(
1344-
o == 0 || UnsafeRawPointer(self) < UnsafeRawPointer(bitPattern: 0 &- o)!,
1340+
!UInt(bitPattern: self).addingReportingOverflow(UInt(bitPattern: o)).overflow,
13451341
"Overflow in pointer arithmetic"
13461342
)
13471343
return .init(Builtin.gepRaw_Word(_rawValue, o._builtinWordValue))
@@ -1356,16 +1352,14 @@ extension UnsafeMutablePointer {
13561352
/// - Returns: A mutable pointer to the stored property represented
13571353
/// by the key path, or `nil`.
13581354
@_alwaysEmitIntoClient
1359-
#if $Embedded
13601355
@_transparent
1361-
#endif
13621356
public func pointer<Property>(
13631357
to property: WritableKeyPath<Pointee, Property>
13641358
) -> UnsafeMutablePointer<Property>? {
13651359
guard let o = property._storedInlineOffset else { return nil }
13661360
_internalInvariant(o >= 0)
13671361
_debugPrecondition(
1368-
o == 0 || UnsafeRawPointer(self) < UnsafeRawPointer(bitPattern: 0 &- o)!,
1362+
!UInt(bitPattern: self).addingReportingOverflow(UInt(bitPattern: o)).overflow,
13691363
"Overflow in pointer arithmetic"
13701364
)
13711365
return .init(Builtin.gepRaw_Word(_rawValue, o._builtinWordValue))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend %s -module-name=test -parse-as-library -emit-sil | %FileCheck %s
2+
3+
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
4+
5+
public struct S {
6+
var a: Int
7+
var b: Int
8+
}
9+
10+
// Check that even with -Onone, no keypath is created.
11+
12+
// CHECK-LABEL: sil @$s4test6testitySPySiGSgSPyAA1SVGF :
13+
// CHECK-NOT: keypath
14+
// CHECK: } // end sil function '$s4test6testitySPySiGSgSPyAA1SVGF'
15+
public func testit(_ p: UnsafePointer<S>) -> UnsafePointer<Int>? {
16+
return p.pointer(to: \.b)
17+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=keypath | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
8+
struct S {
9+
@_hasStorage var a: Int
10+
@_hasStorage var b: Int
11+
}
12+
13+
// CHECK-LABEL: sil [ossa] @remove_dead_keypath_ossa :
14+
// CHECK-NOT: keypath
15+
// CHECK-NOT: destroy_value
16+
// CHECK: %0 = tuple
17+
// CHECK-NEXT: return
18+
// CHECK: } // end sil function 'remove_dead_keypath_ossa'
19+
sil [ossa] @remove_dead_keypath_ossa : $@convention(thin) () -> () {
20+
bb0:
21+
%0 = keypath $WritableKeyPath<S, Int>, (root $S; stored_property #S.b : $Int)
22+
%1 = upcast %0 : $WritableKeyPath<S, Int> to $KeyPath<S, Int>
23+
%2 = begin_borrow %1 : $KeyPath<S, Int>
24+
end_borrow %2 : $KeyPath<S, Int>
25+
%4 = copy_value %1 : $KeyPath<S, Int>
26+
%5 = move_value %4 : $KeyPath<S, Int>
27+
destroy_value %1 : $KeyPath<S, Int>
28+
destroy_value %5 : $KeyPath<S, Int>
29+
%r = tuple()
30+
return %r : $()
31+
}
32+
33+
// CHECK-LABEL: sil @remove_dead_keypath :
34+
// CHECK-NOT: keypath
35+
// CHECK-NOT: strong_release
36+
// CHECK: %0 = tuple
37+
// CHECK-NEXT: return
38+
// CHECK: } // end sil function 'remove_dead_keypath'
39+
sil @remove_dead_keypath : $@convention(thin) () -> () {
40+
bb0:
41+
%0 = keypath $WritableKeyPath<S, Int>, (root $S; stored_property #S.b : $Int)
42+
%1 = upcast %0 : $WritableKeyPath<S, Int> to $KeyPath<S, Int>
43+
strong_release %1 : $KeyPath<S, Int>
44+
%r = tuple()
45+
return %r : $()
46+
}
47+

0 commit comments

Comments
 (0)