From 844217d58cbd351609365d00f7342cdc7c1bf47e Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 3 Sep 2025 17:49:55 +0200 Subject: [PATCH] Optimizer: replace `explicit_copy_value` and `explicit_copy_addr` with their non-explicit counterparts The `explicit_copy_value` and `explicit_copy_addr` instructions are only used for non-copyable diagnostics in the mandatory pipeline. After that we can replace them by their non-explicit counterparts so that optimizations (which only know of `copy_value` and `copy_addr`) can do their work. rdar://159039552 --- .../InstructionSimplification/CMakeLists.txt | 1 + .../SimplifyExplicitCopy.swift | 64 +++++++++++++++++++ .../SILCombiner/Simplifications.def | 2 + .../simplify_explicit_copy_addr.sil | 38 +++++++++++ .../simplify_explicit_copy_value.sil | 21 ++++++ 5 files changed, 126 insertions(+) create mode 100644 SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyExplicitCopy.swift create mode 100644 test/SILOptimizer/simplify_explicit_copy_addr.sil create mode 100644 test/SILOptimizer/simplify_explicit_copy_value.sil diff --git a/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt b/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt index be95415331968..132b43780581d 100644 --- a/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt +++ b/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt @@ -25,6 +25,7 @@ swift_compiler_sources(Optimizer SimplifyDestroyValue.swift SimplifyDestructure.swift SimplifyEndCOWMutationAddr.swift + SimplifyExplicitCopy.swift SimplifyFixLifetime.swift SimplifyGlobalValue.swift SimplifyInitEnumDataAddr.swift diff --git a/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyExplicitCopy.swift b/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyExplicitCopy.swift new file mode 100644 index 0000000000000..3afabf24f7754 --- /dev/null +++ b/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyExplicitCopy.swift @@ -0,0 +1,64 @@ +//===--- SimplifyExplicitCopy.swift ---------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import SIL + +// The `explicit_copy_value` and `explicit_copy_addr` instructions are only used for non-copyable +// diagnostics in the mandatory pipeline. After that we can replace them by their non-explicit counterparts +// so that optimizations (which only know of `copy_value` and `copy_addr`) can do their work. + +/// Replaces +/// +/// ``` +/// %1 = explicit_copy_value %0 +/// ``` +/// -> +/// ``` +/// %1 = copy_value %0 +/// ``` +/// +extension ExplicitCopyValueInst : Simplifiable, SILCombineSimplifiable { + func simplify(_ context: SimplifyContext) { + if context.silStage == .raw { + // Make sure we don't remove `explicit_copy_value` in the diagnostic pipeline. + return + } + + let builder = Builder(before: self, context) + let copyValue = builder.createCopyValue(operand: fromValue) + replace(with: copyValue, context) + } +} + +/// Replaces +/// +/// ``` +/// explicit_copy_addr %0 to %1 +/// ``` +/// -> +/// ``` +/// copy_addr %0 to %1 +/// ``` +/// +extension ExplicitCopyAddrInst : Simplifiable, SILCombineSimplifiable { + func simplify(_ context: SimplifyContext) { + if context.silStage == .raw { + // Make sure we don't remove `explicit_copy_addr` in the diagnostic pipeline. + return + } + + let builder = Builder(before: self, context) + builder.createCopyAddr(from: source, to: destination, + takeSource: isTakeOfSource, initializeDest: isInitializationOfDestination) + context.erase(instruction: self) + } +} diff --git a/lib/SILOptimizer/SILCombiner/Simplifications.def b/lib/SILOptimizer/SILCombiner/Simplifications.def index 87f3ff0d5725b..34f646e8c20a0 100644 --- a/lib/SILOptimizer/SILCombiner/Simplifications.def +++ b/lib/SILOptimizer/SILCombiner/Simplifications.def @@ -32,6 +32,8 @@ INSTRUCTION_SIMPLIFICATION(BeginBorrowInst) INSTRUCTION_SIMPLIFICATION(BeginCOWMutationInst) INSTRUCTION_SIMPLIFICATION(ClassifyBridgeObjectInst) +INSTRUCTION_SIMPLIFICATION(ExplicitCopyAddrInst) +INSTRUCTION_SIMPLIFICATION(ExplicitCopyValueInst) INSTRUCTION_SIMPLIFICATION(FixLifetimeInst) INSTRUCTION_SIMPLIFICATION(GlobalValueInst) INSTRUCTION_SIMPLIFICATION(StrongRetainInst) diff --git a/test/SILOptimizer/simplify_explicit_copy_addr.sil b/test/SILOptimizer/simplify_explicit_copy_addr.sil new file mode 100644 index 0000000000000..af80a70ab455a --- /dev/null +++ b/test/SILOptimizer/simplify_explicit_copy_addr.sil @@ -0,0 +1,38 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=explicit_copy_addr | %FileCheck %s --check-prefix=CHECK-ONONE --check-prefix=CHECK +// RUN: %target-sil-opt -enable-sil-verify-all %s -simplification -simplify-instruction=explicit_copy_addr | %FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK + +// REQUIRES: swift_in_compiler + +sil_stage canonical + +import Swift +import Builtin + +// CHECK-LABEL: sil [ossa] @simplify_copy_take_init : +// CHECK: bb0(%0 : $*String, %1 : $*String): +// CHECK-O-NEXT: {{ }}copy_addr [take] %1 to [init] %0 +// CHECK-ONONE-NEXT: explicit_copy_addr [take] %1 to [init] %0 +// CHECK-NEXT: %3 = tuple () +// CHECK: } // end sil function 'simplify_copy_take_init' +sil [ossa] @simplify_copy_take_init : $@convention(thin) (@in String) -> @out String { +bb0(%0 : $*String, %1 : $*String): + explicit_copy_addr [take] %1 to [init] %0 + %3 = tuple () + return %3 +} + +// CHECK-LABEL: sil [ossa] @simplify_copy_assign : +// CHECK: bb0(%0 : $*String, %1 : $*String): +// CHECK-O-NEXT: {{ }}copy_addr %1 to %0 +// CHECK-ONONE-NEXT: explicit_copy_addr %1 to %0 +// CHECK-NEXT: %3 = tuple () +// CHECK: } // end sil function 'simplify_copy_assign' +sil [ossa] @simplify_copy_assign : $@convention(thin) (@inout String, @inout String) -> () { +bb0(%0 : $*String, %1 : $*String): + explicit_copy_addr %1 to %0 + %3 = tuple () + return %3 +} + + + diff --git a/test/SILOptimizer/simplify_explicit_copy_value.sil b/test/SILOptimizer/simplify_explicit_copy_value.sil new file mode 100644 index 0000000000000..e8edea597093d --- /dev/null +++ b/test/SILOptimizer/simplify_explicit_copy_value.sil @@ -0,0 +1,21 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=explicit_copy_value | %FileCheck %s --check-prefix=CHECK-ONONE --check-prefix=CHECK +// RUN: %target-sil-opt -enable-sil-verify-all %s -simplification -simplify-instruction=explicit_copy_value | %FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK + +// REQUIRES: swift_in_compiler + +sil_stage canonical + +import Swift +import Builtin + +// CHECK-LABEL: sil [ossa] @simplify_explicit_copy_value : +// CHECK-O: %1 = copy_value %0 +// CHECK-ONONE: %1 = explicit_copy_value %0 +// CHECK-NEXT: return %1 +// CHECK: } // end sil function 'simplify_explicit_copy_value' +sil [ossa] @simplify_explicit_copy_value : $@convention(thin) (@guaranteed String) -> @owned String { +bb0(%0 : @guaranteed $String): + %1 = explicit_copy_value %0 + return %1 +} +