From d1fcc52e4494c5763d0d967b86ef17f02aa904c4 Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Tue, 15 Aug 2023 12:19:13 -0700 Subject: [PATCH 1/3] [SIL] ApplySite: Get args by callee index. Added convenience functions to ApplySite to access argument and argument operand by index into the callee's argument list (rather than by index into the arguments used by the apply instruction). --- include/swift/SIL/ApplySite.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index 17755694aa864..59ff025996d38 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -295,9 +295,20 @@ class ApplySite { /// Return the apply operand for the given applied argument index. Operand &getArgumentRef(unsigned i) const { return getArgumentOperands()[i]; } + // The apply operand at the given index into the callee's function's + // arguments. + Operand &getArgumentRefAtCalleeArgIndex(unsigned i) const { + return getArgumentRef(i - getCalleeArgIndexOfFirstAppliedArg()); + } + /// Return the ith applied argument. SILValue getArgument(unsigned i) const { return getArguments()[i]; } + // The argument at the given index into the callee's function's arguments. + SILValue getArgumentAtCalleeArgIndex(unsigned i) const { + return getArgument(i - getCalleeArgIndexOfFirstAppliedArg()); + } + /// Set the ith applied argument. void setArgument(unsigned i, SILValue V) const { getArgumentOperands()[i].set(V); From 5c31339028c6c06979ef9b442f30f8c68c021130 Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Tue, 15 Aug 2023 12:28:26 -0700 Subject: [PATCH 2/3] [AddressLowering] Loosen assert for partial_apply. Full apply instructions have the same number of arguments as the callee has parameters. Partial apply instructions have some number less than or equal to the number of callee parameters. --- lib/SILOptimizer/Mandatory/AddressLowering.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/SILOptimizer/Mandatory/AddressLowering.cpp b/lib/SILOptimizer/Mandatory/AddressLowering.cpp index be708a67a0a81..f62e720da460e 100644 --- a/lib/SILOptimizer/Mandatory/AddressLowering.cpp +++ b/lib/SILOptimizer/Mandatory/AddressLowering.cpp @@ -2190,8 +2190,11 @@ bool CallArgRewriter::rewriteArguments() { bool changed = false; auto origConv = apply.getSubstCalleeConv(); - assert(apply.getNumArguments() == origConv.getNumParameters() && - "results should not yet be rewritten"); + assert((apply.getNumArguments() == origConv.getNumParameters() && + apply.asFullApplySite()) || + (apply.getNumArguments() <= origConv.getNumParameters() && + !apply.asFullApplySite()) && + "results should not yet be rewritten"); for (unsigned argIdx = apply.getCalleeArgIndexOfFirstAppliedArg(), endArgIdx = argIdx + apply.getNumArguments(); From 35113d8a8071a26f914487208f2d0e229e675493 Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Tue, 15 Aug 2023 12:30:04 -0700 Subject: [PATCH 3/3] [AddressLowering] Fix partial_apply arg indexing. When rewriting arguments, the index used is into the callee's argument list. For full applies, that is identical to the index into the instruction's argument list. For partial applies, it is not. Previously, though, the index was used as if it were an index into the instruction's argument list to get an argument ref. Here, use instead the newly added convenience to get the argument ref using the index into the callee's arguments. --- lib/SILOptimizer/Mandatory/AddressLowering.cpp | 2 +- test/SILOptimizer/address_lowering.sil | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/SILOptimizer/Mandatory/AddressLowering.cpp b/lib/SILOptimizer/Mandatory/AddressLowering.cpp index f62e720da460e..dade537b68bc8 100644 --- a/lib/SILOptimizer/Mandatory/AddressLowering.cpp +++ b/lib/SILOptimizer/Mandatory/AddressLowering.cpp @@ -2200,7 +2200,7 @@ bool CallArgRewriter::rewriteArguments() { endArgIdx = argIdx + apply.getNumArguments(); argIdx < endArgIdx; ++argIdx) { - Operand &operand = apply.getArgumentRef(argIdx); + Operand &operand = apply.getArgumentRefAtCalleeArgIndex(argIdx); // Ignore arguments that have already been rewritten with an address. if (operand.get()->getType().isAddress()) continue; diff --git a/test/SILOptimizer/address_lowering.sil b/test/SILOptimizer/address_lowering.sil index 841acb2b5003e..1ee4ff01d12c8 100644 --- a/test/SILOptimizer/address_lowering.sil +++ b/test/SILOptimizer/address_lowering.sil @@ -2619,6 +2619,22 @@ sil [ossa] @test_partial_apply_4_loadable_stack : $() -> () { return %retval : $() } +// CHECK-LABEL: sil [ossa] @test_partial_apply_5_indexing : {{.*}} { +// CHECK: {{bb[0-9]+}}([[C:%[^,]+]] : +// CHECK: [[CALLEE:%[^,]+]] = function_ref @test_partial_apply_5_indexing_callee +// CHECK: [[CLOSURE:%[^,]+]] = partial_apply [callee_guaranteed] [[CALLEE]]([[C]]) +// CHECK: destroy_value [[CLOSURE]] +// CHECK-LABEL: } // end sil function 'test_partial_apply_5_indexing' +sil @test_partial_apply_5_indexing_callee : $@convention(thin) (@inout Int, @guaranteed Klass) -> (@out Int) +sil [ossa] @test_partial_apply_5_indexing : $@convention(thin) (@owned Klass) -> () { +bb0(%c : @owned $Klass): + %callee = function_ref @test_partial_apply_5_indexing_callee : $@convention(thin) (@inout Int, @guaranteed Klass) -> (@out Int) + %closure = partial_apply [callee_guaranteed] %callee(%c) : $@convention(thin) (@inout Int, @guaranteed Klass) -> (@out Int) + destroy_value %closure : $@callee_guaranteed (@inout Int) -> (@out Int) + %retval = tuple () + return %retval : $() +} + // CHECK-LABEL: sil hidden [ossa] @test_store_1 : {{.*}} { // CHECK: [[MAYBE_ADDR:%[^,]+]] = alloc_stack $Optional // CHECK: [[LOAD_ADDR:%[^,]+]] = alloc_stack $Self