@@ -326,6 +326,14 @@ 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+ for (auto *Succ : successors (&CallSiteBB))
333+ DomTreeUpdates.emplace_back (DominatorTree::UpdateKind::Delete,
334+ const_cast <BasicBlock *>(&CallSiteBB),
335+ const_cast <BasicBlock *>(Succ));
336+
329337 // Inlining only handles invoke and calls. If this is an invoke, and inlining
330338 // it pulls another invoke, the original landing pad may get split, so as to
331339 // share its content with other potential users. So the edge up to which we
@@ -336,6 +344,11 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
336344 if (const auto *II = dyn_cast<InvokeInst>(&CB)) {
337345 const auto *UnwindDest = II->getUnwindDest ();
338346 Successors.insert (succ_begin (UnwindDest), succ_end (UnwindDest));
347+ // Same idea as above, we pretend we lose all these edges.
348+ for (auto *Succ : successors (UnwindDest))
349+ DomTreeUpdates.emplace_back (DominatorTree::UpdateKind::Delete,
350+ const_cast <BasicBlock *>(UnwindDest),
351+ const_cast <BasicBlock *>(Succ));
339352 }
340353
341354 // Exclude the CallSiteBB, if it happens to be its own successor (1-BB loop).
@@ -356,6 +369,37 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
356369 FPI.updateForBB (*BB, -1 );
357370}
358371
372+ DominatorTree &FunctionPropertiesUpdater::getUpdatedDominatorTree (
373+ FunctionAnalysisManager &FAM) const {
374+ auto &DT =
375+ FAM.getResult <DominatorTreeAnalysis>(const_cast <Function &>(Caller));
376+
377+ SmallVector<DominatorTree::UpdateType, 2 > FinalDomTreeUpdates;
378+
379+ // When constructing the updater, we pesimistically went through all the
380+ // successors of the callsite BB and prepared them for removal, but not all
381+ // may actually end up being removed. Check which actually survived.
382+ // Conversely, we won't re-add them if they weren't removed.
383+ DenseSet<const BasicBlock *> NewSuccessors;
384+ NewSuccessors.insert (succ_begin (&CallSiteBB), succ_end (&CallSiteBB));
385+ for (auto &Upd : DomTreeUpdates)
386+ if (Upd.getFrom () != &CallSiteBB || !NewSuccessors.contains (Upd.getTo ()))
387+ FinalDomTreeUpdates.push_back (Upd);
388+
389+ DenseSet<const BasicBlock *> Inserted;
390+ for (auto *Succ : successors (&CallSiteBB))
391+ if (Inserted.insert (Succ).second && !NewSuccessors.contains (Succ))
392+ FinalDomTreeUpdates.push_back ({DominatorTree::UpdateKind::Insert,
393+ const_cast <BasicBlock *>(&CallSiteBB),
394+ const_cast <BasicBlock *>(Succ)});
395+
396+ DT.applyUpdates (FinalDomTreeUpdates);
397+ #ifdef EXPENSIVE_CHECKS
398+ assert (DT.verify (DominatorTree::VerificationLevel::Full));
399+ #endif
400+ return DT;
401+ }
402+
359403void FunctionPropertiesUpdater::finish (FunctionAnalysisManager &FAM) const {
360404 // Update feature values from the BBs that were copied from the callee, or
361405 // might have been modified because of inlining. The latter have been
@@ -383,8 +427,7 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
383427 // remove E.
384428 SetVector<const BasicBlock *> Reinclude;
385429 SetVector<const BasicBlock *> Unreachable;
386- const auto &DT =
387- FAM.getResult <DominatorTreeAnalysis>(const_cast <Function &>(Caller));
430+ auto &DT = getUpdatedDominatorTree (FAM);
388431
389432 if (&CallSiteBB != &*Caller.begin ())
390433 Reinclude.insert (&*Caller.begin ());
@@ -427,6 +470,9 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
427470
428471 const auto &LI = FAM.getResult <LoopAnalysis>(const_cast <Function &>(Caller));
429472 FPI.updateAggregateStats (Caller, LI);
473+ #ifdef EXPENSIVE_CHECKS
474+ assert (isUpdateValid (Caller, FPI, FAM));
475+ #endif
430476}
431477
432478bool FunctionPropertiesUpdater::isUpdateValid (Function &F,
0 commit comments