Skip to content

Commit a133549

Browse files
committed
[SIL-opaque] Add @in_guaranteed function argument support.
Temporarily map storage to a fake load_borrow.
1 parent 4e3f0df commit a133549

File tree

2 files changed

+43
-16
lines changed

2 files changed

+43
-16
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,12 @@ struct AddressLoweringState {
425425

426426
AddressLoweringState(SILFunction *function, DominanceInfo *domInfo)
427427
: function(function), loweredFnConv(getLoweredFnConv(function)),
428-
domInfo(domInfo) {}
428+
domInfo(domInfo) {
429+
for (auto &block : *function) {
430+
if (block.getTerminator()->isFunctionExiting())
431+
exitingInsts.push_back(block.getTerminator());
432+
}
433+
}
429434

430435
SILModule *getModule() const { return &function->getModule(); }
431436

@@ -489,28 +494,39 @@ static void convertDirectToIndirectFunctionArgs(AddressLoweringState &pass) {
489494
if (param.isFormalIndirect() && !fnConv.isSILIndirect(param)) {
490495
SILArgument *arg = pass.function->getArgument(argIdx);
491496
SILType addrType = arg->getType().getAddressType();
492-
LoadInst *loadArg = argBuilder.createTrivialLoadOr(
493-
SILValue(arg).getLoc(), SILUndef::get(addrType, *pass.function),
494-
LoadOwnershipQualifier::Take);
495-
496-
arg->replaceAllUsesWith(loadArg);
497+
auto loc = SILValue(arg).getLoc();
498+
SILValue undefAddress = SILUndef::get(addrType, *pass.function);
499+
SingleValueInstruction *load;
500+
if (param.isConsumed()) {
501+
load = argBuilder.createTrivialLoadOr(loc, undefAddress,
502+
LoadOwnershipQualifier::Take);
503+
} else {
504+
load = cast<SingleValueInstruction>(
505+
argBuilder.emitLoadBorrowOperation(loc, undefAddress));
506+
for (SILInstruction *termInst : pass.exitingInsts) {
507+
pass.getBuilder(termInst->getIterator())
508+
.createEndBorrow(pass.genLoc(), load);
509+
}
510+
}
511+
arg->replaceAllUsesWith(load);
497512
assert(!pass.valueStorageMap.contains(arg));
498513

499514
arg = arg->getParent()->replaceFunctionArgument(
500515
arg->getIndex(), addrType, OwnershipKind::None, arg->getDecl());
501516

502-
loadArg->setOperand(arg);
517+
assert(isa<LoadInst>(load) || isa<LoadBorrowInst>(load));
518+
load->setOperand(0, arg);
503519

504520
// Indirect calling convention may be used for loadable types. In that
505521
// case, generating the argument loads is sufficient.
506522
if (addrType.isAddressOnly(*pass.function)) {
507-
pass.valueStorageMap.insertValue(loadArg, arg);
523+
pass.valueStorageMap.insertValue(load, arg);
508524
}
509525
}
510526
++argIdx;
511527
}
512-
assert(argIdx
513-
== fnConv.getSILArgIndexOfFirstParam() + fnConv.getNumSILArguments());
528+
assert(argIdx ==
529+
fnConv.getSILArgIndexOfFirstParam() + fnConv.getNumSILArguments());
514530
}
515531

516532
/// Before populating the ValueStorageMap, insert function arguments for any
@@ -575,9 +591,6 @@ class OpaqueValueVisitor {
575591
/// to valueStorageMap in RPO.
576592
void OpaqueValueVisitor::mapValueStorage() {
577593
for (auto *block : postorderInfo.getReversePostOrder()) {
578-
if (block->getTerminator()->isFunctionExiting())
579-
pass.exitingInsts.push_back(block->getTerminator());
580-
581594
// Opaque function arguments have already been replaced.
582595
if (block != pass.function->getEntryBlock()) {
583596
for (auto *arg : block->getArguments()) {

test/SILOptimizer/address_lowering.sil

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,12 @@ bb0(%0 : @owned $C):
272272

273273
sil [ossa] @f044_indirectGuaranteed : $@convention(thin) <T>(@in_guaranteed T) -> ()
274274

275-
// CHECK-LABEL: sil [ossa] @f045_indirectGuaranteedArg : $@convention(thin) <T> (@in T) -> () {
275+
// CHECK-LABEL: sil [ossa] @f045_indirectGuaranteedCallArg : $@convention(thin) <T> (@in T) -> () {
276276
// CHECK: bb0(%0 : $*T):
277277
// CHECK: apply %{{.*}}<T>(%0) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
278278
// CHECK: destroy_addr %0 : $*T
279-
// CHECK-LABEL: } // end sil function 'f045_indirectGuaranteedArg'
280-
sil [ossa] @f045_indirectGuaranteedArg : $@convention(thin) <T>(@in T) -> () {
279+
// CHECK-LABEL: } // end sil function 'f045_indirectGuaranteedCallArg'
280+
sil [ossa] @f045_indirectGuaranteedCallArg : $@convention(thin) <T>(@in T) -> () {
281281
bb0(%0 : @owned $T):
282282
%1 = function_ref @f044_indirectGuaranteed : $@convention(thin) <τ_0_0>(@in_guaranteed τ_0_0) -> ()
283283
%2 = apply %1<T>(%0) : $@convention(thin) <τ_0_0>(@in_guaranteed τ_0_0) -> ()
@@ -286,6 +286,20 @@ bb0(%0 : @owned $T):
286286
return %6 : $()
287287
}
288288

289+
// CHECK-LABEL: sil [ossa] @f046_indirectGuaranteedFunctionArg : $@convention(thin) <T> (@in_guaranteed T) -> () {
290+
// CHECK: bb0(%0 : $*T):
291+
// CHECK-NOT: load
292+
// CHECK: apply %{{.*}}<T>(%0) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
293+
// CHECK-NOT: end_borrow
294+
// CHECK-LABEL: } // end sil function 'f046_indirectGuaranteedFunctionArg'
295+
sil [ossa] @f046_indirectGuaranteedFunctionArg : $@convention(thin) <T>(@in_guaranteed T) -> () {
296+
bb0(%0 : @guaranteed $T):
297+
%1 = function_ref @f044_indirectGuaranteed : $@convention(thin) <τ_0_0>(@in_guaranteed τ_0_0) -> ()
298+
%2 = apply %1<T>(%0) : $@convention(thin) <τ_0_0>(@in_guaranteed τ_0_0) -> ()
299+
%6 = tuple ()
300+
return %6 : $()
301+
}
302+
289303
// CHECK-LABEL: sil [ossa] @f050_storeinout : $@convention(thin) <T> (@inout T, @inout T, @in T) -> () {
290304
// CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $*T):
291305
// CHECK: %[[PREV1:.*]] = alloc_stack $T

0 commit comments

Comments
 (0)