@@ -326,6 +326,20 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
326326  //  with the CB BB ('Entry') between which the inlined callee will be pasted.
327327  Successors.insert (succ_begin (&CallSiteBB), succ_end (&CallSiteBB));
328328
329+   //  the outcome of the inlining may be that some edges get lost (DCEd BBs
330+   //  because inlining brought some constant, for example). We don't know which
331+   //  edges will be removed, so we list all of them as potentially removable.
332+   //  Some BBs have (at this point) duplicate edges. Remove duplicates, otherwise
333+   //  the DT updater will not apply changes correctly.
334+   DenseSet<const  BasicBlock *> Inserted;
335+   for  (auto  *Succ : successors (&CallSiteBB))
336+     if  (Inserted.insert (Succ).second )
337+       DomTreeUpdates.emplace_back (DominatorTree::UpdateKind::Delete,
338+                                   const_cast <BasicBlock *>(&CallSiteBB),
339+                                   const_cast <BasicBlock *>(Succ));
340+   //  Reuse Inserted (which has some allocated capacity at this point) below, if
341+   //  we have an invoke.
342+   Inserted.clear ();
329343  //  Inlining only handles invoke and calls. If this is an invoke, and inlining
330344  //  it pulls another invoke, the original landing pad may get split, so as to
331345  //  share its content with other potential users. So the edge up to which we
@@ -336,6 +350,12 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
336350  if  (const  auto  *II = dyn_cast<InvokeInst>(&CB)) {
337351    const  auto  *UnwindDest = II->getUnwindDest ();
338352    Successors.insert (succ_begin (UnwindDest), succ_end (UnwindDest));
353+     //  Same idea as above, we pretend we lose all these edges.
354+     for  (auto  *Succ : successors (UnwindDest))
355+       if  (Inserted.insert (Succ).second )
356+         DomTreeUpdates.emplace_back (DominatorTree::UpdateKind::Delete,
357+                                     const_cast <BasicBlock *>(UnwindDest),
358+                                     const_cast <BasicBlock *>(Succ));
339359  }
340360
341361  //  Exclude the CallSiteBB, if it happens to be its own successor (1-BB loop).
@@ -356,6 +376,33 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
356376    FPI.updateForBB (*BB, -1 );
357377}
358378
379+ DominatorTree &FunctionPropertiesUpdater::getUpdatedDominatorTree (
380+     FunctionAnalysisManager &FAM) const  {
381+   auto  &DT =
382+       FAM.getResult <DominatorTreeAnalysis>(const_cast <Function &>(Caller));
383+ 
384+   SmallVector<DominatorTree::UpdateType, 2 > FinalDomTreeUpdates;
385+ 
386+   DenseSet<const  BasicBlock *> Inserted;
387+   for  (auto  *Succ : successors (&CallSiteBB))
388+     if  (Inserted.insert (Succ).second )
389+       FinalDomTreeUpdates.push_back ({DominatorTree::UpdateKind::Insert,
390+                                      const_cast <BasicBlock *>(&CallSiteBB),
391+                                      const_cast <BasicBlock *>(Succ)});
392+ 
393+   //  Perform the deletes last, so that any new nodes connected to nodes
394+   //  participating in the edge deletion are known to the DT.
395+   for  (auto  &Upd : DomTreeUpdates)
396+     if  (!llvm::is_contained (successors (Upd.getFrom ()), Upd.getTo ()))
397+       FinalDomTreeUpdates.push_back (Upd);
398+ 
399+   DT.applyUpdates (FinalDomTreeUpdates);
400+ #ifdef  EXPENSIVE_CHECKS
401+   assert (DT.verify (DominatorTree::VerificationLevel::Full));
402+ #endif 
403+   return  DT;
404+ }
405+ 
359406void  FunctionPropertiesUpdater::finish (FunctionAnalysisManager &FAM) const  {
360407  //  Update feature values from the BBs that were copied from the callee, or
361408  //  might have been modified because of inlining. The latter have been
@@ -383,8 +430,7 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
383430  //  remove E.
384431  SetVector<const  BasicBlock *> Reinclude;
385432  SetVector<const  BasicBlock *> Unreachable;
386-   const  auto  &DT =
387-       FAM.getResult <DominatorTreeAnalysis>(const_cast <Function &>(Caller));
433+   auto  &DT = getUpdatedDominatorTree (FAM);
388434
389435  if  (&CallSiteBB != &*Caller.begin ())
390436    Reinclude.insert (&*Caller.begin ());
@@ -427,11 +473,17 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
427473
428474  const  auto  &LI = FAM.getResult <LoopAnalysis>(const_cast <Function &>(Caller));
429475  FPI.updateAggregateStats (Caller, LI);
476+ #ifdef  EXPENSIVE_CHECKS
477+   assert (isUpdateValid (Caller, FPI, FAM));
478+ #endif 
430479}
431480
432481bool  FunctionPropertiesUpdater::isUpdateValid (Function &F,
433482                                              const  FunctionPropertiesInfo &FPI,
434483                                              FunctionAnalysisManager &FAM) {
484+   if  (!FAM.getResult <DominatorTreeAnalysis>(F).verify (
485+           DominatorTree::VerificationLevel::Full))
486+     return  false ;
435487  DominatorTree DT (F);
436488  LoopInfo LI (DT);
437489  auto  Fresh = FunctionPropertiesInfo::getFunctionPropertiesInfo (F, DT, LI);
0 commit comments