@@ -485,19 +485,11 @@ bool OwnershipModelEliminatorVisitor::visitDestroyValueInst(
485485 DestroyValueInst *dvi) {
486486 // Nonescaping closures are represented ultimately as trivial pointers to
487487 // 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.
491489 auto operand = dvi->getOperand ();
492490 auto operandTy = operand->getType ();
493491 if (auto operandFnTy = operandTy.getAs <SILFunctionType>()){
494492 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-
501493 eraseInstruction (dvi);
502494 return true ;
503495 }
@@ -627,9 +619,41 @@ static bool stripOwnership(SILFunction &func) {
627619 if (func.isExternalDeclaration ())
628620 return false ;
629621
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+
630644 // Set F to have unqualified ownership.
631645 func.setOwnershipEliminated ();
632646
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+
633657 bool madeChange = false ;
634658 SmallVector<SILInstruction *, 32 > createdInsts;
635659 OwnershipModelEliminatorVisitor visitor (func);
0 commit comments