re PR tree-optimization/83081 ([arm] gcc.dg/pr80218.c fails since r254888)
authorJakub Jelinek <jakub@redhat.com>
Mon, 22 Jan 2018 22:59:33 +0000 (23:59 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 22 Jan 2018 22:59:33 +0000 (23:59 +0100)
PR tree-optimization/83081
* profile-count.h (profile_probability::split): New method.
* dojump.c (do_jump_1) <case TRUTH_ANDIF_EXPR, case TRUTH_ORIF_EXPR>:
Use profile_probability::split.
(do_compare_rtx_and_jump): Fix adjustment of probabilities
when splitting a single conditional jump into 2.

* gcc.dg/predict-8.c: Adjust expected probability.

From-SVN: r256966

gcc/ChangeLog
gcc/dojump.c
gcc/profile-count.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/predict-8.c

index 2570832d8b45a34535a26400c3b06ee2d2f7b1a2..d8c30e719166bca8d0afee38ae6eda0861b5daf8 100644 (file)
@@ -1,3 +1,12 @@
+2018-01-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/83081
+       * profile-count.h (profile_probability::split): New method.
+       * dojump.c (do_jump_1) <case TRUTH_ANDIF_EXPR, case TRUTH_ORIF_EXPR>:
+       Use profile_probability::split.
+       (do_compare_rtx_and_jump): Fix adjustment of probabilities
+       when splitting a single conditional jump into 2.
+
 2018-01-22  David Malcolm  <dmalcolm@redhat.com>
 
        PR tree-optimization/69452
index f86f83eedc1790bf379252098e560463076a4fec..9da8a0e3091fe78836ea14af75b8035aa09115a9 100644 (file)
@@ -347,13 +347,11 @@ do_jump_1 (enum tree_code code, tree op0, tree op1,
         profile_probability op1_prob = profile_probability::uninitialized ();
         if (prob.initialized_p ())
           {
-            profile_probability false_prob = prob.invert ();
-            profile_probability op0_false_prob = false_prob.apply_scale (1, 2);
-           profile_probability op1_false_prob = false_prob.apply_scale (1, 2)
-                               / op0_false_prob.invert ();
+           op1_prob = prob.invert ();
+           op0_prob = op1_prob.split (profile_probability::even ());
             /* Get the probability that each jump below is true.  */
-            op0_prob = op0_false_prob.invert ();
-            op1_prob = op1_false_prob.invert ();
+           op0_prob = op0_prob.invert ();
+           op1_prob = op1_prob.invert ();
           }
        if (if_false_label == NULL)
           {
@@ -380,8 +378,8 @@ do_jump_1 (enum tree_code code, tree op0, tree op1,
         profile_probability op1_prob = profile_probability::uninitialized ();
         if (prob.initialized_p ())
           {
-            op0_prob = prob.apply_scale (1, 2);
-            op1_prob = prob.apply_scale (1, 2) / op0_prob.invert ();
+           op1_prob = prob;
+           op0_prob = op1_prob.split (profile_probability::even ());
          }
        if (if_true_label == NULL)
          {
@@ -1120,16 +1118,27 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
 
          else
            {
-             profile_probability first_prob = prob;
+             profile_probability cprob
+               = profile_probability::guessed_always ();
              if (first_code == UNORDERED)
-               first_prob = profile_probability::guessed_always ().apply_scale
-                                (1, 100);
+               cprob = cprob.apply_scale (1, 100);
              else if (first_code == ORDERED)
-               first_prob = profile_probability::guessed_always ().apply_scale
-                                (99, 100);
+               cprob = cprob.apply_scale (99, 100);
+             else
+               cprob = profile_probability::even ();
+             /* We want to split:
+                if (x) goto t; // prob;
+                into
+                if (a) goto t; // first_prob;
+                if (b) goto t; // prob;
+                such that the overall probability of jumping to t
+                remains the same and first_prob is prob * cprob.  */
              if (and_them)
                {
                  rtx_code_label *dest_label;
+                 prob = prob.invert ();
+                 profile_probability first_prob = prob.split (cprob).invert ();
+                 prob = prob.invert ();
                  /* If we only jump if true, just bypass the second jump.  */
                  if (! if_false_label)
                    {
@@ -1143,8 +1152,11 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
                                           size, dest_label, NULL, first_prob);
                }
               else
-                do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
-                                        size, NULL, if_true_label, first_prob);
+               {
+                 profile_probability first_prob = prob.split (cprob);
+                 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
+                                          size, NULL, if_true_label, first_prob);
+               }
            }
        }
 
index 03e6635f0da12df7eb4db92b0ac3d8134cb2499b..db274f4c5afddcd336b47b398c2c0f1c15e2b2b0 100644 (file)
@@ -410,6 +410,30 @@ public:
       return *this;
     }
 
+  /* Split *THIS (ORIG) probability into 2 probabilities, such that
+     the returned one (FIRST) is *THIS * CPROB and *THIS is
+     adjusted (SECOND) so that FIRST + FIRST.invert () * SECOND
+     == ORIG.  This is useful e.g. when splitting a conditional
+     branch like:
+     if (cond)
+       goto lab; // ORIG probability
+     into
+     if (cond1)
+       goto lab; // FIRST = ORIG * CPROB probability
+     if (cond2)
+       goto lab; // SECOND probability
+     such that the overall probability of jumping to lab remains
+     the same.  CPROB gives the relative probability between the
+     branches.  */
+  profile_probability split (const profile_probability &cprob)
+    {
+      profile_probability ret = *this * cprob;
+      /* The following is equivalent to:
+         *this = cprob.invert () * *this / ret.invert ();  */
+      *this = (*this - ret) / ret.invert ();
+      return ret;
+    }
+
   gcov_type apply (gcov_type val) const
     {
       if (*this == profile_probability::uninitialized ())
index 485079a7cb159f744730ea1b6d6d84cdc9229fdf..23cef820eeade5f2cafb2a4248b0dc7a7a2bbd26 100644 (file)
@@ -1,3 +1,8 @@
+2018-01-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/83081
+       * gcc.dg/predict-8.c: Adjust expected probability.
+
 2018-01-22  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/83862
index fa975b3d95f9711dcda74541ce4353a15d5b6d1f..5578175ec8048b835708bf56c4fa8a7ea84b54a5 100644 (file)
@@ -8,4 +8,4 @@ int foo(float a, float b) {
     return 2;
 }
 
-/* { dg-final { scan-rtl-dump-times "99.0. .guessed" 2 "expand"} } */
+/* { dg-final { scan-rtl-dump-times "65.\[34]. .guessed" 2 "expand"} } */