mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #85482 from meg-gupta/reduceendcowmutation
Avoid inserting end_cow_mutation_addr in some common cases
This commit is contained in:
@@ -142,6 +142,10 @@ let lifetimeDependenceScopeFixupPass = FunctionPass(
|
||||
|
||||
private extension Type {
|
||||
func mayHaveMutableSpan(in function: Function, _ context: FunctionPassContext) -> Bool {
|
||||
// Escapable and Copyable types cannot have MutableSpan
|
||||
if isEscapable || !isMoveOnly {
|
||||
return false
|
||||
}
|
||||
if hasArchetype {
|
||||
return true
|
||||
}
|
||||
@@ -176,6 +180,24 @@ private extension Type {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Returns true if a type maybe Array/ArraySlice/ContiguousArray which are optimized COW types.
|
||||
// The standard library introduces builtins begin_cow_mutation/end_cow_mutation for such types which are then used to optimize uniqueness checks.
|
||||
func mayHaveOptimizedCOWType(in function: Function) -> Bool {
|
||||
// Trivial types cannot be Array/ArraySlice/ContiguousArray.
|
||||
if isTrivial(in: function) {
|
||||
return false
|
||||
}
|
||||
// Builtin types do not contain Array/ArraySlice/ContiguousArray.
|
||||
if isBuiltinType {
|
||||
return false
|
||||
}
|
||||
// ~Copyable types cannot contain Array/ArraySlice/ContiguousArray.
|
||||
if isMoveOnly {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert end_cow_mutation_addr for lifetime dependent values that maybe of type MutableSpan and depend on a mutable address.
|
||||
@@ -203,7 +225,8 @@ private func createEndCOWMutationIfNeeded(lifetimeDep: LifetimeDependence, _ con
|
||||
return
|
||||
}
|
||||
|
||||
guard lifetimeDep.dependentValue.type.mayHaveMutableSpan(in: lifetimeDep.dependentValue.parentFunction, context) else {
|
||||
guard lifetimeDep.dependentValue.type.mayHaveMutableSpan(in: lifetimeDep.dependentValue.parentFunction, context) &&
|
||||
lifetimeDep.parentValue.type.mayHaveOptimizedCOWType(in: lifetimeDep.dependentValue.parentFunction) else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// RUN: %target-swift-frontend -O -emit-sil %s -disable-availability-checking | %FileCheck %s --check-prefix=CHECK-SIL
|
||||
|
||||
public protocol P {
|
||||
mutating func mutate(_ other: Self)
|
||||
}
|
||||
|
||||
// CHECK-SIL-LABEL: sil @$s38mutable_span_stdlib_bounds_check_tests0a1_B7_doubleyys11MutableSpanVyxGzAA1PRzlF :
|
||||
// CHECK-SIL: bb3({{.*}}):
|
||||
// CHECK-SIL-NOT: end_cow_mutation
|
||||
// CHECK-SIL-NOT: cond_fail "index out of bounds"
|
||||
// CHECK-SIL-LABEL: } // end sil function '$s38mutable_span_stdlib_bounds_check_tests0a1_B7_doubleyys11MutableSpanVyxGzAA1PRzlF'
|
||||
public func mutable_span_double<T: P>(_ ms: inout MutableSpan<T>) {
|
||||
for i in ms.indices {
|
||||
ms[i].mutate(ms[i])
|
||||
}
|
||||
}
|
||||
|
||||
extension Int : P {
|
||||
public mutating func mutate(_ other: Int) {
|
||||
self += other
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-SIL-LABEL: sil @$s38mutable_span_stdlib_bounds_check_tests17specializedCalleryySaySiGzF : $@convention(thin) (@inout Array<Int>) -> () {
|
||||
// CHECK-SIL-NOT: cond_fail "index out of bounds"
|
||||
// CHECK-SIL-LABEL: } // end sil function '$s38mutable_span_stdlib_bounds_check_tests17specializedCalleryySaySiGzF'
|
||||
public func specializedCaller(_ array: inout Array<Int>) {
|
||||
var mut = array.mutableSpan
|
||||
mutable_span_double(&mut)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user