Skip to content

Commit 584cfcc

Browse files
committed
[nfc] Incrementally update DominatorTreeAnalysis in FunctionPropertiesAnalysis
1 parent a6bae5c commit 584cfcc

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H
1616

1717
#include "llvm/ADT/DenseSet.h"
18+
#include "llvm/IR/Dominators.h"
1819
#include "llvm/IR/PassManager.h"
1920

2021
namespace llvm {
@@ -186,7 +187,12 @@ class FunctionPropertiesUpdater {
186187
static bool isUpdateValid(Function &F, const FunctionPropertiesInfo &FPI,
187188
FunctionAnalysisManager &FAM);
188189

190+
DominatorTree &getUpdatedDominatorTree(FunctionAnalysisManager &FAM) const;
191+
189192
DenseSet<const BasicBlock *> Successors;
193+
194+
// Edges we might potentially need to remove from the dominator tree.
195+
SmallVector<DominatorTree::UpdateType, 2> DomTreeUpdates;
190196
};
191197
} // namespace llvm
192198
#endif // LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H

llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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,45 @@ 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+
SetVector<const BasicBlock *> NewSucc;
378+
NewSucc.insert(succ_begin(&CallSiteBB), succ_end(&CallSiteBB));
379+
380+
// tell the DomTree about the new edges
381+
std::deque<const BasicBlock *> Worklist;
382+
Worklist.push_back(&CallSiteBB);
383+
384+
// Build the list of edges to actually remove. Those are those edges in the
385+
// DomTreeUpdates that cannot be found in the CFG anymore.
386+
SmallVector<DominatorTree::UpdateType, 2> FinalDomTreeUpdates;
387+
while (!Worklist.empty()) {
388+
auto *BB = Worklist.front();
389+
Worklist.pop_front();
390+
assert(DT.getNode(BB));
391+
392+
for (auto *Succ : NewSucc) {
393+
if (!DT.getNode(Succ))
394+
Worklist.push_back(Succ);
395+
FinalDomTreeUpdates.push_back({DominatorTree::UpdateKind::Insert,
396+
const_cast<BasicBlock *>(BB),
397+
const_cast<BasicBlock *>(Succ)});
398+
}
399+
}
400+
for (auto &Upd : DomTreeUpdates)
401+
if (!llvm::is_contained(successors(Upd.getFrom()), Upd.getTo()))
402+
FinalDomTreeUpdates.push_back(Upd);
403+
404+
DT.applyUpdates(FinalDomTreeUpdates);
405+
#ifdef EXPENSIVE_CHECKS
406+
assert(DT.verify(DominatorTree::VerificationLevel::Full));
407+
#endif
408+
return DT;
409+
}
410+
359411
void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
360412
// Update feature values from the BBs that were copied from the callee, or
361413
// might have been modified because of inlining. The latter have been
@@ -383,8 +435,7 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
383435
// remove E.
384436
SetVector<const BasicBlock *> Reinclude;
385437
SetVector<const BasicBlock *> Unreachable;
386-
const auto &DT =
387-
FAM.getResult<DominatorTreeAnalysis>(const_cast<Function &>(Caller));
438+
auto &DT = getUpdatedDominatorTree(FAM);
388439

389440
if (&CallSiteBB != &*Caller.begin())
390441
Reinclude.insert(&*Caller.begin());
@@ -427,6 +478,9 @@ void FunctionPropertiesUpdater::finish(FunctionAnalysisManager &FAM) const {
427478

428479
const auto &LI = FAM.getResult<LoopAnalysis>(const_cast<Function &>(Caller));
429480
FPI.updateAggregateStats(Caller, LI);
481+
#ifdef EXPENSIVE_CHECKS
482+
assert(isUpdateValid(Caller, FPI, FAM));
483+
#endif
430484
}
431485

432486
bool FunctionPropertiesUpdater::isUpdateValid(Function &F,

llvm/lib/Analysis/MLInlineAdvisor.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ void MLInlineAdvisor::onSuccessfulInlining(const MLInlineAdvice &Advice,
288288
{
289289
PreservedAnalyses PA = PreservedAnalyses::all();
290290
PA.abandon<FunctionPropertiesAnalysis>();
291-
PA.abandon<DominatorTreeAnalysis>();
292291
PA.abandon<LoopAnalysis>();
293292
FAM.invalidate(*Caller, PA);
294293
}

test-cfg-only.dot

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
digraph "CFG for 'f' function" {
2+
label="CFG for 'f' function";
3+
4+
Node0x5640f3daad80 [shape=record,label="{bb0|{<s0>T|<s1>F}}"];
5+
Node0x5640f3daad80:s0 -> Node0x5640f3d8f320;
6+
Node0x5640f3daad80:s1 -> Node0x5640f3d9eb90;
7+
Node0x5640f3d8f320 [shape=record,label="{bb1}"];
8+
Node0x5640f3d8f320 -> Node0x5640f3da2ea0;
9+
Node0x5640f3d9eb90 [shape=record,label="{bb2}"];
10+
Node0x5640f3d9eb90 -> Node0x5640f3da2ea0;
11+
Node0x5640f3da2ea0 [shape=record,label="{bb3}"];
12+
}

test-full.dot

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
digraph "CFG for 'f' function" {
2+
label="CFG for 'f' function";
3+
4+
Node0x5640f3daad80 [shape=record,label="{bb0:\l| %y1 = icmp eq i32 %x, 0\l br i1 %y1, label %bb1, label %bb2\l|{<s0>T|<s1>F}}"];
5+
Node0x5640f3daad80:s0 -> Node0x5640f3d8f320;
6+
Node0x5640f3daad80:s1 -> Node0x5640f3d9eb90;
7+
Node0x5640f3d8f320 [shape=record,label="{bb1:\l| br label %bb3\l}"];
8+
Node0x5640f3d8f320 -> Node0x5640f3da2ea0;
9+
Node0x5640f3d9eb90 [shape=record,label="{bb2:\l| br label %bb3\l}"];
10+
Node0x5640f3d9eb90 -> Node0x5640f3da2ea0;
11+
Node0x5640f3da2ea0 [shape=record,label="{bb3:\l| %y2 = phi i32 [ 0, %bb1 ], [ 1, %bb2 ]\l ret i32 %y2\l}"];
12+
}

0 commit comments

Comments
 (0)