@@ -485,19 +485,11 @@ bool OwnershipModelEliminatorVisitor::visitDestroyValueInst(
485
485
DestroyValueInst *dvi) {
486
486
// Nonescaping closures are represented ultimately as trivial pointers to
487
487
// their context, but we use ownership to do borrow checking of their captures
488
- // in OSSA. Now that we're eliminating ownership, fold away destroys, unless
489
- // we're destroying the original partial_apply, in which case this is where
490
- // we dealloc_stack the context.
488
+ // in OSSA. Now that we're eliminating ownership, fold away destroys.
491
489
auto operand = dvi->getOperand ();
492
490
auto operandTy = operand->getType ();
493
491
if (auto operandFnTy = operandTy.getAs <SILFunctionType>()){
494
492
if (operandFnTy->isTrivialNoEscape ()) {
495
- if (auto origPA = dvi->getNonescapingClosureAllocation ()) {
496
- withBuilder<void >(dvi, [&](SILBuilder &b, SILLocation loc) {
497
- b.createDeallocStack (loc, origPA);
498
- });
499
- }
500
-
501
493
eraseInstruction (dvi);
502
494
return true ;
503
495
}
@@ -627,9 +619,41 @@ static bool stripOwnership(SILFunction &func) {
627
619
if (func.isExternalDeclaration ())
628
620
return false ;
629
621
622
+ llvm::DenseMap<PartialApplyInst *, SmallVector<SILInstruction *>>
623
+ lifetimeEnds;
624
+
625
+ // Nonescaping closures are represented ultimately as trivial pointers to
626
+ // their context, but we use ownership to do borrow checking of their captures
627
+ // in OSSA. Now that we're eliminating ownership, we need to dealloc_stack the
628
+ // context at its lifetime ends.
629
+ // partial_apply's lifetime ends has to be gathered before we begin to leave
630
+ // OSSA, but no dealloc_stack can be emitted until after we leave OSSA.
631
+ for (auto &block : func) {
632
+ for (auto &ii : block) {
633
+ auto *pai = dyn_cast<PartialApplyInst>(&ii);
634
+ if (!pai || !pai->isOnStack ()) {
635
+ continue ;
636
+ }
637
+ pai->visitOnStackLifetimeEnds ([&](Operand *op) {
638
+ lifetimeEnds[pai].push_back (op->getUser ());
639
+ return true ;
640
+ });
641
+ }
642
+ }
643
+
630
644
// Set F to have unqualified ownership.
631
645
func.setOwnershipEliminated ();
632
646
647
+ // Now that we are in non-ossa, create dealloc_stack at partial_apply's
648
+ // lifetime ends
649
+ for (auto &it : lifetimeEnds) {
650
+ auto *pai = it.first ;
651
+ for (auto *lifetimeEnd : it.second ) {
652
+ SILBuilderWithScope (lifetimeEnd->getNextInstruction ())
653
+ .createDeallocStack (lifetimeEnd->getLoc (), pai);
654
+ }
655
+ }
656
+
633
657
bool madeChange = false ;
634
658
SmallVector<SILInstruction *, 32 > createdInsts;
635
659
OwnershipModelEliminatorVisitor visitor (func);
0 commit comments