Hi,
this patch fixes two issues triggered by testcase in PR middle-end/81290.
First is that jump threading has hack converting frequencies to counts
and computing probabilities out of them.  This gets wrong quality for
these. Second is that force_edge_cold is bit overzelaous when propagate
coldnes backward across CFG.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

        PR middle-end/81290
        * predict.c (force_edge_cold): Be more careful about propagation
        backward.
        * profile-count.h (profile_probability::guessed,
        profile_probability::fdo, profile_count::guessed, profile_count::fdo):
        New.
        * tree-ssa-threadupdate.c (recompute_probabilities): Result is guessed.

        * gcc.c-torture/compile/pr81290.c: New.
Index: predict.c
===================================================================
--- predict.c   (revision 249906)
+++ predict.c   (working copy)
@@ -3962,15 +3962,26 @@ force_edge_cold (edge e, bool impossible
              e2->count.apply_scale (count_sum2, count_sum);
            e2->probability /= prob_comp;
          }
-      if (current_ir_type () != IR_GIMPLE)
+      if (current_ir_type () != IR_GIMPLE
+         && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
        update_br_prob_note (e->src);
     }
   /* If all edges out of e->src are unlikely, the basic block itself
      is unlikely.  */
   else
     {
-      e->probability = profile_probability::always ();
-      if (current_ir_type () != IR_GIMPLE)
+      if (prob_sum == profile_probability::never ())
+        e->probability = profile_probability::always ();
+      else
+       {
+         if (impossible)
+           e->probability = profile_probability::never ();
+         /* If BB has some edges out that are not impossible, we can not
+            assume that BB itself is.  */
+         impossible = false;
+       }
+      if (current_ir_type () != IR_GIMPLE
+         && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
        update_br_prob_note (e->src);
       if (e->src->count == profile_count::zero ())
        return;
Index: profile-count.h
===================================================================
--- profile-count.h     (revision 249907)
+++ profile-count.h     (working copy)
@@ -351,6 +351,22 @@ public:
       return profile_probability::always() - *this;
     }
 
+  /* Return THIS with quality dropped to GUESSED.  */
+  profile_probability guessed () const
+    {
+      profile_probability ret = *this;
+      ret.m_quality = profile_guessed;
+      return ret;
+    }
+
+  /* Return THIS with quality dropped to AFDO.  */
+  profile_probability afdo () const
+    {
+      profile_probability ret = *this;
+      ret.m_quality = profile_afdo;
+      return ret;
+    }
+
   profile_probability combine_with_freq (int freq1, profile_probability other,
                                         int freq2) const
     {
@@ -767,6 +783,22 @@ public:
       return ret;
     }
 
+  /* Return THIS with quality dropped to GUESSED.  */
+  profile_count guessed () const
+    {
+      profile_count ret = *this;
+      ret.m_quality = profile_guessed;
+      return ret;
+    }
+
+  /* Return THIS with quality dropped to AFDO.  */
+  profile_count afdo () const
+    {
+      profile_count ret = *this;
+      ret.m_quality = profile_afdo;
+      return ret;
+    }
+
   /* Return probability of event with counter THIS within event with counter
      OVERALL.  */
   profile_probability probability_in (const profile_count overall) const
Index: testsuite/gcc.c-torture/compile/pr81290.c
===================================================================
--- testsuite/gcc.c-torture/compile/pr81290.c   (revision 0)
+++ testsuite/gcc.c-torture/compile/pr81290.c   (working copy)
@@ -0,0 +1,22 @@
+/* { dg-options "-funroll-loops" } */
+int vz;
+
+void
+ms (int sw, int cm)
+{
+  for (vz = 0; vz < 19; ++vz)
+    {
+ fx:
+      sw *= 2;
+    }
+
+  for (;;)
+    {
+      if (sw != 0)
+        for (;;)
+          {
+          }
+      if (1 / 0 && cm != 0)
+        goto fx;
+    }
+}
Index: tree-ssa-threadupdate.c
===================================================================
--- tree-ssa-threadupdate.c     (revision 249906)
+++ tree-ssa-threadupdate.c     (working copy)
@@ -908,7 +908,7 @@ recompute_probabilities (basic_block bb)
 
       /* Prevent overflow computation due to insane profiles.  */
       if (esucc->count < bb->count)
-       esucc->probability = esucc->count.probability_in (bb->count);
+       esucc->probability = esucc->count.probability_in (bb->count).guessed ();
       else
        /* Can happen with missing/guessed probabilities, since we
           may determine that more is flowing along duplicated
@@ -1051,7 +1051,8 @@ freqs_to_counts_path (struct redirection
       if (ein->probability.initialized_p ())
         ein->count = profile_count::from_gcov_type
                  (apply_probability (ein->src->frequency * REG_BR_PROB_BASE,
-                                       ein->probability.to_reg_br_prob_base 
()));
+                                       ein->probability
+                                         .to_reg_br_prob_base ())).guessed ();
       else
        /* FIXME: this is hack; we should track uninitialized values.  */
        ein->count = profile_count::zero ();

Reply via email to