diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index b69ccd18f96480..6b363672a1348c 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -2323,6 +2323,11 @@ class FlowGraphDominatorTree static BasicBlock* IntersectDom(BasicBlock* block1, BasicBlock* block2); public: + const FlowGraphDfsTree* GetDfsTree() + { + return m_dfsTree; + } + BasicBlock* Intersect(BasicBlock* block, BasicBlock* block2); bool Dominates(BasicBlock* dominator, BasicBlock* dominated); @@ -2357,23 +2362,28 @@ class BlockToNaturalLoopMap // exceptional flow, then CanReach returns false. class BlockReachabilitySets { - FlowGraphDfsTree* m_dfsTree; + const FlowGraphDfsTree* m_dfsTree; BitVec* m_reachabilitySets; - BlockReachabilitySets(FlowGraphDfsTree* dfsTree, BitVec* reachabilitySets) + BlockReachabilitySets(const FlowGraphDfsTree* dfsTree, BitVec* reachabilitySets) : m_dfsTree(dfsTree) , m_reachabilitySets(reachabilitySets) { } public: + const FlowGraphDfsTree* GetDfsTree() + { + return m_dfsTree; + } + bool CanReach(BasicBlock* from, BasicBlock* to); #ifdef DEBUG void Dump(); #endif - static BlockReachabilitySets* Build(FlowGraphDfsTree* dfsTree); + static BlockReachabilitySets* Build(const FlowGraphDfsTree* dfsTree); }; enum class FieldKindForVN @@ -6095,7 +6105,7 @@ class Compiler bool fgDebugCheckIncomingProfileData(BasicBlock* block, ProfileChecks checks); bool fgDebugCheckOutgoingProfileData(BasicBlock* block, ProfileChecks checks); - void fgDebugCheckDfsTree(); + void fgDebugCheckFlowGraphAnnotations(); #endif // DEBUG diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index 3818cbcd471df1..772cfc2b078178 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -4743,10 +4743,17 @@ void Compiler::fgDebugCheckLoops() } //------------------------------------------------------------------------------ -// fgDebugCheckDfsTree: Checks that the DFS tree matches the current flow graph. +// fgDebugCheckFlowGraphAnnotations: Checks that all flow graph annotations +// that are currently non-null are valid. // -void Compiler::fgDebugCheckDfsTree() +void Compiler::fgDebugCheckFlowGraphAnnotations() { + if (m_dfsTree == nullptr) + { + assert((m_loops == nullptr) && (m_domTree == nullptr) && (m_reachabilitySets == nullptr)); + return; + } + unsigned count = fgRunDfs([](BasicBlock* block, unsigned preorderNum) { assert(block->bbPreorderNum == preorderNum); }, [=](BasicBlock* block, unsigned postorderNum) { @@ -4756,6 +4763,10 @@ void Compiler::fgDebugCheckDfsTree() [](BasicBlock* block, BasicBlock* succ) {}); assert(m_dfsTree->GetPostOrderCount() == count); + + assert((m_loops == nullptr) || (m_loops->GetDfsTree() == m_dfsTree)); + assert((m_domTree == nullptr) || (m_domTree->GetDfsTree() == m_dfsTree)); + assert((m_reachabilitySets == nullptr) || (m_reachabilitySets->GetDfsTree() == m_dfsTree)); } /*****************************************************************************/ diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index b621739a41cddb..4055a10f097179 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -6146,7 +6146,7 @@ BlockToNaturalLoopMap* BlockToNaturalLoopMap::Build(FlowGraphNaturalLoops* loops // This algorithm consumes O(n^2) memory because we're using dense // bitsets to represent reachability. // -BlockReachabilitySets* BlockReachabilitySets::Build(FlowGraphDfsTree* dfsTree) +BlockReachabilitySets* BlockReachabilitySets::Build(const FlowGraphDfsTree* dfsTree) { Compiler* comp = dfsTree->GetCompiler(); BitVecTraits postOrderTraits = dfsTree->PostOrderTraits(); diff --git a/src/coreclr/jit/phase.cpp b/src/coreclr/jit/phase.cpp index 717d0a7d270d5e..78bf4eec09c752 100644 --- a/src/coreclr/jit/phase.cpp +++ b/src/coreclr/jit/phase.cpp @@ -171,10 +171,7 @@ void Phase::PostPhase(PhaseStatus status) comp->fgDebugCheckLinkedLocals(); } - if (comp->m_dfsTree != nullptr) - { - comp->fgDebugCheckDfsTree(); - } + comp->fgDebugCheckFlowGraphAnnotations(); } #endif // DEBUG }