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