From 8fb9cfe141ea0ad6e8ec695273b2b8f901ea24c0 Mon Sep 17 00:00:00 2001 From: Adam Nemet Date: Sat, 31 May 2014 16:23:20 +0000 Subject: [PATCH] [SelectionDAG] Force cycle detection in AssignTopologicalOrder before aborting DAG cycle detection is only enabled with ENABLE_EXPENSIVE_CHECKS. However we can run it just before we would crash in order to provide more informative diagnostics. Now in addition to the "Overran sorted position" message we also get the Node printed if a cycle was detected. Tested by building several configs: Debug+Assert, Debug+Assert+Check (this is ENABLE_EXPENSIVE_CHECKS), Release+Assert and Release. Also tried that the AssignTopologicalOrder assert produces the expected results. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209977 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 2 +- include/llvm/CodeGen/SelectionDAGNodes.h | 3 ++- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 27 +++++++++++++++-------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 66473554d03..c6d716a5355 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -151,7 +151,7 @@ public: }; class SelectionDAG; -void checkForCycles(const SelectionDAG *DAG); +void checkForCycles(const SelectionDAG *DAG, bool force = false); /// SelectionDAG class - This is used to represent a portion of an LLVM function /// in a low-level Data Dependence DAG representation suitable for instruction diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index f281a069706..09cac428418 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -49,7 +49,8 @@ template struct DenseMapInfo; template struct simplify_type; template struct ilist_traits; -void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr); +void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr, + bool force = false); /// SDVTList - This represents a list of ValueType's that has been intern'd by /// a SelectionDAG. Instances of this simple value class are returned by diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 0f1d9758348..b701add2de3 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -6002,6 +6002,8 @@ unsigned SelectionDAG::AssignTopologicalOrder() { SDNode *S = ++I; dbgs() << "Overran sorted position:\n"; S->dumprFull(this); dbgs() << "\n"; + dbgs() << "Checking if this is due to cycles\n"; + checkForCycles(this, true); #endif llvm_unreachable(nullptr); } @@ -6587,7 +6589,7 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) { return true; } -#ifdef XDEBUG +#ifndef NDEBUG static void checkForCyclesHelper(const SDNode *N, SmallPtrSet &Visited, SmallPtrSet &Checked, @@ -6614,15 +6616,22 @@ static void checkForCyclesHelper(const SDNode *N, #endif void llvm::checkForCycles(const llvm::SDNode *N, - const llvm::SelectionDAG *DAG) { + const llvm::SelectionDAG *DAG, + bool force) { +#ifndef NDEBUG + bool check = force; #ifdef XDEBUG - assert(N && "Checking nonexistent SDNode"); - SmallPtrSet visited; - SmallPtrSet checked; - checkForCyclesHelper(N, visited, checked, DAG); -#endif + check = true; +#endif // XDEBUG + if (check) { + assert(N && "Checking nonexistent SDNode"); + SmallPtrSet visited; + SmallPtrSet checked; + checkForCyclesHelper(N, visited, checked, DAG); + } +#endif // !NDEBUG } -void llvm::checkForCycles(const llvm::SelectionDAG *DAG) { - checkForCycles(DAG->getRoot().getNode(), DAG); +void llvm::checkForCycles(const llvm::SelectionDAG *DAG, bool force) { + checkForCycles(DAG->getRoot().getNode(), DAG, force); } -- 2.34.1