@@ -425,7 +425,12 @@ struct AddressLoweringState {
425
425
426
426
AddressLoweringState (SILFunction *function, DominanceInfo *domInfo)
427
427
: 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
+ }
429
434
430
435
SILModule *getModule () const { return &function->getModule (); }
431
436
@@ -489,28 +494,39 @@ static void convertDirectToIndirectFunctionArgs(AddressLoweringState &pass) {
489
494
if (param.isFormalIndirect () && !fnConv.isSILIndirect (param)) {
490
495
SILArgument *arg = pass.function ->getArgument (argIdx);
491
496
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);
497
512
assert (!pass.valueStorageMap .contains (arg));
498
513
499
514
arg = arg->getParent ()->replaceFunctionArgument (
500
515
arg->getIndex (), addrType, OwnershipKind::None, arg->getDecl ());
501
516
502
- loadArg->setOperand (arg);
517
+ assert (isa<LoadInst>(load) || isa<LoadBorrowInst>(load));
518
+ load->setOperand (0 , arg);
503
519
504
520
// Indirect calling convention may be used for loadable types. In that
505
521
// case, generating the argument loads is sufficient.
506
522
if (addrType.isAddressOnly (*pass.function )) {
507
- pass.valueStorageMap .insertValue (loadArg , arg);
523
+ pass.valueStorageMap .insertValue (load , arg);
508
524
}
509
525
}
510
526
++argIdx;
511
527
}
512
- assert (argIdx
513
- == fnConv.getSILArgIndexOfFirstParam () + fnConv.getNumSILArguments ());
528
+ assert (argIdx ==
529
+ fnConv.getSILArgIndexOfFirstParam () + fnConv.getNumSILArguments ());
514
530
}
515
531
516
532
// / Before populating the ValueStorageMap, insert function arguments for any
@@ -575,9 +591,6 @@ class OpaqueValueVisitor {
575
591
// / to valueStorageMap in RPO.
576
592
void OpaqueValueVisitor::mapValueStorage () {
577
593
for (auto *block : postorderInfo.getReversePostOrder ()) {
578
- if (block->getTerminator ()->isFunctionExiting ())
579
- pass.exitingInsts .push_back (block->getTerminator ());
580
-
581
594
// Opaque function arguments have already been replaced.
582
595
if (block != pass.function ->getEntryBlock ()) {
583
596
for (auto *arg : block->getArguments ()) {
0 commit comments