https://gcc.gnu.org/g:8498ef3d0758012bf3e355a61a0f89aff7513851

commit r16-4165-g8498ef3d0758012bf3e355a61a0f89aff7513851
Author: Jan Hubicka <[email protected]>
Date:   Wed Oct 1 16:56:15 2025 +0200

    Improve profile update in merge_blocks
    
    When merging blocks we currently alway use count of the first basic block.
    In some cases we merge block containing call to cold noreturn function (thus
    having count 0 (reliable)) with earlier block with weaker form of profile.
    In this case we can still preserve reliable count of 0.
    
    The patch also makes block merging to pick higher of the counts if quality
    is the same.  This should reduce chances of losing track of hot code in 
broken
    profiles.
    
    gcc/ChangeLog:
    
            * cfghooks.cc (merge_blocks): Choose more reliable or higher BB
            count.

Diff:
---
 gcc/cfghooks.cc | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc
index 5f7fc2723745..8b3346898aa2 100644
--- a/gcc/cfghooks.cc
+++ b/gcc/cfghooks.cc
@@ -817,6 +817,15 @@ merge_blocks (basic_block a, basic_block b)
   if (!cfg_hooks->merge_blocks)
     internal_error ("%s does not support merge_blocks", cfg_hooks->name);
 
+  /* Pick the more reliable count.  If both qualities agrees, pick the larger
+     one since turning mistakely hot code to cold is more harmful.  */
+  if (a->count.initialized_p ())
+    a->count = b->count;
+  else if (a->count.quality () < b->count.quality ())
+    a->count = b->count;
+  else if (a->count.quality () == b->count.quality ())
+    a->count = a->count.max (b->count);
+
   cfg_hooks->merge_blocks (a, b);
 
   if (current_loops != NULL)

Reply via email to