@@ -102,16 +102,20 @@ class BeginApplySite {
102
102
return BeginApplySite (BeginApply, Loc, Builder);
103
103
}
104
104
105
- void preprocess (SILBasicBlock *returnToBB) {
105
+ void preprocess (SILBasicBlock *returnToBB,
106
+ SmallVectorImpl<SILInstruction *> &endBorrowInsertPts) {
106
107
SmallVector<EndApplyInst *, 1 > endApplyInsts;
107
108
SmallVector<AbortApplyInst *, 1 > abortApplyInsts;
108
109
BeginApply->getCoroutineEndPoints (endApplyInsts, abortApplyInsts);
109
110
while (!endApplyInsts.empty ()) {
110
111
auto *endApply = endApplyInsts.pop_back_val ();
111
112
collectEndApply (endApply);
113
+ endBorrowInsertPts.push_back (&*std::next (endApply->getIterator ()));
112
114
}
113
115
while (!abortApplyInsts.empty ()) {
114
- collectAbortApply (abortApplyInsts.pop_back_val ());
116
+ auto *abortApply = abortApplyInsts.pop_back_val ();
117
+ collectAbortApply (abortApply);
118
+ endBorrowInsertPts.push_back (&*std::next (abortApply->getIterator ()));
115
119
}
116
120
}
117
121
@@ -428,29 +432,38 @@ SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
428
432
429
433
SmallVector<SILValue, 4 > entryArgs;
430
434
entryArgs.reserve (AppliedArgs.size ());
435
+ SmallBitVector borrowedArgs (AppliedArgs.size ());
436
+
431
437
auto calleeConv = getCalleeFunction ()->getConventions ();
432
- for (unsigned argIdx = 0 , endIdx = AppliedArgs. size (); argIdx < endIdx;
433
- ++argIdx) {
434
- SILValue callArg = AppliedArgs[argIdx] ;
438
+ for (auto p : llvm::enumerate (AppliedArgs)) {
439
+ SILValue callArg = p. value ();
440
+ unsigned idx = p. index () ;
435
441
// Insert begin/end borrow for guaranteed arguments.
436
- if (argIdx >= calleeConv.getSILArgIndexOfFirstParam ()
437
- && calleeConv.getParamInfoForSILArg (argIdx).isGuaranteed ()) {
438
- callArg = borrowFunctionArgument (callArg, Apply);
442
+ if (idx >= calleeConv.getSILArgIndexOfFirstParam () &&
443
+ calleeConv.getParamInfoForSILArg (idx).isGuaranteed ()) {
444
+ if (SILValue newValue = borrowFunctionArgument (callArg, Apply)) {
445
+ callArg = newValue;
446
+ borrowedArgs[idx] = true ;
447
+ }
439
448
}
440
449
entryArgs.push_back (callArg);
441
450
}
442
451
443
452
// Create the return block and set ReturnToBB for use in visitTerminator
444
453
// callbacks.
445
- SILBasicBlock *callerBB = Apply.getParent ();
454
+ SILBasicBlock *callerBlock = Apply.getParent ();
455
+ SILBasicBlock *throwBlock = nullptr ;
456
+ SmallVector<SILInstruction *, 1 > endBorrowInsertPts;
457
+
446
458
switch (Apply.getKind ()) {
447
459
case FullApplySiteKind::ApplyInst: {
448
460
auto *AI = dyn_cast<ApplyInst>(Apply);
449
461
450
462
// Split the BB and do NOT create a branch between the old and new
451
463
// BBs; we will create the appropriate terminator manually later.
452
464
ReturnToBB =
453
- callerBB->split (std::next (Apply.getInstruction ()->getIterator ()));
465
+ callerBlock->split (std::next (Apply.getInstruction ()->getIterator ()));
466
+ endBorrowInsertPts.push_back (&*ReturnToBB->begin ());
454
467
455
468
// Create an argument on the return-to BB representing the returned value.
456
469
auto *retArg =
@@ -459,22 +472,49 @@ SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
459
472
AI->replaceAllUsesWith (retArg);
460
473
break ;
461
474
}
462
- case FullApplySiteKind::BeginApplyInst:
475
+ case FullApplySiteKind::BeginApplyInst: {
463
476
ReturnToBB =
464
- callerBB->split (std::next (Apply.getInstruction ()->getIterator ()));
465
- BeginApply->preprocess (ReturnToBB);
477
+ callerBlock->split (std::next (Apply.getInstruction ()->getIterator ()));
478
+ // For begin_apply, we insert the end_borrow in the end_apply, abort_apply
479
+ // blocks to ensure that our borrowed values live over both the body and
480
+ // resume block of our coroutine.
481
+ BeginApply->preprocess (ReturnToBB, endBorrowInsertPts);
466
482
break ;
467
-
468
- case FullApplySiteKind::TryApplyInst:
469
- ReturnToBB = cast<TryApplyInst>(Apply)->getNormalBB ();
483
+ }
484
+ case FullApplySiteKind::TryApplyInst: {
485
+ auto *tai = cast<TryApplyInst>(Apply);
486
+ ReturnToBB = tai->getNormalBB ();
487
+ endBorrowInsertPts.push_back (&*ReturnToBB->begin ());
488
+ throwBlock = tai->getErrorBB ();
470
489
break ;
471
490
}
491
+ }
492
+
493
+ // Then insert end_borrow in our end borrow block and in the throw
494
+ // block if we have one.
495
+ if (borrowedArgs.any ()) {
496
+ for (unsigned i : indices (AppliedArgs)) {
497
+ if (!borrowedArgs.test (i)) {
498
+ continue ;
499
+ }
500
+
501
+ for (auto *insertPt : endBorrowInsertPts) {
502
+ SILBuilderWithScope returnBuilder (insertPt, getBuilder ());
503
+ returnBuilder.createEndBorrow (Apply.getLoc (), entryArgs[i]);
504
+ }
505
+
506
+ if (throwBlock) {
507
+ SILBuilderWithScope throwBuilder (throwBlock->begin (), getBuilder ());
508
+ throwBuilder.createEndBorrow (Apply.getLoc (), entryArgs[i]);
509
+ }
510
+ }
511
+ }
472
512
473
513
// Visit original BBs in depth-first preorder, starting with the
474
514
// entry block, cloning all instructions and terminators.
475
515
//
476
516
// NextIter is initialized during `fixUp`.
477
- cloneFunctionBody (getCalleeFunction (), callerBB , entryArgs);
517
+ cloneFunctionBody (getCalleeFunction (), callerBlock , entryArgs);
478
518
479
519
// For non-throwing applies, the inlined body now unconditionally branches to
480
520
// the returned-to-code, which was previously part of the call site's basic
@@ -560,25 +600,11 @@ SILValue SILInlineCloner::borrowFunctionArgument(SILValue callArg,
560
600
FullApplySite AI) {
561
601
if (!AI.getFunction ()->hasOwnership ()
562
602
|| callArg.getOwnershipKind () != ValueOwnershipKind::Owned) {
563
- return callArg ;
603
+ return SILValue () ;
564
604
}
565
605
566
606
SILBuilderWithScope beginBuilder (AI.getInstruction (), getBuilder ());
567
- auto *borrow = beginBuilder.createBeginBorrow (AI.getLoc (), callArg);
568
- if (auto *tryAI = dyn_cast<TryApplyInst>(AI)) {
569
- SILBuilderWithScope returnBuilder (tryAI->getNormalBB ()->begin (),
570
- getBuilder ());
571
- returnBuilder.createEndBorrow (AI.getLoc (), borrow, callArg);
572
-
573
- SILBuilderWithScope throwBuilder (tryAI->getErrorBB ()->begin (),
574
- getBuilder ());
575
- throwBuilder.createEndBorrow (AI.getLoc (), borrow, callArg);
576
- } else {
577
- SILBuilderWithScope returnBuilder (
578
- std::next (AI.getInstruction ()->getIterator ()), getBuilder ());
579
- returnBuilder.createEndBorrow (AI.getLoc (), borrow, callArg);
580
- }
581
- return borrow;
607
+ return beginBuilder.createBeginBorrow (AI.getLoc (), callArg);
582
608
}
583
609
584
610
void SILInlineCloner::visitDebugValueInst (DebugValueInst *Inst) {
0 commit comments