mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Swift's readonly and readnone should not be automatically mapped to LLVM's readonly. Swift SIL optimizer relies on @effects(readonly) to remove e.g. dead code remaining from initializers of strings or dictionaries of variables that are not used. But those initializers are often not really readonly in terms of LLVM IR. For example, the Dictionary.init() is marked as @effects(readonly) in Swift, but it does invoke reference-counting operations. As a result, it leads to miscompiles and runtime crashes. In the future, we may add the functionality to analyze the body of the function and if we can prove that is really readonly, we can map it to the LLVM readonly attribute. I checked that removal of this mapping does not affect the performance of any of our existing benchmarks. Fixes rdar://problem/28830504
68 lines
2.1 KiB
Plaintext
68 lines
2.1 KiB
Plaintext
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-ir %s | %FileCheck %s
|
|
//sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
private class XXX{}
|
|
|
|
sil @XXX_dtor : $@convention(method) (@owned XXX) -> ()
|
|
sil @XXX_ctor : $@convention(method) (@owned XXX) -> @owned XXX
|
|
|
|
// CHECK: target datalayout
|
|
|
|
// No @owned or @out parameters -- function is not read only at LLVM level,
|
|
// because Swift level read only attribute is not automatically mapped
|
|
// to the LLVM read only attribute, unless IRGen can prove by analyzing
|
|
// the function body that this function is really read only.
|
|
|
|
// CHECK-NOT: ; Function Attrs: readonly
|
|
// CHECK: define{{( protected)?}} swiftcc void @function_foo(
|
|
sil [readonly] @function_foo : $@convention(thin) (Int) -> () {
|
|
bb0(%0 : $Int):
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|
|
|
|
// No @owned or @out parameters -- function is not read only at LLVM level,
|
|
// because Swift level read none attribute is not automatically mapped
|
|
// to the LLVM read only attribute, unless IRGen can prove by analyzing
|
|
// the function body that this function is really read only or read none.
|
|
|
|
// CHECK-NOT: ; Function Attrs: readonly
|
|
// CHECK: define{{( protected)?}} swiftcc void @function_foo2(
|
|
sil [readnone] @function_foo2 : $@convention(thin) (Int) -> () {
|
|
bb0(%0 : $Int):
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|
|
|
|
// There's an @owned parameter, and destructors can call arbitrary code
|
|
// -- function is not read only at LLVM level
|
|
|
|
// CHECK-NOT: ; Function Attrs: readonly
|
|
// CHECK: define{{( protected)?}} swiftcc void @function_bar(
|
|
sil [readonly] @function_bar : $@convention(thin) (@owned XXX) -> () {
|
|
bb0(%0 : $XXX):
|
|
strong_release %0 : $XXX
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|
|
|
|
// There's an @out parameter -- function is not read only at LLVM level
|
|
|
|
// CHECK-NOT: ; Function Attrs: readonly
|
|
// CHECK: define{{( protected)?}} swiftcc void @function_baz(
|
|
sil [readonly] @function_baz : $@convention(thin) () -> (@out Any) {
|
|
bb0(%0 : $*Any):
|
|
init_existential_addr %0 : $*Any, $()
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|
|
|
|
sil_vtable XXX {
|
|
#XXX.deinit!deallocator: XXX_dtor
|
|
#XXX.init!initializer.1: XXX_ctor
|
|
}
|