diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index c0a60c66ad76bc..07431d8a14e803 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -2091,6 +2091,9 @@ class FlowGraphNaturalLoop // Can be used to store additional annotations for this loop on the side. unsigned m_index = 0; + // True if this loop contains an improper loop header + bool m_containsImproperHeader = false; + FlowGraphNaturalLoop(const FlowGraphDfsTree* dfsTree, BasicBlock* head); unsigned LoopBlockBitVecIndex(BasicBlock* block); @@ -2179,6 +2182,11 @@ class FlowGraphNaturalLoop bool ContainsBlock(BasicBlock* block); bool ContainsLoop(FlowGraphNaturalLoop* childLoop); + bool ContainsImproperHeader() const + { + return m_containsImproperHeader; + } + unsigned NumLoopBlocks(); template diff --git a/src/coreclr/jit/fgprofilesynthesis.cpp b/src/coreclr/jit/fgprofilesynthesis.cpp index 2de615136cfeb4..0ab8576cb24b86 100644 --- a/src/coreclr/jit/fgprofilesynthesis.cpp +++ b/src/coreclr/jit/fgprofilesynthesis.cpp @@ -1193,12 +1193,14 @@ void ProfileSynthesis::GaussSeidelSolver() // if (block->bbPreds != nullptr) { - // Leverage Cp for existing loop headers. + // Leverage Cp for existing loop headers, provided that + // all contained loops are proper. + // // This is an optimization to speed convergence. // FlowGraphNaturalLoop* const loop = m_loops->GetLoopByHeader(block); - if (loop != nullptr) + if ((loop != nullptr) && !loop->ContainsImproperHeader()) { // Sum all entry edges that aren't EH flow // diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 9b9f3a3f951418..e2f450a7cb194d 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -4386,6 +4386,15 @@ FlowGraphNaturalLoops* FlowGraphNaturalLoops::Find(const FlowGraphDfsTree* dfsTr if (!FindNaturalLoopBlocks(loop, worklist)) { loops->m_improperLoopHeaders++; + + for (FlowGraphNaturalLoop* const otherLoop : loops->InPostOrder()) + { + if (otherLoop->ContainsBlock(header)) + { + otherLoop->m_containsImproperHeader = true; + } + } + continue; }