Hi,
profile updating in tail merging is completely wrong when profile feedback
is missing or 0.  This fixes it hopefully reasonably.
Bootstrapped/regtested x86_64-linux.

Honza

        * tree-ssa-tail-merge.c (replace_block_by): Fix profile updating.
Index: tree-ssa-tail-merge.c
===================================================================
--- tree-ssa-tail-merge.c       (revision 249244)
+++ tree-ssa-tail-merge.c       (working copy)
@@ -1555,29 +1555,51 @@ replace_block_by (basic_block bb1, basic
                   pred_edge, UNKNOWN_LOCATION);
     }
 
-  bb2->frequency += bb1->frequency;
-  if (bb2->frequency > BB_FREQ_MAX)
-    bb2->frequency = BB_FREQ_MAX;
-
   bb2->count += bb1->count;
 
   /* Merge the outgoing edge counts from bb1 onto bb2.  */
   profile_count out_sum = profile_count::zero ();
+  int out_freq_sum = 0;
+
+  /* Recompute the edge probabilities from the new merged edge count.
+     Use the sum of the new merged edge counts computed above instead
+     of bb2's merged count, in case there are profile count insanities
+     making the bb count inconsistent with the edge weights.  */
+  FOR_EACH_EDGE (e1, ei, bb1->succs)
+    {
+      if (e1->count.initialized_p ())
+       out_sum += e1->count;
+      out_freq_sum += EDGE_FREQUENCY (e1);
+    }
+  FOR_EACH_EDGE (e1, ei, bb2->succs)
+    {
+      if (e1->count.initialized_p ())
+       out_sum += e1->count;
+      out_freq_sum += EDGE_FREQUENCY (e1);
+    }
+
   FOR_EACH_EDGE (e1, ei, bb1->succs)
     {
       e2 = find_edge (bb2, e1->dest);
       gcc_assert (e2);
       e2->count += e1->count;
+      if (out_sum > 0 && e2->count.initialized_p ())
+       {
+         e2->probability = e2->count.probability_in (bb2->count);
+       }
+      else if (bb1->frequency && bb2->frequency)
+       e2->probability = e1->probability;
+      else if (bb2->frequency && !bb1->frequency)
+       ;
+      else if (out_freq_sum)
+       e2->probability = GCOV_COMPUTE_SCALE (EDGE_FREQUENCY (e1)
+                                             + EDGE_FREQUENCY (e2),
+                                             out_freq_sum);
       out_sum += e2->count;
     }
-  /* Recompute the edge probabilities from the new merged edge count.
-     Use the sum of the new merged edge counts computed above instead
-     of bb2's merged count, in case there are profile count insanities
-     making the bb count inconsistent with the edge weights.  */
-  FOR_EACH_EDGE (e2, ei, bb2->succs)
-    {
-      e2->probability = e2->count.probability_in (out_sum);
-    }
+  bb2->frequency += bb1->frequency;
+  if (bb2->frequency > BB_FREQ_MAX)
+    bb2->frequency = BB_FREQ_MAX;
 
   /* Move over any user labels from bb1 after the bb2 labels.  */
   gimple_stmt_iterator gsi1 = gsi_start_bb (bb1);

Reply via email to