From bf5b1c0ffb0aff0c74bba6af61b47497809b3913 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 27 Mar 2024 19:27:20 -0700 Subject: [PATCH] JIT: fix count reconstruction problem In large methods with lots of irreducible loops we may find reconstructed counts reaching very large values. Since profile counts in practice won't ever be much larger than say 10^12, detect when reconstructed counts exceed this value, and stop the algorithm. We may eventually decide to rerun in "hard blend" mode where we intentionally limit the edge likelihood ranges. But this should do for now. Closes #100350. --- src/coreclr/jit/fgprofilesynthesis.cpp | 12 ++++++++++++ src/coreclr/jit/fgprofilesynthesis.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/coreclr/jit/fgprofilesynthesis.cpp b/src/coreclr/jit/fgprofilesynthesis.cpp index d76dcece8220d..5e9748abc0272 100644 --- a/src/coreclr/jit/fgprofilesynthesis.cpp +++ b/src/coreclr/jit/fgprofilesynthesis.cpp @@ -1289,6 +1289,12 @@ void ProfileSynthesis::GaussSeidelSolver() residual = change; residualBlock = block; } + + if (newWeight >= maxCount) + { + JITDUMP("count overflow in " FMT_BB ": " FMT_WT "\n", block->bbNum, newWeight); + m_overflow = true; + } } // If there were no improper headers, we will have converged in one pass. @@ -1312,6 +1318,12 @@ void ProfileSynthesis::GaussSeidelSolver() break; } + if (m_overflow) + { + printf("*** Overflowed counts in %s\n", m_comp->info.compFullName); + break; + } + // If we have been iterating for a bit, estimate the dominant GS // eigenvalue. (we might want to start with Jacobi iterations // to get the Jacobi eigenvalue instead). diff --git a/src/coreclr/jit/fgprofilesynthesis.h b/src/coreclr/jit/fgprofilesynthesis.h index c5e3883bdca00..216bd58297286 100644 --- a/src/coreclr/jit/fgprofilesynthesis.h +++ b/src/coreclr/jit/fgprofilesynthesis.h @@ -51,6 +51,7 @@ class ProfileSynthesis static constexpr weight_t ilNextLikelihood = 0.52; static constexpr weight_t loopBackLikelihood = 0.9; static constexpr weight_t loopExitLikelihood = 0.9; + static constexpr weight_t maxCount = 1e12; void Run(ProfileSynthesisOption option); @@ -84,6 +85,7 @@ class ProfileSynthesis unsigned m_improperLoopHeaders = 0; unsigned m_cappedCyclicProbabilities = 0; bool m_approximate = false; + bool m_overflow = false; }; #endif // !_FGPROFILESYNTHESIS_H_