@@ -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.
576592void 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 ()) {
0 commit comments