diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/dojump.c | 82 |
2 files changed, 63 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4578a605c25..be3dc782309 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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). diff --git a/gcc/dojump.c b/gcc/dojump.c index 3f04eacabb7..ee12d761eee 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -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 (); |