Files
swift-mirror/test/Serialization/generated-ref-to-nserror.swift
Erik Eckstein 8aa911ba2f Optimizer: add simplifications for destroy_value
Attempt to optimize by forwarding the destroy to operands of forwarding instructions.

```
  %3 = struct $S (%1, %2)
  destroy_value %3         // the only use of %3
```
->
```
  destroy_value %1
  destroy_value %2
```

The benefit of this transformation is that the forwarding instruction can be removed.

Also, handle `destroy_value` for phi arguments.
This is a more complex case where the destroyed value comes from different predecessors via a phi argument.
The optimization moves the `destroy_value` to each predecessor block.

```
bb1:
  br bb3(%0)
bb2:
  br bb3(%1)
bb3(%3 : @owned T):
  ...                // no deinit-barriers
  destroy_value %3   // the only use of %3
```
->
```
bb1:
  destroy_value %0
  br bb3
bb2:
  destroy_value %1
  br bb3
bb3:
  ...
```
2025-12-03 15:53:55 +01:00

160 lines
6.3 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: split-file %s %t --leading-lines
// REQUIRES: objc_interop
/// Build a minimal version of Foundation defining only NSError
// RUN: %target-swift-frontend -emit-module %t/Foundation.swift \
// RUN: -o %t/Foundation.swiftmodule
// RUN: %target-swift-frontend -emit-module %t/FoundationExporter.swift -I%t \
// RUN: -o %t/FoundationExporter.swiftmodule
/// Enabled existential to NSError optimization
// CHECK-OPTIMIZED: $NSError
/// Optimize Foundation itself
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
// RUN: -swift-version 5 -enable-library-evolution \
// RUN: %t/Foundation.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
/// Public import or non-resilient modules
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
// RUN: -swift-version 5 -enable-library-evolution -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/inlinable-public.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/inlinable-public.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/inlinable-internal.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
/// Foundation is imported from a different file
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/inlinable-not-imported-fileA.swift \
// RUN: %t/inlinable-not-imported-fileB.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main \
// RUN: -swift-version 5 -enable-library-evolution -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/inlinable-not-imported-fileA.swift \
// RUN: %t/inlinable-not-imported-fileB.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
/// Foundation is imported via a transitive dependency
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/inlinable-imported-transitive.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
/// Any non-inlinable uses
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/non-inlinable-public.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/non-inlinable-ioi.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/non-inlinable-internal.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/non-inlinable-not-imported-fileA.swift \
// RUN: %t/non-inlinable-not-imported-fileB.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: -swift-version 5 -enable-library-evolution \
// RUN: %t/non-inlinable-not-imported-fileA.swift \
// RUN: %t/non-inlinable-not-imported-fileB.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
/// Disabled existential to NSError optimization
// CHECK-NOT-OPTIMIZED-NOT: $NSError
/// Implementation-only import
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: %t/inlinable-ioi.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-NOT-OPTIMIZED --input-file %t/main.sil %s
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: -swift-version 5 -enable-library-evolution \
// RUN: %t/inlinable-ioi.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-NOT-OPTIMIZED --input-file %t/main.sil %s
/// Internal import from resilient module
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -Xllvm -sil-disable-pass=simplify-destroy_value \
// RUN: -swift-version 5 -enable-library-evolution \
// RUN: %t/inlinable-internal.swift > %t/main.sil
// RUN: %FileCheck --check-prefix CHECK-NOT-OPTIMIZED --input-file %t/main.sil %s
//--- Foundation.swift
class NSError {}
@inlinable public func foo<E: Error>(e: E) -> Error {
return e
}
//--- FoundationExporter.swift
@_exported import Foundation
//--- inlinable-public.swift
public import Foundation
@inlinable public func foo<E: Error>(e: E) -> Error {
return e
}
//--- inlinable-ioi.swift
@_implementationOnly import Foundation
@inlinable public func foo<E: Error>(e: E) -> Error {
return e
}
//--- inlinable-internal.swift
internal import Foundation
@inlinable public func foo<E: Error>(e: E) -> Error {
return e
}
//--- inlinable-not-imported-fileA.swift
@inlinable public func foo<E: Error>(e: E) -> Error {
return e
}
//--- inlinable-not-imported-fileB.swift
import Foundation
//--- inlinable-imported-transitive.swift
public import FoundationExporter
@inlinable public func foo<E: Error>(e: E) -> Error {
return e
}
//--- non-inlinable-public.swift
public import Foundation
public func foo<E: Error>(e: E) -> Error {
return e
}
//--- non-inlinable-ioi.swift
@_implementationOnly import Foundation
public func foo<E: Error>(e: E) -> Error {
return e
}
//--- non-inlinable-internal.swift
internal import Foundation
public func foo<E: Error>(e: E) -> Error {
return e
}
//--- non-inlinable-not-imported-fileA.swift
public func foo<E: Error>(e: E) -> Error {
return e
}
//--- non-inlinable-not-imported-fileB.swift
import Foundation