]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Improve profile update in merge_blocks
authorJan Hubicka <hubicka@ucw.cz>
Wed, 1 Oct 2025 14:56:15 +0000 (16:56 +0200)
committerJan Hubicka <hubicka@ucw.cz>
Wed, 1 Oct 2025 14:56:15 +0000 (16:56 +0200)
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.

gcc/cfghooks.cc

index 5f7fc27237456fa8df740df194de3afc2fde66a3..8b3346898aa26b2e64522d46b5cdf4d25a24f5f4 100644 (file)
@@ -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)