llvm.org GIT mirror llvm / dfc9aa7
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326315 91177308-0d34-0410-b5e6-96231b3b80d8 David Green 2 years ago
15 changed file(s) with 76 addition(s) and 107 deletion(s). Raw diff Collapse all Expand all
7575
7676 bool runOnFunction(Function &F) override;
7777
78 void verifyAnalysis() const override;
79
7880 void getAnalysisUsage(AnalysisUsage &AU) const override {
7981 AU.setPreservesAll();
8082 }
248248 "A basic block inserted via edge splitting cannot appear twice");
249249 CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB});
250250 }
251
252 /// \brief Verify the correctness of the domtree by re-computing it.
253 ///
254 /// This should only be used for debugging as it aborts the program if the
255 /// verification fails.
256 void verifyDomTree() const;
257251 };
258252
259253 //===-------------------------------------
172172
173173 /// \brief Provide an overload for a Use.
174174 bool isReachableFromEntry(const Use &U) const;
175
176 /// \brief Verify the correctness of the domtree by re-computing it.
177 ///
178 /// This should only be used for debugging as it aborts the program if the
179 /// verification fails.
180 void verifyDomTree() const;
181175
182176 // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`.
183177 void viewGraph(const Twine &Name, const Twine &Title);
16011601 const bool Different = DT.compare(FreshTree);
16021602
16031603 if (Different) {
1604 errs() << "DominatorTree is different than a freshly computed one!\n"
1604 errs() << (DT.isPostDominator() ? "Post" : "")
1605 << "DominatorTree is different than a freshly computed one!\n"
16051606 << "\tCurrent:\n";
16061607 DT.print(errs());
16071608 errs() << "\n\tFreshly computed tree:\n";
16411642 template
16421643 bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL) {
16431644 SemiNCAInfo SNCA(nullptr);
1644 const bool InitialChecks = SNCA.verifyRoots(DT) &&
1645 SNCA.verifyReachability(DT) &&
1646 SNCA.VerifyLevels(DT) && SNCA.VerifyDFSNumbers(DT);
1647
1648 if (!InitialChecks)
1645
1646 // Simplist check is to compare against a new tree. This will also
1647 // usefully print the old and new trees, if they are different.
1648 if (!SNCA.IsSameAsFreshTree(DT))
16491649 return false;
16501650
1651 switch (VL) {
1652 case DomTreeT::VerificationLevel::Fast:
1653 return SNCA.IsSameAsFreshTree(DT);
1654
1655 case DomTreeT::VerificationLevel::Basic:
1656 return SNCA.verifyParentProperty(DT) && SNCA.IsSameAsFreshTree(DT);
1657
1658 case DomTreeT::VerificationLevel::Full: {
1659 bool FullRes
1660 = SNCA.verifyParentProperty(DT) && SNCA.verifySiblingProperty(DT);
1661
1662 // Postdominators depend on root selection, make sure that a fresh tree
1663 // looks the same.
1664 if (DT.isPostDominator())
1665 FullRes &= SNCA.IsSameAsFreshTree(DT);
1666
1667 return FullRes;
1668 }
1669 }
1670
1671 llvm_unreachable("Unhandled DomTree VerificationLevel");
1651 // Common checks to verify the properties of the tree. O(N log N) at worst
1652 if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
1653 !SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
1654 return false;
1655
1656 // Extra checks depending on VerificationLevel. Up to O(N^3)
1657 if (VL == DomTreeT::VerificationLevel::Basic ||
1658 VL == DomTreeT::VerificationLevel::Full)
1659 if (!SNCA.verifyParentProperty(DT))
1660 return false;
1661 if (VL == DomTreeT::VerificationLevel::Full)
1662 if (!SNCA.verifySiblingProperty(DT))
1663 return false;
1664
1665 return true;
16721666 }
16731667
16741668 } // namespace DomTreeBuilder
2020
2121 #define DEBUG_TYPE "postdomtree"
2222
23 #ifdef EXPENSIVE_CHECKS
24 static constexpr bool ExpensiveChecksEnabled = true;
25 #else
26 static constexpr bool ExpensiveChecksEnabled = false;
27 #endif
28
2329 //===----------------------------------------------------------------------===//
2430 // PostDominatorTree Implementation
2531 //===----------------------------------------------------------------------===//
4147 bool PostDominatorTreeWrapperPass::runOnFunction(Function &F) {
4248 DT.recalculate(F);
4349 return false;
50 }
51
52 void PostDominatorTreeWrapperPass::verifyAnalysis() const {
53 if (VerifyDomInfo)
54 assert(DT.verify(PostDominatorTree::VerificationLevel::Full));
55 else if (ExpensiveChecksEnabled)
56 assert(DT.verify(PostDominatorTree::VerificationLevel::Basic));
4457 }
4558
4659 void PostDominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const {
6464 }
6565
6666 void MachineDominatorTree::verifyAnalysis() const {
67 if (DT && VerifyMachineDomInfo)
68 verifyDomTree();
67 if (DT && VerifyMachineDomInfo) {
68 MachineFunction &F = *getRoot()->getParent();
69
70 DomTreeBase OtherDT;
71 OtherDT.recalculate(F);
72 if (getRootNode()->getBlock() != OtherDT.getRootNode()->getBlock() ||
73 DT->compare(OtherDT)) {
74 errs() << "MachineDominatorTree for function " << F.getName()
75 << " is not up to date!\nComputed:\n";
76 DT->print(errs());
77 errs() << "\nActual:\n";
78 OtherDT.print(errs());
79 abort();
80 }
81 }
6982 }
7083
7184 void MachineDominatorTree::print(raw_ostream &OS, const Module*) const {
137150 NewBBs.clear();
138151 CriticalEdgesToSplit.clear();
139152 }
140
141 void MachineDominatorTree::verifyDomTree() const {
142 if (!DT)
143 return;
144 MachineFunction &F = *getRoot()->getParent();
145
146 DomTreeBase OtherDT;
147 OtherDT.recalculate(F);
148 if (getRootNode()->getBlock() != OtherDT.getRootNode()->getBlock() ||
149 DT->compare(OtherDT)) {
150 errs() << "MachineDominatorTree for function " << F.getName()
151 << " is not up to date!\nComputed:\n";
152 DT->print(errs());
153 errs() << "\nActual:\n";
154 OtherDT.print(errs());
155 abort();
156 }
157 }
305305 return isReachableFromEntry(I->getParent());
306306 }
307307
308 void DominatorTree::verifyDomTree() const {
309 // Perform the expensive checks only when VerifyDomInfo is set.
310 VerificationLevel VL = VerificationLevel::Fast;
311 if (VerifyDomInfo)
312 VL = VerificationLevel::Full;
313 else if (ExpensiveChecksEnabled)
314 VL = VerificationLevel::Basic;
315
316 if (!verify(VL)) {
317 errs() << "\n~~~~~~~~~~~\n\t\tDomTree verification failed!\n~~~~~~~~~~~\n";
318 errs() << "\nCFG:\n";
319 getRoot()->getParent()->print(errs());
320 errs().flush();
321 abort();
322 }
323 }
324
325308 //===----------------------------------------------------------------------===//
326309 // DominatorTreeAnalysis and related pass implementations
327310 //===----------------------------------------------------------------------===//
352335
353336 PreservedAnalyses DominatorTreeVerifierPass::run(Function &F,
354337 FunctionAnalysisManager &AM) {
355 AM.getResult(F).verifyDomTree();
356
338 auto &DT = AM.getResult(F);
339 assert(DT.verify());
340 (void)DT;
357341 return PreservedAnalyses::all();
358342 }
359343
376360 }
377361
378362 void DominatorTreeWrapperPass::verifyAnalysis() const {
379 if (ExpensiveChecksEnabled || VerifyDomInfo)
380 DT.verifyDomTree();
363 if (VerifyDomInfo)
364 assert(DT.verify(DominatorTree::VerificationLevel::Full));
365 else if (ExpensiveChecksEnabled)
366 assert(DT.verify(DominatorTree::VerificationLevel::Basic));
381367 }
382368
383369 void DominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const {
779779
780780 if (LDistVerify) {
781781 LI->verify(*DT);
782 DT->verifyDomTree();
782 assert(DT->verify(DominatorTree::VerificationLevel::Fast));
783783 }
784784
785785 ++NumLoopsDistributed;
636636 BranchInst::Create(CommonSuccBB, BB);
637637 }
638638
639 DT.verifyDomTree();
639 assert(DT.verify(DominatorTree::VerificationLevel::Fast));
640640 ++NumTrivial;
641641 ++NumSwitches;
642642 return true;
20782078 NonTrivialUnswitchCB))
20792079 return PreservedAnalyses::all();
20802080
2081 #ifndef NDEBUG
20822081 // Historically this pass has had issues with the dominator tree so verify it
20832082 // in asserts builds.
2084 AR.DT.verifyDomTree();
2085 #endif
2083 assert(AR.DT.verify(DominatorTree::VerificationLevel::Fast));
20862084 return getLoopPassPreservedAnalyses();
20872085 }
20882086
21462144 // loop.
21472145 LPM.deleteSimpleAnalysisLoop(L);
21482146
2149 #ifndef NDEBUG
21502147 // Historically this pass has had issues with the dominator tree so verify it
21512148 // in asserts builds.
2152 DT.verifyDomTree();
2153 #endif
2149 assert(DT.verify(DominatorTree::VerificationLevel::Fast));
2150
21542151 return Changed;
21552152 }
21562153
528528 bool Changed = CCDCE.perform();
529529
530530 // Verify the dominator after we've updated it locally.
531 #ifndef NDEBUG
532 if (DT)
533 DT->verifyDomTree();
534 #endif
531 assert(!DT || DT->verify(DominatorTree::VerificationLevel::Fast));
535532 return Changed;
536533 }
537534
768768 }
769769 }
770770
771 if (DT && UnrollVerifyDomtree)
772 DT->verifyDomTree();
771 assert(!DT || !UnrollVerifyDomtree ||
772 DT->verify(DominatorTree::VerificationLevel::Fast));
773773
774774 // Merge adjacent basic blocks, if possible.
775775 SmallPtrSet ForgottenLoops;
499499 // the original loop body.
500500 if (Iter == 0)
501501 DT->changeImmediateDominator(Exit, cast(LVMap[Latch]));
502 #ifndef NDEBUG
503 if (VerifyDomInfo)
504 DT->verifyDomTree();
505 #endif
502 assert(DT->verify(DominatorTree::VerificationLevel::Fast));
506503 }
507504
508505 updateBranchWeights(InsertBot, cast(VMap[LatchBR]), Iter,
47784778 DT->addNewBlock(LoopScalarPreHeader, LoopBypassBlocks[0]);
47794779 DT->changeImmediateDominator(LoopScalarBody, LoopScalarPreHeader);
47804780 DT->changeImmediateDominator(LoopExitBlock, LoopBypassBlocks[0]);
4781 DEBUG(DT->verifyDomTree());
4781 assert(DT->verify(DominatorTree::VerificationLevel::Fast));
47824782 }
47834783
47844784 /// \brief Check whether it is safe to if-convert this phi node.
263263 EXPECT_EQ(DT->getNode(BB4)->getLevel(), 1U);
264264
265265 // Change root node
266 DT->verifyDomTree();
266 EXPECT_TRUE(DT->verify());
267267 BasicBlock *NewEntry =
268268 BasicBlock::Create(F.getContext(), "new_entry", &F, BB0);
269269 BranchInst::Create(BB0, NewEntry);
270270 EXPECT_EQ(F.begin()->getName(), NewEntry->getName());
271271 EXPECT_TRUE(&F.getEntryBlock() == NewEntry);
272272 DT->setNewRoot(NewEntry);
273 DT->verifyDomTree();
273 EXPECT_TRUE(DT->verify());
274274 });
275275 }
276276
961961 AR.DT.addNewBlock(NewLoop010PHBB, &Loop01BB);
962962 AR.DT.addNewBlock(NewLoop010BB, NewLoop010PHBB);
963963 AR.DT.addNewBlock(NewLoop01LatchBB, NewLoop010BB);
964 AR.DT.verifyDomTree();
964 EXPECT_TRUE(AR.DT.verify());
965965 L.addBasicBlockToLoop(NewLoop010PHBB, AR.LI);
966966 NewLoop->addBasicBlockToLoop(NewLoop010BB, AR.LI);
967967 L.addBasicBlockToLoop(NewLoop01LatchBB, AR.LI);
10031003 AR.DT.addNewBlock(NewLoop011PHBB, NewLoop010BB);
10041004 auto *NewDTNode = AR.DT.addNewBlock(NewLoop011BB, NewLoop011PHBB);
10051005 AR.DT.changeImmediateDominator(AR.DT[NewLoop01LatchBB], NewDTNode);
1006 AR.DT.verifyDomTree();
1006 EXPECT_TRUE(AR.DT.verify());
10071007 L.addBasicBlockToLoop(NewLoop011PHBB, AR.LI);
10081008 NewLoop->addBasicBlockToLoop(NewLoop011BB, AR.LI);
10091009 NewLoop->verifyLoop();
11481148 AR.DT.addNewBlock(NewLoop01PHBB, &Loop00BB);
11491149 auto *NewDTNode = AR.DT.addNewBlock(NewLoop01BB, NewLoop01PHBB);
11501150 AR.DT.changeImmediateDominator(AR.DT[&Loop02PHBB], NewDTNode);
1151 AR.DT.verifyDomTree();
1151 EXPECT_TRUE(AR.DT.verify());
11521152 L.getParentLoop()->addBasicBlockToLoop(NewLoop01PHBB, AR.LI);
11531153 NewLoop->addBasicBlockToLoop(NewLoop01BB, AR.LI);
11541154 L.getParentLoop()->verifyLoop();
12151215 AR.DT.addNewBlock(NewLoop040PHBB, NewLoop04BB);
12161216 AR.DT.addNewBlock(NewLoop040BB, NewLoop040PHBB);
12171217 AR.DT.addNewBlock(NewLoop04LatchBB, NewLoop040BB);
1218 AR.DT.verifyDomTree();
1218 EXPECT_TRUE(AR.DT.verify());
12191219 L.getParentLoop()->addBasicBlockToLoop(NewLoop03PHBB, AR.LI);
12201220 NewLoops[0]->addBasicBlockToLoop(NewLoop03BB, AR.LI);
12211221 L.getParentLoop()->addBasicBlockToLoop(NewLoop04PHBB, AR.LI);
12701270 AR.DT.addNewBlock(NewLoop1PHBB, &Loop0BB);
12711271 auto *NewDTNode = AR.DT.addNewBlock(NewLoop1BB, NewLoop1PHBB);
12721272 AR.DT.changeImmediateDominator(AR.DT[&Loop2PHBB], NewDTNode);
1273 AR.DT.verifyDomTree();
1273 EXPECT_TRUE(AR.DT.verify());
12741274 NewLoop->addBasicBlockToLoop(NewLoop1BB, AR.LI);
12751275 NewLoop->verifyLoop();
12761276 Updater.addSiblingLoops({NewLoop});
15071507 AR.DT.addNewBlock(NewLoop03BB, NewLoop03PHBB);
15081508 AR.DT.changeImmediateDominator(AR.DT[&Loop0LatchBB],
15091509 AR.DT[NewLoop03BB]);
1510 AR.DT.verifyDomTree();
1510 EXPECT_TRUE(AR.DT.verify());
15111511 ParentL->addBasicBlockToLoop(NewLoop03PHBB, AR.LI);
15121512 NewSibling->addBasicBlockToLoop(NewLoop03BB, AR.LI);
15131513 NewSibling->verifyLoop();