@@ -311,6 +311,28 @@ getCalleeFunction(FullApplySite AI, bool &IsThick,
311311 return CalleeFunction;
312312}
313313
314+ static std::tuple<FullApplySite, SILBasicBlock::iterator>
315+ tryDevirtualizeApplyHelper (FullApplySite InnerAI, SILBasicBlock::iterator I,
316+ ClassHierarchyAnalysis *CHA) {
317+ auto NewInstPair = tryDevirtualizeApply (InnerAI, CHA);
318+ auto *NewInst = NewInstPair.first ;
319+ if (!NewInst)
320+ return std::make_tuple (InnerAI, I);
321+
322+ replaceDeadApply (InnerAI, NewInst);
323+ if (auto *II = dyn_cast<SILInstruction>(NewInst))
324+ I = II->getIterator ();
325+ else
326+ I = NewInst->getParentBlock ()->begin ();
327+ auto NewAI = FullApplySite::isa (NewInstPair.second .getInstruction ());
328+ // *NOTE*, it is important that we return I here since we may have
329+ // devirtualized but not have a full apply site anymore.
330+ if (!NewAI)
331+ return std::make_tuple (FullApplySite (), I);
332+
333+ return std::make_tuple (NewAI, I);
334+ }
335+
314336// / \brief Inlines all mandatory inlined functions into the body of a function,
315337// / first recursively inlining all mandatory apply instructions in those
316338// / functions into their bodies if necessary.
@@ -363,19 +385,9 @@ runOnFunctionRecursively(SILFunction *F, FullApplySite AI,
363385
364386 auto *ApplyBlock = InnerAI.getParent ();
365387
366- auto NewInstPair = tryDevirtualizeApply (InnerAI, CHA);
367- if (auto *NewInst = NewInstPair.first ) {
368- replaceDeadApply (InnerAI, NewInst);
369- if (auto *II = dyn_cast<SILInstruction>(NewInst))
370- I = II->getIterator ();
371- else
372- I = NewInst->getParentBlock ()->begin ();
373- auto NewAI = FullApplySite::isa (NewInstPair.second .getInstruction ());
374- if (!NewAI)
375- continue ;
376-
377- InnerAI = NewAI;
378- }
388+ std::tie (InnerAI, I) = tryDevirtualizeApplyHelper (InnerAI, I, CHA);
389+ if (!InnerAI)
390+ continue ;
379391
380392 SILLocation Loc = InnerAI.getLoc ();
381393 SILValue CalleeValue = InnerAI.getCallee ();
0 commit comments