Skip to content

Commit f1c6ed6

Browse files
committed
Swift Optimizer: add Onone simplification of apply instructions
1 parent 7eb2cb8 commit f1c6ed6

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

99
swift_compiler_sources(Optimizer
10+
SimplifyApply.swift
1011
SimplifyBeginCOWMutation.swift
1112
SimplifyGlobalValue.swift
1213
SimplifyStrongRetainRelease.swift)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===--- SimplifyApply.swift ----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
15+
extension ApplyInst : OnoneSimplifyable {
16+
func simplify(_ context: SimplifyContext) {
17+
tryReplaceTrivialApplyOfPartialApply(context)
18+
}
19+
}
20+
21+
private extension ApplyInst {
22+
func tryReplaceTrivialApplyOfPartialApply(_ context: SimplifyContext) {
23+
guard let pa = callee as? PartialApplyInst else {
24+
return
25+
}
26+
27+
if pa.referencedFunction == nil {
28+
return
29+
}
30+
31+
// Currently we don't handle generic closures. For Onone this is good enough.
32+
// TODO: handle it once we replace the SILCombine simplification with this.
33+
if !allArgumentsAreTrivial(arguments) {
34+
return
35+
}
36+
37+
if !allArgumentsAreTrivial(pa.arguments) {
38+
return
39+
}
40+
41+
if !substitutionMap.isEmpty {
42+
return
43+
}
44+
45+
let allArgs = Array<Value>(arguments) + Array<Value>(pa.arguments)
46+
let builder = Builder(before: self, context)
47+
let newApply = builder.createApply(function: pa.callee, pa.substitutionMap, arguments: allArgs,
48+
isNonThrowing: isNonThrowing, isNonAsync: isNonAsync,
49+
specializationInfo: specializationInfo)
50+
uses.replaceAll(with: newApply, context)
51+
context.erase(instruction: self)
52+
53+
if context.tryDeleteDeadClosure(closure: pa) {
54+
context.notifyInvalidatedStackNesting()
55+
}
56+
}
57+
}
58+
59+
private func allArgumentsAreTrivial(_ args: LazyMapSequence<OperandArray, Value>) -> Bool {
60+
return !args.contains { !$0.hasTrivialType }
61+
}

test/SILOptimizer/simplify_apply.sil

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=apply | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
5+
import Swift
6+
import Builtin
7+
8+
sil @closure_with_args : $@convention(thin) (Int, Bool) -> ()
9+
sil @closure2_with_args : $@convention(thin) (Int, String) -> ()
10+
sil @closure3_with_args : $@convention(thin) (String, Bool) -> ()
11+
sil @generic_callee_inguaranteed : $@convention(thin) <T, U> (@in_guaranteed T, @in_guaranteed U) -> ()
12+
13+
// CHECK-LABEL: sil @test_apply_of_partial_apply
14+
// CHECK: [[F:%.*]] = function_ref @closure_with_args
15+
// CHECK-NOT: partial_apply
16+
// CHECK: apply [[F]](%0, %1)
17+
// CHECK: } // end sil function 'test_apply_of_partial_apply'
18+
sil @test_apply_of_partial_apply : $@convention(thin) (Int, Bool) -> () {
19+
bb0(%0 : $Int, %1 : $Bool):
20+
%2 = function_ref @closure_with_args : $@convention(thin) (Int, Bool) -> ()
21+
%3 = partial_apply %2(%1) : $@convention(thin) (Int, Bool) -> ()
22+
apply %3(%0) : $@callee_owned (Int) -> ()
23+
%r = tuple()
24+
return %r : $()
25+
}
26+
27+
// Currently this is not optimized by the simplification passes.
28+
// TODO: change the check lines if we can handle generic closures
29+
30+
// CHECK-LABEL: sil @test_generic_partial_apply_apply_inguaranteed
31+
// CHECK: [[F:%.*]] = function_ref @generic_callee_inguaranteed
32+
// CHECK: [[PA:%.*]] = partial_apply [[F]]
33+
// CHECK: apply [[PA]]
34+
// CHECK: } // end sil function 'test_generic_partial_apply_apply_inguaranteed'
35+
sil @test_generic_partial_apply_apply_inguaranteed : $@convention(thin) <T> (@in T, @in T) -> () {
36+
bb0(%0 : $*T, %1 : $*T):
37+
%f1 = function_ref @generic_callee_inguaranteed : $@convention(thin) <T, U> (@in_guaranteed T, @in_guaranteed U) -> ()
38+
%pa = partial_apply %f1<T, T>(%1) : $@convention(thin) <T, U> (@in_guaranteed T, @in_guaranteed U) -> ()
39+
%a1 = apply %pa(%0) : $@callee_owned (@in_guaranteed T) -> ()
40+
destroy_addr %0 : $*T
41+
%r = tuple ()
42+
return %r : $()
43+
}
44+
45+
// Currently this is not optimized by the simplification passes.
46+
// TODO: change the check lines if we can handle non-trivial arguments
47+
48+
// CHECK-LABEL: sil @dont_handle_non_trivial_pa_args
49+
// CHECK: [[F:%.*]] = function_ref @closure2_with_args
50+
// CHECK: [[PA:%.*]] = partial_apply [[F]]
51+
// CHECK: apply [[PA]]
52+
// CHECK: } // end sil function 'dont_handle_non_trivial_pa_args'
53+
sil @dont_handle_non_trivial_pa_args : $@convention(thin) (Int, String) -> () {
54+
bb0(%0 : $Int, %1 : $String):
55+
%2 = function_ref @closure2_with_args : $@convention(thin) (Int, String) -> ()
56+
%3 = partial_apply %2(%1) : $@convention(thin) (Int, String) -> ()
57+
apply %3(%0) : $@callee_owned (Int) -> ()
58+
%r = tuple()
59+
return %r : $()
60+
}
61+
62+
// Currently this is not optimized by the simplification passes.
63+
// TODO: change the check lines if we can handle non-trivial arguments
64+
65+
// CHECK-LABEL: sil @dont_handle_non_trivial_apply_args
66+
// CHECK: [[F:%.*]] = function_ref @closure3_with_args
67+
// CHECK: [[PA:%.*]] = partial_apply [[F]]
68+
// CHECK: apply [[PA]]
69+
// CHECK: } // end sil function 'dont_handle_non_trivial_apply_args'
70+
sil @dont_handle_non_trivial_apply_args : $@convention(thin) (String, Bool) -> () {
71+
bb0(%0 : $String, %1 : $Bool):
72+
%2 = function_ref @closure3_with_args : $@convention(thin) (String, Bool) -> ()
73+
%3 = partial_apply %2(%1) : $@convention(thin) (String, Bool) -> ()
74+
apply %3(%0) : $@callee_owned (String) -> ()
75+
%r = tuple()
76+
return %r : $()
77+
}
78+

0 commit comments

Comments
 (0)