Skip to content

Commit 7c35de1

Browse files
committed
[Dominators] Remove verifyDomTree and add some verifying for Post Dom Trees
Removes verifyDomTree, using assert(verify()) everywhere instead, and changes verify a little to always run IsSameAsFreshTree first in order to print good output when we find errors. Also adds verifyAnalysis for PostDomTrees, which will allow checking of PostDomTrees it the same way we check DomTrees and MachineDomTrees. Differential Revision: https://reviews.llvm.org/D41298 llvm-svn: 326315
1 parent a94a430 commit 7c35de1

File tree

15 files changed

+73
-104
lines changed

15 files changed

+73
-104
lines changed

llvm/include/llvm/Analysis/PostDominators.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ struct PostDominatorTreeWrapperPass : public FunctionPass {
7676

7777
bool runOnFunction(Function &F) override;
7878

79+
void verifyAnalysis() const override;
80+
7981
void getAnalysisUsage(AnalysisUsage &AU) const override {
8082
AU.setPreservesAll();
8183
}

llvm/include/llvm/CodeGen/MachineDominators.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,6 @@ class MachineDominatorTree : public MachineFunctionPass {
249249
"A basic block inserted via edge splitting cannot appear twice");
250250
CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB});
251251
}
252-
253-
/// \brief Verify the correctness of the domtree by re-computing it.
254-
///
255-
/// This should only be used for debugging as it aborts the program if the
256-
/// verification fails.
257-
void verifyDomTree() const;
258252
};
259253

260254
//===-------------------------------------

llvm/include/llvm/IR/Dominators.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,6 @@ class DominatorTree : public DominatorTreeBase<BasicBlock, false> {
174174
/// \brief Provide an overload for a Use.
175175
bool isReachableFromEntry(const Use &U) const;
176176

177-
/// \brief Verify the correctness of the domtree by re-computing it.
178-
///
179-
/// This should only be used for debugging as it aborts the program if the
180-
/// verification fails.
181-
void verifyDomTree() const;
182-
183177
// Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`.
184178
void viewGraph(const Twine &Name, const Twine &Title);
185179
void viewGraph();

llvm/include/llvm/Support/GenericDomTreeConstruction.h

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,7 +1602,8 @@ struct SemiNCAInfo {
16021602
const bool Different = DT.compare(FreshTree);
16031603

16041604
if (Different) {
1605-
errs() << "DominatorTree is different than a freshly computed one!\n"
1605+
errs() << (DT.isPostDominator() ? "Post" : "")
1606+
<< "DominatorTree is different than a freshly computed one!\n"
16061607
<< "\tCurrent:\n";
16071608
DT.print(errs());
16081609
errs() << "\n\tFreshly computed tree:\n";
@@ -1642,34 +1643,27 @@ void ApplyUpdates(DomTreeT &DT,
16421643
template <class DomTreeT>
16431644
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL) {
16441645
SemiNCAInfo<DomTreeT> SNCA(nullptr);
1645-
const bool InitialChecks = SNCA.verifyRoots(DT) &&
1646-
SNCA.verifyReachability(DT) &&
1647-
SNCA.VerifyLevels(DT) && SNCA.VerifyDFSNumbers(DT);
16481646

1649-
if (!InitialChecks)
1647+
// Simplist check is to compare against a new tree. This will also
1648+
// usefully print the old and new trees, if they are different.
1649+
if (!SNCA.IsSameAsFreshTree(DT))
16501650
return false;
16511651

1652-
switch (VL) {
1653-
case DomTreeT::VerificationLevel::Fast:
1654-
return SNCA.IsSameAsFreshTree(DT);
1655-
1656-
case DomTreeT::VerificationLevel::Basic:
1657-
return SNCA.verifyParentProperty(DT) && SNCA.IsSameAsFreshTree(DT);
1658-
1659-
case DomTreeT::VerificationLevel::Full: {
1660-
bool FullRes
1661-
= SNCA.verifyParentProperty(DT) && SNCA.verifySiblingProperty(DT);
1662-
1663-
// Postdominators depend on root selection, make sure that a fresh tree
1664-
// looks the same.
1665-
if (DT.isPostDominator())
1666-
FullRes &= SNCA.IsSameAsFreshTree(DT);
1652+
// Common checks to verify the properties of the tree. O(N log N) at worst
1653+
if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
1654+
!SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
1655+
return false;
16671656

1668-
return FullRes;
1669-
}
1670-
}
1657+
// Extra checks depending on VerificationLevel. Up to O(N^3)
1658+
if (VL == DomTreeT::VerificationLevel::Basic ||
1659+
VL == DomTreeT::VerificationLevel::Full)
1660+
if (!SNCA.verifyParentProperty(DT))
1661+
return false;
1662+
if (VL == DomTreeT::VerificationLevel::Full)
1663+
if (!SNCA.verifySiblingProperty(DT))
1664+
return false;
16711665

1672-
llvm_unreachable("Unhandled DomTree VerificationLevel");
1666+
return true;
16731667
}
16741668

16751669
} // namespace DomTreeBuilder

llvm/lib/Analysis/PostDominators.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ using namespace llvm;
2121

2222
#define DEBUG_TYPE "postdomtree"
2323

24+
#ifdef EXPENSIVE_CHECKS
25+
static constexpr bool ExpensiveChecksEnabled = true;
26+
#else
27+
static constexpr bool ExpensiveChecksEnabled = false;
28+
#endif
29+
2430
//===----------------------------------------------------------------------===//
2531
// PostDominatorTree Implementation
2632
//===----------------------------------------------------------------------===//
@@ -44,6 +50,13 @@ bool PostDominatorTreeWrapperPass::runOnFunction(Function &F) {
4450
return false;
4551
}
4652

53+
void PostDominatorTreeWrapperPass::verifyAnalysis() const {
54+
if (VerifyDomInfo)
55+
assert(DT.verify(PostDominatorTree::VerificationLevel::Full));
56+
else if (ExpensiveChecksEnabled)
57+
assert(DT.verify(PostDominatorTree::VerificationLevel::Basic));
58+
}
59+
4760
void PostDominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const {
4861
DT.print(OS);
4962
}

llvm/lib/CodeGen/MachineDominators.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,21 @@ void MachineDominatorTree::releaseMemory() {
6565
}
6666

6767
void MachineDominatorTree::verifyAnalysis() const {
68-
if (DT && VerifyMachineDomInfo)
69-
verifyDomTree();
68+
if (DT && VerifyMachineDomInfo) {
69+
MachineFunction &F = *getRoot()->getParent();
70+
71+
DomTreeBase<MachineBasicBlock> OtherDT;
72+
OtherDT.recalculate(F);
73+
if (getRootNode()->getBlock() != OtherDT.getRootNode()->getBlock() ||
74+
DT->compare(OtherDT)) {
75+
errs() << "MachineDominatorTree for function " << F.getName()
76+
<< " is not up to date!\nComputed:\n";
77+
DT->print(errs());
78+
errs() << "\nActual:\n";
79+
OtherDT.print(errs());
80+
abort();
81+
}
82+
}
7083
}
7184

7285
void MachineDominatorTree::print(raw_ostream &OS, const Module*) const {
@@ -138,21 +151,3 @@ void MachineDominatorTree::applySplitCriticalEdges() const {
138151
NewBBs.clear();
139152
CriticalEdgesToSplit.clear();
140153
}
141-
142-
void MachineDominatorTree::verifyDomTree() const {
143-
if (!DT)
144-
return;
145-
MachineFunction &F = *getRoot()->getParent();
146-
147-
DomTreeBase<MachineBasicBlock> OtherDT;
148-
OtherDT.recalculate(F);
149-
if (getRootNode()->getBlock() != OtherDT.getRootNode()->getBlock() ||
150-
DT->compare(OtherDT)) {
151-
errs() << "MachineDominatorTree for function " << F.getName()
152-
<< " is not up to date!\nComputed:\n";
153-
DT->print(errs());
154-
errs() << "\nActual:\n";
155-
OtherDT.print(errs());
156-
abort();
157-
}
158-
}

llvm/lib/IR/Dominators.cpp

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -306,23 +306,6 @@ bool DominatorTree::isReachableFromEntry(const Use &U) const {
306306
return isReachableFromEntry(I->getParent());
307307
}
308308

309-
void DominatorTree::verifyDomTree() const {
310-
// Perform the expensive checks only when VerifyDomInfo is set.
311-
VerificationLevel VL = VerificationLevel::Fast;
312-
if (VerifyDomInfo)
313-
VL = VerificationLevel::Full;
314-
else if (ExpensiveChecksEnabled)
315-
VL = VerificationLevel::Basic;
316-
317-
if (!verify(VL)) {
318-
errs() << "\n~~~~~~~~~~~\n\t\tDomTree verification failed!\n~~~~~~~~~~~\n";
319-
errs() << "\nCFG:\n";
320-
getRoot()->getParent()->print(errs());
321-
errs().flush();
322-
abort();
323-
}
324-
}
325-
326309
//===----------------------------------------------------------------------===//
327310
// DominatorTreeAnalysis and related pass implementations
328311
//===----------------------------------------------------------------------===//
@@ -353,8 +336,9 @@ PreservedAnalyses DominatorTreePrinterPass::run(Function &F,
353336

354337
PreservedAnalyses DominatorTreeVerifierPass::run(Function &F,
355338
FunctionAnalysisManager &AM) {
356-
AM.getResult<DominatorTreeAnalysis>(F).verifyDomTree();
357-
339+
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
340+
assert(DT.verify());
341+
(void)DT;
358342
return PreservedAnalyses::all();
359343
}
360344

@@ -377,8 +361,10 @@ bool DominatorTreeWrapperPass::runOnFunction(Function &F) {
377361
}
378362

379363
void DominatorTreeWrapperPass::verifyAnalysis() const {
380-
if (ExpensiveChecksEnabled || VerifyDomInfo)
381-
DT.verifyDomTree();
364+
if (VerifyDomInfo)
365+
assert(DT.verify(DominatorTree::VerificationLevel::Full));
366+
else if (ExpensiveChecksEnabled)
367+
assert(DT.verify(DominatorTree::VerificationLevel::Basic));
382368
}
383369

384370
void DominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const {

llvm/lib/Transforms/Scalar/LoopDistribute.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ class LoopDistributeForLoop {
780780

781781
if (LDistVerify) {
782782
LI->verify(*DT);
783-
DT->verifyDomTree();
783+
assert(DT->verify(DominatorTree::VerificationLevel::Fast));
784784
}
785785

786786
++NumLoopsDistributed;

llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT,
637637
BranchInst::Create(CommonSuccBB, BB);
638638
}
639639

640-
DT.verifyDomTree();
640+
assert(DT.verify(DominatorTree::VerificationLevel::Fast));
641641
++NumTrivial;
642642
++NumSwitches;
643643
return true;
@@ -2079,11 +2079,9 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
20792079
NonTrivialUnswitchCB))
20802080
return PreservedAnalyses::all();
20812081

2082-
#ifndef NDEBUG
20832082
// Historically this pass has had issues with the dominator tree so verify it
20842083
// in asserts builds.
2085-
AR.DT.verifyDomTree();
2086-
#endif
2084+
assert(AR.DT.verify(DominatorTree::VerificationLevel::Fast));
20872085
return getLoopPassPreservedAnalyses();
20882086
}
20892087

@@ -2147,11 +2145,10 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
21472145
// loop.
21482146
LPM.deleteSimpleAnalysisLoop(L);
21492147

2150-
#ifndef NDEBUG
21512148
// Historically this pass has had issues with the dominator tree so verify it
21522149
// in asserts builds.
2153-
DT.verifyDomTree();
2154-
#endif
2150+
assert(DT.verify(DominatorTree::VerificationLevel::Fast));
2151+
21552152
return Changed;
21562153
}
21572154

llvm/lib/Transforms/Utils/LibCallsShrinkWrap.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,10 +529,7 @@ static bool runImpl(Function &F, const TargetLibraryInfo &TLI,
529529
bool Changed = CCDCE.perform();
530530

531531
// Verify the dominator after we've updated it locally.
532-
#ifndef NDEBUG
533-
if (DT)
534-
DT->verifyDomTree();
535-
#endif
532+
assert(!DT || DT->verify(DominatorTree::VerificationLevel::Fast));
536533
return Changed;
537534
}
538535

0 commit comments

Comments
 (0)