@@ -295,27 +295,38 @@ bool MandatoryGenericSpecializer::
295295optimizeInst (SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
296296 InstructionDeleter &deleter, ClassHierarchyAnalysis *cha) {
297297 if (auto as = ApplySite::isa (inst)) {
298+
299+ bool changed = false ;
300+
298301 // Specialization opens opportunities to devirtualize method calls.
299- ApplySite newAS = tryDevirtualizeApply (as, cha).first ;
300- if (!newAS)
301- return false ;
302- deleter.forceDelete (as.getInstruction ());
303- auto newFAS = FullApplySite::isa (newAS.getInstruction ());
304- if (!newFAS)
305- return true ;
302+ if (ApplySite newAS = tryDevirtualizeApply (as, cha).first ) {
303+ deleter.forceDelete (as.getInstruction ());
304+ changed = true ;
305+ as = newAS;
306+ }
307+
308+ auto fas = FullApplySite::isa (as.getInstruction ());
309+ if (!fas)
310+ return changed;
311+
312+ SILFunction *callee = fas.getReferencedFunctionOrNull ();
313+ if (!callee)
314+ return changed;
306315
307- SILFunction *callee = newFAS.getReferencedFunctionOrNull ();
308- if (!callee || callee->isTransparent () == IsNotTransparent)
309- return true ;
316+ if (callee->isTransparent () == IsNotTransparent &&
317+ // Force inlining of co-routines, because co-routines may allocate
318+ // memory.
319+ !isa<BeginApplyInst>(fas.getInstruction ()))
320+ return changed;
310321
311322 if (callee->isExternalDeclaration ())
312323 getModule ()->loadFunction (callee, SILModule::LinkingMode::LinkAll);
313324
314325 if (callee->isExternalDeclaration ())
315- return true ;
326+ return changed ;
316327
317328 // If the de-virtualized callee is a transparent function, inline it.
318- SILInliner::inlineFullApply (newFAS , SILInliner::InlineKind::MandatoryInline,
329+ SILInliner::inlineFullApply (fas , SILInliner::InlineKind::MandatoryInline,
319330 funcBuilder, deleter);
320331 return true ;
321332 }
0 commit comments