@@ -326,6 +326,20 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
326
326
// with the CB BB ('Entry') between which the inlined callee will be pasted.
327
327
Successors.insert (succ_begin (&CallSiteBB), succ_end (&CallSiteBB));
328
328
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 ();
329
343
// Inlining only handles invoke and calls. If this is an invoke, and inlining
330
344
// it pulls another invoke, the original landing pad may get split, so as to
331
345
// share its content with other potential users. So the edge up to which we
@@ -336,6 +350,12 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
336
350
if (const auto *II = dyn_cast<InvokeInst>(&CB)) {
337
351
const auto *UnwindDest = II->getUnwindDest ();
338
352
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));
339
359
}
340
360
341
361
// Exclude the CallSiteBB, if it happens to be its own successor (1-BB loop).
@@ -356,6 +376,30 @@ FunctionPropertiesUpdater::FunctionPropertiesUpdater(
356
376
FPI.updateForBB (*BB, -1 );
357
377
}
358
378
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
+ for (auto &Upd : DomTreeUpdates)
387
+ FinalDomTreeUpdates.push_back (Upd);
388
+
389
+ DenseSet<const BasicBlock *> Inserted;
390
+ for (auto *Succ : successors (&CallSiteBB))
391
+ if (Inserted.insert (Succ).second )
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
+
359
403
void FunctionPropertiesUpdater::finish (FunctionAnalysisManager &FAM) const {
360
404
// Update feature values from the BBs that were copied from the callee, or
361
405
// might have been modified because of inlining. The latter have been
@@ -383,8 +427,7 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
383
427
// remove E.
384
428
SetVector<const BasicBlock *> Reinclude;
385
429
SetVector<const BasicBlock *> Unreachable;
386
- const auto &DT =
387
- FAM.getResult <DominatorTreeAnalysis>(const_cast <Function &>(Caller));
430
+ auto &DT = getUpdatedDominatorTree (FAM);
388
431
389
432
if (&CallSiteBB != &*Caller.begin ())
390
433
Reinclude.insert (&*Caller.begin ());
@@ -427,6 +470,9 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
427
470
428
471
const auto &LI = FAM.getResult <LoopAnalysis>(const_cast <Function &>(Caller));
429
472
FPI.updateAggregateStats (Caller, LI);
473
+ #ifdef EXPENSIVE_CHECKS
474
+ assert (isUpdateValid (Caller, FPI, FAM));
475
+ #endif
430
476
}
431
477
432
478
bool FunctionPropertiesUpdater::isUpdateValid (Function &F,
0 commit comments