Files
swift-mirror/test/SILOptimizer/simplify_raw_pointer_to_ref.sil
Erik Eckstein ec74abb6c9 Optimizer: add an optimization to set the immortal flag on raw_pointer_to_ref
Add a `raw_pointer_to_ref` instruction simplification which sets the
`immortal` flag if the instruction is used to create an empty collection
singleton, i.e. if the pattern is

    %0 = global_addr @_swiftEmptyArrayStorage
    %1 = address_to_pointer %0
    %2 = raw_pointer_to_ref %1

and the Swift 5.1 runtime is available on the deployment target. Since
Swift 5.1 such statically allocated objects have immortal reference
counts, so retaining and releasing them is a no-op.

This moves the pattern matching out of the strong_retain/strong_release
simplification, which now only needs to check the flag.
2026-09-21 08:48:01 +02:00

72 lines
2.3 KiB
Plaintext

// RUN: %target-sil-opt %s -simplification -simplify-instruction=raw_pointer_to_ref | %FileCheck %s
sil_stage canonical
import Builtin
struct EmptyArrayStorage {
var t: Builtin.Int64
}
class C {}
// The empty collection singletons (and the other objects which are created with
// `raw_pointer_to_ref`) are immortal if the swift 5.1 runtime is available.
sil_global @emptyArrayStorage : $EmptyArrayStorage
// CHECK-LABEL: sil [ossa] @set_immortal_flag :
// CHECK: %2 = raw_pointer_to_ref [immortal] %1 to $C
// CHECK: } // end sil function 'set_immortal_flag'
sil [ossa] @set_immortal_flag : $@convention(thin) () -> () {
bb0:
%0 = global_addr @emptyArrayStorage : $*EmptyArrayStorage
%1 = address_to_pointer %0 to $Builtin.RawPointer
%2 = raw_pointer_to_ref %1 to $C
fix_lifetime %2
destroy_value %2
%3 = tuple ()
return %3
}
// CHECK-LABEL: sil [ossa] @keep_immortal_flag :
// CHECK: %1 = raw_pointer_to_ref [immortal] %0 to $C
// CHECK: } // end sil function 'keep_immortal_flag'
sil [ossa] @keep_immortal_flag : $@convention(thin) (Builtin.RawPointer) -> () {
bb0(%0 : $Builtin.RawPointer):
%1 = raw_pointer_to_ref [immortal] %0 to $C
fix_lifetime %1
%3 = tuple ()
return %3
}
// CHECK-LABEL: sil [ossa] @dont_set_immortal_flag_on_unknown_pointer :
// CHECK: %1 = raw_pointer_to_ref %0 to $C
// CHECK: } // end sil function 'dont_set_immortal_flag_on_unknown_pointer'
sil [ossa] @dont_set_immortal_flag_on_unknown_pointer : $@convention(thin) (Builtin.RawPointer) -> () {
bb0(%0 : $Builtin.RawPointer):
%1 = raw_pointer_to_ref %0 to $C
fix_lifetime %1
destroy_value %1
%3 = tuple ()
return %3
}
// A serialized function can be inlined into a client with an older deployment
// target, therefore the swift 5.1 runtime cannot be assumed to be available.
// CHECK-LABEL: sil [serialized] [ossa] @dont_set_immortal_flag_in_serialized_function :
// CHECK: %2 = raw_pointer_to_ref %1 to $C
// CHECK: } // end sil function 'dont_set_immortal_flag_in_serialized_function'
sil [serialized] [ossa] @dont_set_immortal_flag_in_serialized_function : $@convention(thin) () -> () {
bb0:
%0 = global_addr @emptyArrayStorage : $*EmptyArrayStorage
%1 = address_to_pointer %0 to $Builtin.RawPointer
%2 = raw_pointer_to_ref %1 to $C
fix_lifetime %2
destroy_value %2
%3 = tuple ()
return %3
}