llvm.org GIT mirror llvm / 83971cb
[Dominators] Add NearestCommonDominator verification Summary: This patch adds another verification function for checking correctness of findNearestCommonDominator. For every edge from U to V in the input graph, `NCD(U, V) == IDom(V) or V` -- the new function checks this condition. Reviewers: dberlin, sanjoy, chandlerc Reviewed By: dberlin Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34575 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306893 91177308-0d34-0410-b5e6-96231b3b80d8 Jakub Kuderski 3 years ago
2 changed file(s) with 44 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
406406
407407 /// findNearestCommonDominator - Find nearest common dominator basic block
408408 /// for basic block A and B. If there is no such block then return NULL.
409 NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
409 NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const {
410410 assert(A->getParent() == B->getParent() &&
411411 "Two blocks are not in same function");
412412
432432 return NodeA ? NodeA->getBlock() : nullptr;
433433 }
434434
435 const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
435 const NodeT *findNearestCommonDominator(const NodeT *A,
436 const NodeT *B) const {
436437 // Cast away the const qualifiers here. This is ok since
437438 // const is re-introduced on the return type.
438439 return findNearestCommonDominator(const_cast(A),
279279 }
280280
281281 void doFullDFSWalk(const DomTreeT &DT) {
282 NumToNode.push_back(nullptr);
282283 unsigned Num = 0;
283284 for (auto *Root : DT.Roots)
284285 if (!DT.isPostDominator())
341342 errs() << " has level " << TN->getLevel() << " while it's IDom ";
342343 PrintBlockOrNullptr(errs(), IDom->getBlock());
343344 errs() << " has level " << IDom->getLevel() << "!\n";
345 errs().flush();
346
347 return false;
348 }
349 }
350
351 return true;
352 }
353
354 // Checks if for every edge From -> To in the graph
355 // NCD(From, To) == IDom(To) or To.
356 bool verifyNCD(const DomTreeT &DT) {
357 clear();
358 doFullDFSWalk(DT);
359
360 for (auto &BlockToInfo : NodeToInfo) {
361 auto &Info = BlockToInfo.second;
362
363 const NodePtr From = NumToNode[Info.Parent];
364 if (!From) continue;
365
366 const NodePtr To = BlockToInfo.first;
367 const TreeNodePtr ToTN = DT.getNode(To);
368 assert(ToTN);
369
370 const NodePtr NCD = DT.findNearestCommonDominator(From, To);
371 const TreeNodePtr NCDTN = NCD ? DT.getNode(NCD) : nullptr;
372 const TreeNodePtr ToIDom = ToTN->getIDom();
373 if (NCDTN != ToTN && NCDTN != ToIDom) {
374 errs() << "NearestCommonDominator verification failed:\n\tNCD(From:";
375 PrintBlockOrNullptr(errs(), From);
376 errs() << ", To:";
377 PrintBlockOrNullptr(errs(), To);
378 errs() << ") = ";
379 PrintBlockOrNullptr(errs(), NCD);
380 errs() << ",\t (should be To or IDom[To]: ";
381 PrintBlockOrNullptr(errs(), ToIDom ? ToIDom->getBlock() : nullptr);
382 errs() << ")\n";
344383 errs().flush();
345384
346385 return false;
438477 SemiNCAInfo::type> SNCA;
439478
440479 return SNCA.verifyReachability(DT) && SNCA.VerifyLevels(DT) &&
441 SNCA.verifyParentProperty(DT) && SNCA.verifySiblingProperty(DT);
480 SNCA.verifyNCD(DT) && SNCA.verifyParentProperty(DT) &&
481 SNCA.verifySiblingProperty(DT);
442482 }
443483
444484 } // namespace DomTreeBuilder