@@ -539,19 +539,11 @@ bool OwnershipModelEliminatorVisitor::visitDestroyValueInst(
539539 DestroyValueInst *dvi) {
540540 // Nonescaping closures are represented ultimately as trivial pointers to
541541 // their context, but we use ownership to do borrow checking of their captures
542- // in OSSA. Now that we're eliminating ownership, fold away destroys, unless
543- // we're destroying the original partial_apply, in which case this is where
544- // we dealloc_stack the context.
542+ // in OSSA. Now that we're eliminating ownership, fold away destroys.
545543 auto operand = dvi->getOperand ();
546544 auto operandTy = operand->getType ();
547545 if (auto operandFnTy = operandTy.getAs <SILFunctionType>()){
548546 if (operandFnTy->isTrivialNoEscape ()) {
549- if (auto origPA = dvi->getNonescapingClosureAllocation ()) {
550- withBuilder<void >(dvi, [&](SILBuilder &b, SILLocation loc) {
551- b.createDeallocStack (loc, origPA);
552- });
553- }
554-
555547 eraseInstruction (dvi);
556548 return true ;
557549 }
@@ -685,9 +677,41 @@ static bool stripOwnership(SILFunction &func) {
685677 if (func.isExternalDeclaration ())
686678 return false ;
687679
680+ llvm::DenseMap<PartialApplyInst *, SmallVector<SILInstruction *>>
681+ lifetimeEnds;
682+
683+ // Nonescaping closures are represented ultimately as trivial pointers to
684+ // their context, but we use ownership to do borrow checking of their captures
685+ // in OSSA. Now that we're eliminating ownership, we need to dealloc_stack the
686+ // context at its lifetime ends.
687+ // partial_apply's lifetime ends has to be gathered before we begin to leave
688+ // OSSA, but no dealloc_stack can be emitted until after we leave OSSA.
689+ for (auto &block : func) {
690+ for (auto &ii : block) {
691+ auto *pai = dyn_cast<PartialApplyInst>(&ii);
692+ if (!pai || !pai->isOnStack ()) {
693+ continue ;
694+ }
695+ pai->visitOnStackLifetimeEnds ([&](Operand *op) {
696+ lifetimeEnds[pai].push_back (op->getUser ());
697+ return true ;
698+ });
699+ }
700+ }
701+
688702 // Set F to have unqualified ownership.
689703 func.setOwnershipEliminated ();
690704
705+ // Now that we are in non-ossa, create dealloc_stack at partial_apply's
706+ // lifetime ends
707+ for (auto &it : lifetimeEnds) {
708+ auto *pai = it.first ;
709+ for (auto *lifetimeEnd : it.second ) {
710+ SILBuilderWithScope (lifetimeEnd->getNextInstruction ())
711+ .createDeallocStack (lifetimeEnd->getLoc (), pai);
712+ }
713+ }
714+
691715 bool madeChange = false ;
692716 SmallVector<SILInstruction *, 32 > createdInsts;
693717 OwnershipModelEliminatorVisitor visitor (func);
0 commit comments