Skip to content

Commit 31e01a5

Browse files
committed
CopyForwarding: More places to check whether we have a function arg
1 parent 2f81e4e commit 31e01a5

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

lib/SILOptimizer/Transforms/CopyForwarding.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ static bool isIdentifiedSourceValue(SILValue Def) {
121121
/// (2) A local alloc_stack variable.
122122
static bool isIdentifiedDestValue(SILValue Def) {
123123
if (SILArgument *Arg = dyn_cast<SILArgument>(Def)) {
124+
if (!Arg->isFunctionArg())
125+
return false;
124126
// Check that the argument is passed as an out type. This means there are
125127
// no aliases accessible within this function scope.
126128
ParameterConvention Conv = Arg->getParameterInfo().getConvention();
@@ -1107,6 +1109,9 @@ static bool canNRVO(CopyAddrInst *CopyInst) {
11071109
if (!OutArg)
11081110
return false;
11091111

1112+
if (!OutArg->isFunctionArg())
1113+
return false;
1114+
11101115
auto ArgConv = OutArg->getParameterInfo().getConvention();
11111116
if (ArgConv != ParameterConvention::Indirect_Out)
11121117
return false;

test/SILOptimizer/copyforward.sil

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,32 @@ bb3: // Preds: bb1 bb2
5252
return %18 : $() // id: %20
5353
}
5454

55+
56+
// CHECK-LABEL: dont_assert_nrvo
57+
// CHECK: return
58+
59+
sil hidden @dont_assert_nrvo : $@convention(thin) <T where T : P> (@out T, Bool) -> () {
60+
bb0(%0 : $*T, %1 : $Bool):
61+
%2 = alloc_stack $T, var, name "ro" // users: %9, %15, %17, %19
62+
debug_value_addr %0 : $*T
63+
debug_value_addr %2 : $*T
64+
%3 = struct_extract %1 : $Bool, #Bool._value // user: %4
65+
%5 = metatype $@thick T.Type // user: %9
66+
%6 = witness_method $T, #P.init!allocator.1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () // user: %9
67+
%7 = integer_literal $Builtin.Int32, 10 // user: %8
68+
%8 = struct $Int32 (%7 : $Builtin.Int32) // user: %9
69+
%9 = apply %6<T>(%2, %8, %5) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> ()
70+
br bb3(%0 : $*T)
71+
72+
bb3(%10 : $*T): // Preds: bb1 bb2
73+
copy_addr [take] %2 to [initialization] %10 : $*T // id: %17
74+
%18 = tuple () // user: %20
75+
debug_value_addr %0 : $*T
76+
debug_value_addr %2 : $*T
77+
dealloc_stack %2 : $*T // id: %19
78+
return %18 : $() // id: %20
79+
}
80+
5581
//CHECK-LABEL: forward_init
5682
//CHECK-NOT: copy_addr
5783
//CHECK-NOT: destroy_addr
@@ -170,6 +196,26 @@ bb0(%0 : $*T):
170196
return %t : $()
171197
}
172198

199+
//CHECK-LABEL: dont_assert_backward_init
200+
//CHECK: return
201+
sil hidden @dont_assert_backward_init : $@convention(thin) <T> (@out T) -> () {
202+
bb0(%0 : $*T):
203+
%l1 = alloc_stack $T
204+
br bb1(%0: $*T)
205+
206+
bb1(%1 : $*T):
207+
%f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> ()
208+
%c1 = apply %f1<T>(%l1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> ()
209+
debug_value_addr %0 : $*T
210+
debug_value_addr %l1 : $*T
211+
copy_addr %l1 to [initialization] %0 : $*T
212+
debug_value_addr %0 : $*T
213+
debug_value_addr %l1 : $*T
214+
destroy_addr %l1 : $*T
215+
dealloc_stack %l1 : $*T
216+
%t = tuple ()
217+
return %t : $()
218+
}
173219
//CHECK-LABEL: backward_noinit
174220
//CHECK: copy_addr
175221
//CHECK: destroy_addr

0 commit comments

Comments
 (0)