// Clone a chain of ConvertFunctionInsts. SILValue ClosureSpecCloner::cloneCalleeConversion(SILValue calleeValue, SILValue NewClosure, SILBuilder &Builder) { if (calleeValue == CallSiteDesc.getClosure()) return NewClosure; if (auto *CFI = dyn_cast<ConvertFunctionInst>(calleeValue)) { calleeValue = cloneCalleeConversion(CFI->getOperand(), NewClosure, Builder); return Builder.createConvertFunction(CallSiteDesc.getLoc(), calleeValue, CFI->getType()); } auto *Cvt = cast<ConvertEscapeToNoEscapeInst>(calleeValue); calleeValue = cloneCalleeConversion(Cvt->getOperand(), NewClosure, Builder); return Builder.createConvertEscapeToNoEscape( CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), false, true); }
// Clone a chain of ConvertFunctionInsts. SILValue ClosureSpecCloner::cloneCalleeConversion( SILValue calleeValue, SILValue NewClosure, SILBuilder &Builder, SmallVectorImpl<PartialApplyInst *> &NeedsRelease) { if (calleeValue == CallSiteDesc.getClosure()) return NewClosure; if (auto *CFI = dyn_cast<ConvertFunctionInst>(calleeValue)) { calleeValue = cloneCalleeConversion(CFI->getOperand(), NewClosure, Builder, NeedsRelease); return Builder.createConvertFunction(CallSiteDesc.getLoc(), calleeValue, CFI->getType(), CFI->withoutActuallyEscaping()); } if (auto *PAI = dyn_cast<PartialApplyInst>(calleeValue)) { assert(isPartialApplyOfReabstractionThunk(PAI) && isSupportedClosure(PAI) && PAI->getArgument(0) ->getType() .getAs<SILFunctionType>() ->isTrivialNoEscape()); calleeValue = cloneCalleeConversion(PAI->getArgument(0), NewClosure, Builder, NeedsRelease); auto FunRef = Builder.createFunctionRef(CallSiteDesc.getLoc(), PAI->getReferencedFunction()); auto NewPA = Builder.createPartialApply( CallSiteDesc.getLoc(), FunRef, {}, {calleeValue}, PAI->getType().getAs<SILFunctionType>()->getCalleeConvention()); NeedsRelease.push_back(NewPA); return NewPA; } auto *Cvt = cast<ConvertEscapeToNoEscapeInst>(calleeValue); calleeValue = cloneCalleeConversion(Cvt->getOperand(), NewClosure, Builder, NeedsRelease); return Builder.createConvertEscapeToNoEscape( CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), false, true); }