]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
This patch fixes an issue where expansion of an ORIF expression arbitrarily...
authorTeresa Johnson <tejohnson@google.com>
Wed, 2 Oct 2013 19:18:17 +0000 (19:18 +0000)
committerTeresa Johnson <tejohnson@gcc.gnu.org>
Wed, 2 Oct 2013 19:18:17 +0000 (19:18 +0000)
This patch fixes an issue where expansion of an ORIF expression arbitrarily
applied the probability that the entire condition was true to just the
first condition. When the ORIF true probability was 100%, this resulted
in the second condition's jump being given a count of zero (since the
first condition's jump got 100% of the count), leading to incorrect function
splitting when it had a non-zero probability in reality. Since there
currently isn't better information about which condition resulted
in the ORIF being true, apply a 50-50 probability that it is the first
vs. second condition that caused the entire expression to be true,
so that neither condition's true label ends up as a 0-count bb.

An equivalent fix is made for ANDIF expansion.

2013-10-02  Teresa Johnson  <tejohnson@google.com>

* dojump.c (do_jump_1): Divide probability between
both conditions of a TRUTH_ORIF_EXPR.

From-SVN: r203126

gcc/ChangeLog
gcc/dojump.c

index 4578a605c25fd74710433c1953701e8a4f29206b..be3dc782309b52369bfdbfeaadabe383a8caae3c 100644 (file)
@@ -1,3 +1,8 @@
+2013-10-02  Teresa Johnson  <tejohnson@google.com>
+
+       * dojump.c (do_jump_1): Divide probability between
+       both conditions of a TRUTH_ANDIF_EXPR/TRUTH_ORIF_EXPR.
+
 2013-10-02  Tom Tromey  <tromey@redhat.com>
 
        * Makefile.in (DRIVER_DEFINES): Use $(if), not $(and).
index 3f04eacabb7e9fd091eaabfdf4ce061942e8c3bc..ee12d761eee0833148f07b95d31656fee3ef6e92 100644 (file)
@@ -311,32 +311,66 @@ do_jump_1 (enum tree_code code, tree op0, tree op1,
       break;
 
     case TRUTH_ANDIF_EXPR:
-      if (if_false_label == NULL_RTX)
-        {
-         drop_through_label = gen_label_rtx ();
-         do_jump (op0, drop_through_label, NULL_RTX, prob);
-         do_jump (op1, NULL_RTX, if_true_label, prob);
-       }
-      else
-       {
-         do_jump (op0, if_false_label, NULL_RTX, prob);
-         do_jump (op1, if_false_label, if_true_label, prob);
-       }
-      break;
+      {
+        /* Spread the probability that the expression is false evenly between
+           the two conditions. So the first condition is false half the total
+           probability of being false. The second condition is false the other
+           half of the total probability of being false, so its jump has a false
+           probability of half the total, relative to the probability we
+           reached it (i.e. the first condition was true).  */
+        int op0_prob = -1;
+        int op1_prob = -1;
+        if (prob != -1)
+          {
+            int false_prob = inv (prob);
+            int op0_false_prob = false_prob / 2;
+            int op1_false_prob = GCOV_COMPUTE_SCALE ((false_prob / 2),
+                                                     inv (op0_false_prob));
+            /* Get the probability that each jump below is true.  */
+            op0_prob = inv (op0_false_prob);
+            op1_prob = inv (op1_false_prob);
+          }
+        if (if_false_label == NULL_RTX)
+          {
+            drop_through_label = gen_label_rtx ();
+            do_jump (op0, drop_through_label, NULL_RTX, op0_prob);
+            do_jump (op1, NULL_RTX, if_true_label, op1_prob);
+          }
+        else
+          {
+            do_jump (op0, if_false_label, NULL_RTX, op0_prob);
+            do_jump (op1, if_false_label, if_true_label, op1_prob);
+          }
+        break;
+      }
 
     case TRUTH_ORIF_EXPR:
-      if (if_true_label == NULL_RTX)
-       {
-          drop_through_label = gen_label_rtx ();
-         do_jump (op0, NULL_RTX, drop_through_label, prob);
-         do_jump (op1, if_false_label, NULL_RTX, prob);
-       }
-      else
-       {
-         do_jump (op0, NULL_RTX, if_true_label, prob);
-         do_jump (op1, if_false_label, if_true_label, prob);
-       }
-      break;
+      {
+        /* Spread the probability evenly between the two conditions. So
+           the first condition has half the total probability of being true.
+           The second condition has the other half of the total probability,
+           so its jump has a probability of half the total, relative to
+           the probability we reached it (i.e. the first condition was false).  */
+        int op0_prob = -1;
+        int op1_prob = -1;
+        if (prob != -1)
+          {
+            op0_prob = prob / 2;
+            op1_prob = GCOV_COMPUTE_SCALE ((prob / 2), inv (op0_prob));
+          }
+        if (if_true_label == NULL_RTX)
+          {
+            drop_through_label = gen_label_rtx ();
+            do_jump (op0, NULL_RTX, drop_through_label, op0_prob);
+            do_jump (op1, if_false_label, NULL_RTX, op1_prob);
+          }
+        else
+          {
+            do_jump (op0, NULL_RTX, if_true_label, op0_prob);
+            do_jump (op1, if_false_label, if_true_label, op1_prob);
+          }
+        break;
+      }
 
     default:
       gcc_unreachable ();