profile-count.h (profile_probability::from_reg_br_prob_note, [...]): New functions.
authorJan Hubicka <hubicka@ucw.cz>
Sun, 16 Jul 2017 16:10:58 +0000 (18:10 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 16 Jul 2017 16:10:58 +0000 (16:10 +0000)
* profile-count.h (profile_probability::from_reg_br_prob_note,
profile_probability::to_reg_br_prob_note): New functions.
* doc/rtl.texi (REG_BR_PROB_NOTE): Update documentation.
* reg-notes.h (REG_BR_PROB, REG_BR_PRED): Update docs.
* predict.c (probability_reliable_p): Update.
(edge_probability_reliable_p): Update.
(br_prob_note_reliable_p): Update.
(invert_br_probabilities): Update.
(add_reg_br_prob_note): New function.
(combine_predictions_for_insn): Update.
* asan.c (asan_clear_shadow): Update.
* cfgbuild.c (compute_outgoing_frequencies): Update.
* cfgrtl.c (force_nonfallthru_and_redirect): Update.
(update_br_prob_note): Update.
(rtl_verify_edges): Update.
(purge_dead_edges): Update.
(fixup_reorder_chain): Update.
* emit-rtl.c (try_split): Update.
* ifcvt.c (cond_exec_process_insns): Update.
(cond_exec_process_if_block): Update.
(dead_or_predicable): Update.
* internal-fn.c (expand_addsub_overflow): Update.
(expand_neg_overflow): Update.
(expand_mul_overflow): Update.
* loop-doloop.c (doloop_modify): Update.
* loop-unroll.c (compare_and_jump_seq): Update.
* optabs.c (emit_cmp_and_jump_insn_1): Update.
* predict.h: Update.
* reorg.c (mostly_true_jump): Update.
* rtl.h: Update.
* config/aarch64/aarch64.c (aarch64_emit_unlikely_jump): Update.
* config/alpha/alpha.c (emit_unlikely_jump): Update.
* config/arc/arc.c: (emit_unlikely_jump): Update.
* config/arm/arm.c: (emit_unlikely_jump): Update.
* config/bfin/bfin.c (cbranch_predicted_taken_p): Update.
* config/frv/frv.c (frv_print_operand_jump_hint): Update.
* config/i386/i386.c (ix86_expand_split_stack_prologue): Update.
(ix86_print_operand): Update.
(ix86_split_fp_branch): Update.
(predict_jump): Update.
* config/ia64/ia64.c (ia64_print_operand): Update.
* config/mmix/mmix.c (mmix_print_operand): Update.
* config/powerpcspe/powerpcspe.c (output_cbranch): Update.
(rs6000_expand_split_stack_prologue): Update.
* config/rs6000/rs6000.c: Update.
* config/s390/s390.c (s390_expand_vec_strlen): Update.
(s390_expand_vec_movstr): Update.
(s390_expand_cs_tdsi): Update.
(s390_expand_split_stack_prologue): Update.
* config/sh/sh.c (sh_print_operand): Update.
(expand_cbranchsi4): Update.
(expand_cbranchdi4): Update.
* config/sparc/sparc.c (output_v9branch): Update.
* config/spu/spu.c (get_branch_target): Update.
(ea_load_store_inline): Update.
* config/tilegx/tilegx.c (cbranch_predicted_p): Update.
* config/tilepro/tilepro.c: Update.
* gcc.dg/predict-8.c: Update.

From-SVN: r250239

38 files changed:
gcc/ChangeLog
gcc/asan.c
gcc/cfgbuild.c
gcc/cfgrtl.c
gcc/config/aarch64/aarch64.c
gcc/config/alpha/alpha.c
gcc/config/arc/arc.c
gcc/config/arm/arm.c
gcc/config/bfin/bfin.c
gcc/config/frv/frv.c
gcc/config/i386/i386.c
gcc/config/ia64/ia64.c
gcc/config/mmix/mmix.c
gcc/config/powerpcspe/powerpcspe.c
gcc/config/rs6000/rs6000.c
gcc/config/s390/s390.c
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.md
gcc/config/sparc/sparc.c
gcc/config/spu/spu.c
gcc/config/tilegx/tilegx.c
gcc/config/tilepro/tilepro.c
gcc/doc/rtl.texi
gcc/emit-rtl.c
gcc/ifcvt.c
gcc/internal-fn.c
gcc/loop-doloop.c
gcc/loop-unroll.c
gcc/optabs.c
gcc/predict.c
gcc/predict.h
gcc/profile-count.h
gcc/reg-notes.def
gcc/reorg.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/predict-8.c

index 4d04f54de103b02176c0e738dc7d80988ea52ee4..f3bafa52d37fac22578c91f4265c2dbdab86d7e1 100644 (file)
@@ -1,3 +1,63 @@
+2017-07-16  Jan Hubicka  <hubicka@ucw.cz>
+
+       * profile-count.h (profile_probability::from_reg_br_prob_note,
+       profile_probability::to_reg_br_prob_note): New functions.
+       * doc/rtl.texi (REG_BR_PROB_NOTE): Update documentation.
+       * reg-notes.h (REG_BR_PROB, REG_BR_PRED): Update docs.
+       * predict.c (probability_reliable_p): Update.
+       (edge_probability_reliable_p): Update.
+       (br_prob_note_reliable_p): Update.
+       (invert_br_probabilities): Update.
+       (add_reg_br_prob_note): New function.
+       (combine_predictions_for_insn): Update.
+       * asan.c (asan_clear_shadow): Update.
+       * cfgbuild.c (compute_outgoing_frequencies): Update.
+       * cfgrtl.c (force_nonfallthru_and_redirect): Update.
+       (update_br_prob_note): Update.
+       (rtl_verify_edges): Update.
+       (purge_dead_edges): Update.
+       (fixup_reorder_chain): Update.
+       * emit-rtl.c (try_split): Update.
+       * ifcvt.c (cond_exec_process_insns): Update.
+       (cond_exec_process_if_block): Update.
+       (dead_or_predicable): Update.
+       * internal-fn.c (expand_addsub_overflow): Update.
+       (expand_neg_overflow): Update.
+       (expand_mul_overflow): Update.
+       * loop-doloop.c (doloop_modify): Update.
+       * loop-unroll.c (compare_and_jump_seq): Update.
+       * optabs.c (emit_cmp_and_jump_insn_1): Update.
+       * predict.h: Update.
+       * reorg.c (mostly_true_jump): Update.
+       * rtl.h: Update.
+       * config/aarch64/aarch64.c (aarch64_emit_unlikely_jump): Update.
+       * config/alpha/alpha.c (emit_unlikely_jump): Update.
+       * config/arc/arc.c: (emit_unlikely_jump): Update.
+       * config/arm/arm.c: (emit_unlikely_jump): Update.
+       * config/bfin/bfin.c (cbranch_predicted_taken_p): Update.
+       * config/frv/frv.c (frv_print_operand_jump_hint): Update.
+       * config/i386/i386.c (ix86_expand_split_stack_prologue): Update.
+       (ix86_print_operand): Update.
+       (ix86_split_fp_branch): Update.
+       (predict_jump): Update.
+       * config/ia64/ia64.c (ia64_print_operand): Update.
+       * config/mmix/mmix.c (mmix_print_operand): Update.
+       * config/powerpcspe/powerpcspe.c (output_cbranch): Update.
+       (rs6000_expand_split_stack_prologue): Update.
+       * config/rs6000/rs6000.c: Update.
+       * config/s390/s390.c (s390_expand_vec_strlen): Update.
+       (s390_expand_vec_movstr): Update.
+       (s390_expand_cs_tdsi): Update.
+       (s390_expand_split_stack_prologue): Update.
+       * config/sh/sh.c (sh_print_operand): Update.
+       (expand_cbranchsi4): Update.
+       (expand_cbranchdi4): Update.
+       * config/sparc/sparc.c (output_v9branch): Update.
+       * config/spu/spu.c (get_branch_target): Update.
+       (ea_load_store_inline): Update.
+       * config/tilegx/tilegx.c (cbranch_predicted_p): Update.
+       * config/tilepro/tilepro.c: Update.
+
 2017-07-16  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gimplify.c (mostly_copy_tree_r): Revert latest change.
index 89c2731e8cdb69d45fb91b345fdf7f081ad9e79d..a56174a165641b3054fcd86cfc2dc5e3a3b81846 100644 (file)
@@ -1208,7 +1208,9 @@ asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
   emit_cmp_and_jump_insns (addr, end, LT, NULL_RTX, Pmode, true, top_label);
   jump = get_last_insn ();
   gcc_assert (JUMP_P (jump));
-  add_int_reg_note (jump, REG_BR_PROB, REG_BR_PROB_BASE * 80 / 100);
+  add_reg_br_prob_note (jump,
+                       profile_probability::guessed_always ()
+                          .apply_scale (80, 100));
 }
 
 void
index 56a2cb92860c68b601b0892a83bfb0ec5f06255b..16b07073b917e62227195bb6d28b47e4d0b2efad 100644 (file)
@@ -546,12 +546,10 @@ compute_outgoing_frequencies (basic_block b)
          probability = XINT (note, 0);
          e = BRANCH_EDGE (b);
          e->probability
-                = profile_probability::from_reg_br_prob_base (probability);
-         e->count = b->count.apply_probability (probability);
+                = profile_probability::from_reg_br_prob_note (probability);
+         e->count = b->count.apply_probability (e->probability);
          f = FALLTHRU_EDGE (b);
-         f->probability
-                = profile_probability::from_reg_br_prob_base (REG_BR_PROB_BASE
-                                                              - probability);
+         f->probability = e->probability.invert ();
          f->count = b->count - e->count;
          return;
        }
index c78cb8ee084392e88f88e622a4961631b8e30f17..8c60eede0b972ebc012bed58afc77589fc44e661 100644 (file)
@@ -1504,8 +1504,8 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
        {
          int prob = XINT (note, 0);
 
-         b->probability = profile_probability::from_reg_br_prob_base (prob);
-         b->count = e->count.apply_probability (prob);
+         b->probability = profile_probability::from_reg_br_prob_note (prob);
+         b->count = e->count.apply_probability (b->probability);
          e->probability -= e->probability;
          e->count -= b->count;
        }
@@ -2253,9 +2253,9 @@ update_br_prob_note (basic_block bb)
     return;
   note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX);
   if (!note
-      || XINT (note, 0) == BRANCH_EDGE (bb)->probability.to_reg_br_prob_base ())
+      || XINT (note, 0) == BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ())
     return;
-  XINT (note, 0) = BRANCH_EDGE (bb)->probability.to_reg_br_prob_base ();
+  XINT (note, 0) = BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ();
 }
 
 /* Get the last insn associated with block BB (that includes barriers and
@@ -2456,12 +2456,12 @@ rtl_verify_edges (void)
                }
            }
          else if (XINT (note, 0)
-                  != BRANCH_EDGE (bb)->probability.to_reg_br_prob_base ()
+                  != BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ()
                   && profile_status_for_fn (cfun) != PROFILE_ABSENT)
            {
              error ("verify_flow_info: REG_BR_PROB does not match cfg %i %i",
                     XINT (note, 0),
-                    BRANCH_EDGE (bb)->probability.to_reg_br_prob_base ());
+                    BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ());
              err = 1;
            }
        }
@@ -3164,9 +3164,9 @@ purge_dead_edges (basic_block bb)
 
          b = BRANCH_EDGE (bb);
          f = FALLTHRU_EDGE (bb);
-         b->probability = profile_probability::from_reg_br_prob_base
+         b->probability = profile_probability::from_reg_br_prob_note
                                         (XINT (note, 0));
-         f->probability = profile_probability::always () - b->probability;
+         f->probability = b->probability.invert ();
          b->count = bb->count.apply_probability (b->probability);
          f->count = bb->count.apply_probability (f->probability);
        }
@@ -3792,7 +3792,8 @@ fixup_reorder_chain (void)
                  rtx note = find_reg_note (bb_end_jump, REG_BR_PROB, 0);
 
                  if (note
-                     && XINT (note, 0) < REG_BR_PROB_BASE / 2
+                     && profile_probability::from_reg_br_prob_note
+                                (XINT (note, 0)) < profile_probability::even ()
                      && invert_jump (bb_end_jump,
                                      (e_fall->dest
                                       == EXIT_BLOCK_PTR_FOR_FN (cfun)
index 134d37ba693df9a81b4f9d96af139fdb869106fe..b8a4160d9de8e689ccd26cb9f0ce046ee65e0ef4 100644 (file)
@@ -12161,10 +12161,8 @@ aarch64_emit_store_exclusive (machine_mode mode, rtx bval,
 static void
 aarch64_emit_unlikely_jump (rtx insn)
 {
-  int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
-
   rtx_insn *jump = emit_jump_insn (insn);
-  add_int_reg_note (jump, REG_BR_PROB, very_unlikely);
+  add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
 }
 
 /* Expand a compare and swap pattern.  */
index 00a69c1a08d672122bdf38438633dbbbb4b26c70..1114e6601b6a8660a895ba16ab0c4d0e696bab84 100644 (file)
@@ -4319,10 +4319,9 @@ alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
 static void
 emit_unlikely_jump (rtx cond, rtx label)
 {
-  int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
   rtx x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
   rtx_insn *insn = emit_jump_insn (gen_rtx_SET (pc_rtx, x));
-  add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
+  add_reg_br_prob_note (insn, profile_probability::very_unlikely ());
 }
 
 /* A subroutine of the atomic operation splitters.  Emit a load-locked
index ed8fd8e756ff29410becebd8071e7bbc2119f742..a92ee4c82c053998b7571dbdbfdb81aee81d8b20 100644 (file)
@@ -9979,10 +9979,8 @@ arc_post_atomic_barrier (enum memmodel model)
 static void
 emit_unlikely_jump (rtx insn)
 {
-  int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
-
   rtx_insn *jump = emit_jump_insn (insn);
-  add_int_reg_note (jump, REG_BR_PROB, very_unlikely);
+  add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
 }
 
 /* Expand code to perform a 8 or 16-bit compare and swap by doing
index f59132c3f079d10d9e3d920b61037db2f3144eee..1b7b382139e281b0812e57c7826eb042a9aac305 100644 (file)
@@ -28271,7 +28271,7 @@ emit_unlikely_jump (rtx insn)
   int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
 
   rtx_insn *jump = emit_jump_insn (insn);
-  add_int_reg_note (jump, REG_BR_PROB, very_unlikely);
+  add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
 }
 
 /* Expand a compare and swap pattern.  */
index 2073927af7c0b653abbcded58e9ea2818a35ce70..9fe90fc37b4496f9172bed086151e6b7356f4bff 100644 (file)
@@ -2435,9 +2435,8 @@ cbranch_predicted_taken_p (rtx insn)
 
   if (x)
     {
-      int pred_val = XINT (x, 0);
-
-      return pred_val >= REG_BR_PROB_BASE / 2;
+      return profile_probability::from_reg_br_prob_note (XINT (x, 0))
+            >= profile_probability::even ();
     }
 
   return 0;
index 0918b9835b94852408f873a9c14fffa4a120b026..c571d63f2c667807635b4714f9c92b49bceb3953 100644 (file)
@@ -2621,7 +2621,6 @@ frv_print_operand_jump_hint (rtx_insn *insn)
   rtx note;
   rtx labelref;
   int ret;
-  int prob = -1;
   enum { UNKNOWN, BACKWARD, FORWARD } jump_type = UNKNOWN;
 
   gcc_assert (JUMP_P (insn));
@@ -2647,8 +2646,8 @@ frv_print_operand_jump_hint (rtx_insn *insn)
 
       else
        {
-         prob = XINT (note, 0);
-         ret = ((prob >= (REG_BR_PROB_BASE / 2))
+         ret = ((profile_probability::from_reg_br_prob_note (XINT (note, 0))
+                 >= profile_probability::even ())
                 ? FRV_JUMP_LIKELY
                 : FRV_JUMP_NOT_LIKELY);
        }
index 42e0ddaca56e5896722620653c302a85e6fb795d..eac76815287a9f2cde1e384c1c7a4f2b577b7ef6 100644 (file)
@@ -15783,8 +15783,7 @@ ix86_expand_split_stack_prologue (void)
   JUMP_LABEL (jump_insn) = label;
 
   /* Mark the jump as very likely to be taken.  */
-  add_int_reg_note (jump_insn, REG_BR_PROB,
-                   REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100);
+  add_reg_br_prob_note (jump_insn, profile_probability::very_likely ());
 
   if (split_stack_fn == NULL_RTX)
     {
@@ -19128,7 +19127,8 @@ ix86_print_operand (FILE *file, rtx x, int code)
            x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
            if (x)
              {
-               int pred_val = XINT (x, 0);
+               int pred_val = profile_probability::from_reg_br_prob_note
+                                (XINT (x, 0)).to_reg_br_prob_base ();
 
                if (pred_val < REG_BR_PROB_BASE * 45 / 100
                    || pred_val > REG_BR_PROB_BASE * 55 / 100)
@@ -23865,8 +23865,8 @@ ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
                      (pc_rtx,
                       gen_rtx_IF_THEN_ELSE (VOIDmode,
                                             condition, target1, target2)));
-  if (split_branch_probability >= 0)
-    add_int_reg_note (i, REG_BR_PROB, split_branch_probability);
+  if (split_branch_probability.initialized_p ())
+    add_reg_br_prob_note (i, split_branch_probability);
 }
 
 void
@@ -26911,7 +26911,7 @@ predict_jump (int prob)
 {
   rtx_insn *insn = get_last_insn ();
   gcc_assert (JUMP_P (insn));
-  add_int_reg_note (insn, REG_BR_PROB, prob);
+  add_reg_br_prob_note (insn, profile_probability::from_reg_br_prob_base (prob));
 }
 
 /* Helper function for the string operations below.  Dest VARIABLE whether
index 617d188d4f2ec22c8a9f97f5161b5a68f118d8cb..c8e4c74bbdbe5cff7c2c0863a85b12a2290a2ca9 100644 (file)
@@ -5502,7 +5502,8 @@ ia64_print_operand (FILE * file, rtx x, int code)
        x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
        if (x)
          {
-           int pred_val = XINT (x, 0);
+           int pred_val = profile_probability::from_reg_br_prob_note
+                                (XINT (x, 0)).to_reg_br_prob_base ();
 
            /* Guess top and bottom 10% statically predicted.  */
            if (pred_val < REG_BR_PROB_BASE / 50
index 32786881959d6e2aba13cfdc13cb703a7cd673d7..9849c19e0766b26e541093e766240d7ee5bec090 100644 (file)
@@ -1536,7 +1536,8 @@ mmix_print_operand (FILE *stream, rtx x, int code)
       if (TARGET_BRANCH_PREDICT)
        {
          x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
-         if (x && XINT (x, 0) > REG_BR_PROB_BASE / 2)
+         if (x && profile_probability::from_reg_br_prob_note (XINT (x, 0))
+             > profile_probability::even ())
            putc ('P', stream);
        }
       return;
index 06d66d7e4cd610812f1c9c43252d96397ea2c766..b94afd5ca2e5e46a3565d4fe1bd20d80eb8b26e8 100644 (file)
@@ -25333,7 +25333,8 @@ output_cbranch (rtx op, const char *label, int reversed, rtx_insn *insn)
   if (note != NULL_RTX)
     {
       /* PROB is the difference from 50%.  */
-      int prob = XINT (note, 0) - REG_BR_PROB_BASE / 2;
+      int prob = profile_probability::from_reg_br_prob_note (XINT (note, 0))
+                  .to_reg_br_prob_base () - REG_BR_PROB_BASE / 2;
 
       /* Only hint for highly probable/improbable branches on newer cpus when
         we have real profile data, as static prediction overrides processor
@@ -26123,10 +26124,9 @@ rs6000_split_signbit (rtx dest, rtx src)
 static void
 emit_unlikely_jump (rtx cond, rtx label)
 {
-  int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
   rtx x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
   rtx_insn *insn = emit_jump_insn (gen_rtx_SET (pc_rtx, x));
-  add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
+  add_reg_br_prob_note (insn, profile_probability::very_unlikely ());
 }
 
 /* A subroutine of the atomic operation splitters.  Emit a load-locked
@@ -32192,8 +32192,7 @@ rs6000_expand_split_stack_prologue (void)
   insn = emit_jump_insn (gen_rtx_SET (pc_rtx, jump));
   JUMP_LABEL (insn) = ok_label;
   /* Mark the jump as very likely to be taken.  */
-  add_int_reg_note (insn, REG_BR_PROB,
-                   REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100);
+  add_reg_br_prob_note (insn, profile_probability::very_likely ());
 
   lr = gen_rtx_REG (Pmode, LR_REGNO);
   insn = emit_move_insn (r0, lr);
index 9bf6f370c4e9843f6426373d1ffffe566b9256d6..e49a09125dfc1a8a21c8d7141cc509b962dafb99 100644 (file)
@@ -22759,7 +22759,8 @@ output_cbranch (rtx op, const char *label, int reversed, rtx_insn *insn)
   if (note != NULL_RTX)
     {
       /* PROB is the difference from 50%.  */
-      int prob = XINT (note, 0) - REG_BR_PROB_BASE / 2;
+      int prob = profile_probability::from_reg_br_prob_note (XINT (note, 0))
+                  .to_reg_br_prob_base () - REG_BR_PROB_BASE / 2;
 
       /* Only hint for highly probable/improbable branches on newer cpus when
         we have real profile data, as static prediction overrides processor
@@ -23528,10 +23529,9 @@ rs6000_split_signbit (rtx dest, rtx src)
 static void
 emit_unlikely_jump (rtx cond, rtx label)
 {
-  int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
   rtx x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
   rtx_insn *insn = emit_jump_insn (gen_rtx_SET (pc_rtx, x));
-  add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
+  add_reg_br_prob_note (insn, profile_probability::very_unlikely ());
 }
 
 /* A subroutine of the atomic operation splitters.  Emit a load-locked
@@ -29284,8 +29284,7 @@ rs6000_expand_split_stack_prologue (void)
   insn = emit_jump_insn (gen_rtx_SET (pc_rtx, jump));
   JUMP_LABEL (insn) = ok_label;
   /* Mark the jump as very likely to be taken.  */
-  add_int_reg_note (insn, REG_BR_PROB,
-                   REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100);
+  add_reg_br_prob_note (insn, profile_probability::very_likely ());
 
   lr = gen_rtx_REG (Pmode, LR_REGNO);
   insn = emit_move_insn (r0, lr);
index 31ced21a043fb272598ade5559fe0017414479f4..bbae89be29d51b21645ed317bccccc8bb7b07add 100644 (file)
@@ -5720,8 +5720,6 @@ s390_emit_ccraw_jump (HOST_WIDE_INT mask, enum rtx_code comparison, rtx label)
 void
 s390_expand_vec_strlen (rtx target, rtx string, rtx alignment)
 {
-  int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
-  int very_likely = REG_BR_PROB_BASE - 1;
   rtx highest_index_to_load_reg = gen_reg_rtx (Pmode);
   rtx str_reg = gen_reg_rtx (V16QImode);
   rtx str_addr_base_reg = gen_reg_rtx (Pmode);
@@ -5792,7 +5790,8 @@ s390_expand_vec_strlen (rtx target, rtx string, rtx alignment)
                                  GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
 
   add_int_reg_note (s390_emit_ccraw_jump (8, NE, loop_start_label),
-                   REG_BR_PROB, very_likely);
+                   REG_BR_PROB,
+                   profile_probability::very_likely ().to_reg_br_prob_note ());
   emit_insn (gen_vec_extractv16qi (len, result_reg, GEN_INT (7)));
 
   /* If the string pointer wasn't aligned we have loaded less then 16
@@ -5812,8 +5811,8 @@ s390_expand_vec_strlen (rtx target, rtx string, rtx alignment)
     emit_insn (gen_movsicc (str_idx_reg, cond,
                            highest_index_to_load_reg, str_idx_reg));
 
-  add_int_reg_note (s390_emit_jump (is_aligned_label, cond), REG_BR_PROB,
-                   very_unlikely);
+  add_reg_br_prob_note (s390_emit_jump (is_aligned_label, cond),
+                       profile_probability::very_unlikely ());
 
   expand_binop (Pmode, add_optab, str_idx_reg,
                GEN_INT (-16), str_idx_reg, 1, OPTAB_DIRECT);
@@ -5829,7 +5828,6 @@ s390_expand_vec_strlen (rtx target, rtx string, rtx alignment)
 void
 s390_expand_vec_movstr (rtx result, rtx dst, rtx src)
 {
-  int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
   rtx temp = gen_reg_rtx (Pmode);
   rtx src_addr = XEXP (src, 0);
   rtx dst_addr = XEXP (dst, 0);
@@ -5906,7 +5904,8 @@ s390_expand_vec_movstr (rtx result, rtx dst, rtx src)
   emit_insn (gen_vec_vfenesv16qi (vpos, vsrc, vsrc,
                                  GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
   add_int_reg_note (s390_emit_ccraw_jump (8, EQ, done_label),
-                   REG_BR_PROB, very_unlikely);
+                   REG_BR_PROB, profile_probability::very_unlikely ()
+                                 .to_reg_br_prob_note ());
 
   emit_move_insn (gen_rtx_MEM (V16QImode,
                               gen_rtx_PLUS (Pmode, dst_addr_reg, offset)),
@@ -6929,7 +6928,6 @@ s390_expand_cs_tdsi (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
 
   if (do_const_opt)
     {
-      const int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
       rtx cc = gen_rtx_REG (CCZmode, CC_REGNUM);
 
       skip_cs_label = gen_label_rtx ();
@@ -6950,7 +6948,8 @@ s390_expand_cs_tdsi (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
          emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (CCZmode, output, cmp)));
        }
       s390_emit_jump (skip_cs_label, gen_rtx_NE (VOIDmode, cc, const0_rtx));
-      add_int_reg_note (get_last_insn (), REG_BR_PROB, very_unlikely);
+      add_reg_br_prob_note (get_last_insn (), 
+                           profile_probability::very_unlikely ());
       /* If the jump is not taken, OUTPUT is the expected value.  */
       cmp = output;
       /* Reload newval to a register manually, *after* the compare and jump
@@ -11678,7 +11677,8 @@ s390_expand_split_stack_prologue (void)
       LABEL_NUSES (call_done)++;
 
       /* Mark the jump as very unlikely to be taken.  */
-      add_int_reg_note (insn, REG_BR_PROB, REG_BR_PROB_BASE / 100);
+      add_reg_br_prob_note (insn, 
+                           profile_probability::very_unlikely ());
 
       if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
        {
index 59be4c0cf3037b350e5ebb60e137873844ccc0c0..305ab2cd19bc695741fadfcfc235f6d0f7f6543c 100644 (file)
@@ -68,7 +68,7 @@ extern bool sh_expand_strlen  (rtx *);
 extern void sh_expand_setmem (rtx *);
 extern enum rtx_code prepare_cbranch_operands (rtx *, machine_mode mode,
                                               enum rtx_code comparison);
-extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int);
+extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison);
 extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison);
 extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx);
 extern void sh_emit_compare_and_branch (rtx *, machine_mode);
index ff79b93adc263e02114c815ff3706ad57d5cad60..6f01dcb700c727887610de78134fc185b94c598a 100644 (file)
@@ -1139,7 +1139,9 @@ sh_print_operand (FILE *stream, rtx x, int code)
       {
        rtx note = find_reg_note (current_output_insn, REG_BR_PROB, 0);
 
-       if (note && XINT (note, 0) * 2 < REG_BR_PROB_BASE)
+       if (note
+           && profile_probability::from_reg_br_prob_note (XINT (note, 0))
+              < profile_probability::even ())
          fputs ("/u", stream);
        break;
       }
@@ -1999,8 +2001,9 @@ prepare_cbranch_operands (rtx *operands, machine_mode mode,
   return comparison;
 }
 
-void
-expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int probability)
+static void
+expand_cbranchsi4 (rtx *operands, enum rtx_code comparison,
+                  profile_probability probability)
 {
   rtx (*branch_expander) (rtx) = gen_branch_true;
   comparison = prepare_cbranch_operands (operands, SImode, comparison);
@@ -2015,8 +2018,15 @@ expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int probability)
                          gen_rtx_fmt_ee (comparison, SImode,
                                          operands[1], operands[2])));
   rtx_insn *jump = emit_jump_insn (branch_expander (operands[3]));
-  if (probability >= 0)
-    add_int_reg_note (jump, REG_BR_PROB, probability);
+  if (probability.initialized_p ())
+    add_reg_br_prob_note (jump, probability);
+}
+
+void
+expand_cbranchsi4 (rtx *operands, enum rtx_code comparison)
+{
+  expand_cbranchsi4 (operands, comparison,
+                    profile_probability::uninitialized ());
 }
 
 /* ??? How should we distribute probabilities when more than one branch
@@ -2043,8 +2053,10 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
   rtx_code_label *skip_label = NULL;
   rtx op1h, op1l, op2h, op2l;
   int num_branches;
-  int prob, rev_prob;
-  int msw_taken_prob = -1, msw_skip_prob = -1, lsw_taken_prob = -1;
+  profile_probability prob, rev_prob;
+  profile_probability msw_taken_prob = profile_probability::uninitialized (),
+                     msw_skip_prob = profile_probability::uninitialized (),
+                     lsw_taken_prob = profile_probability::uninitialized ();
 
   comparison = prepare_cbranch_operands (operands, DImode, comparison);
   op1h = gen_highpart_mode (SImode, DImode, operands[1]);
@@ -2053,34 +2065,28 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
   op2l = gen_lowpart (SImode, operands[2]);
   msw_taken = msw_skip = lsw_taken = LAST_AND_UNUSED_RTX_CODE;
   prob = split_branch_probability;
-  rev_prob = REG_BR_PROB_BASE - prob;
+  rev_prob = prob.invert ();
   switch (comparison)
     {
     case EQ:
       msw_skip = NE;
       lsw_taken = EQ;
-      if (prob >= 0)
+      if (prob.initialized_p ())
        {
-         // If we had more precision, we'd use rev_prob - (rev_prob >> 32) .
+         /* FIXME: This is not optimal.  We do not really know the probablity
+            that values differ by MCW only, but we should probably distribute
+            probabilities more evenly.  */
          msw_skip_prob = rev_prob;
-         if (REG_BR_PROB_BASE <= 65535)
-           lsw_taken_prob = prob ? REG_BR_PROB_BASE : 0;
-         else
-           {
-             lsw_taken_prob
-               = (prob
-                  ? (REG_BR_PROB_BASE
-                     - ((gcov_type) REG_BR_PROB_BASE * rev_prob
-                        / ((gcov_type) prob << 32)))
-                  : 0);
-           }
+         lsw_taken_prob = prob > profile_probability::never ()
+                          ? profile_probability::guessed_always ()
+                          : profile_probability::guessed_never ();
        }
       break;
     case NE:
       msw_taken = NE;
       msw_taken_prob = prob;
       lsw_taken = NE;
-      lsw_taken_prob = 0;
+      lsw_taken_prob = profile_probability::guessed_never ();
       break;
     case GTU: case GT:
       msw_taken = comparison;
@@ -2133,18 +2139,20 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
   if (comparison != EQ && comparison != NE && num_branches > 1)
     {
       if (!CONSTANT_P (operands[2])
-         && prob >= (int) (REG_BR_PROB_BASE * 3 / 8U)
-         && prob <= (int) (REG_BR_PROB_BASE * 5 / 8U))
-       {
-         msw_taken_prob = prob / 2U;
-         msw_skip_prob
-           = REG_BR_PROB_BASE * rev_prob / (REG_BR_PROB_BASE + rev_prob);
+         && prob.initialized_p ()
+         && prob.to_reg_br_prob_base () >= (int) (REG_BR_PROB_BASE * 3 / 8U)
+         && prob.to_reg_br_prob_base () <= (int) (REG_BR_PROB_BASE * 5 / 8U))
+       {
+         msw_taken_prob = prob.apply_scale (1, 2);
+         msw_skip_prob = rev_prob.apply_scale (REG_BR_PROB_BASE,
+                                               rev_prob.to_reg_br_prob_base ()
+                                               + REG_BR_PROB_BASE);
          lsw_taken_prob = prob;
        }
       else
        {
          msw_taken_prob = prob;
-         msw_skip_prob = REG_BR_PROB_BASE;
+         msw_skip_prob = profile_probability::guessed_always ();
          /* ??? If we have a constant op2h, should we use that when
             calculating lsw_taken_prob?  */
          lsw_taken_prob = prob;
index e19e977087db4d5231f2276af53a42ee82bd50de..733c777ef56a86d47e7651155640ad0b0430fe0a 100644 (file)
    (clobber (reg:SI T_REG))]
   "can_create_pseudo_p ()"
 {
-  expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
+  expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE);
   DONE;
 })
 
index dae241111874becbcfe196a566e5383a8400ed58..f4f318a81a1233808381908edd19594315c8a6c1 100644 (file)
@@ -7999,7 +7999,8 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
       if (*labelno && insn && (note = find_reg_note (insn, REG_BR_PROB, NULL_RTX)))
        {
          strcpy (p,
-                 ((XINT (note, 0) >= REG_BR_PROB_BASE / 2) ^ far)
+                 ((profile_probability::from_reg_br_prob_note (XINT (note, 0))
+                  >= profile_probability::even ()) ^ far)
                  ? ",pt" : ",pn");
          p += 3;
          spaces -= 3;
@@ -8462,7 +8463,8 @@ output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
   if (insn && (note = find_reg_note (insn, REG_BR_PROB, NULL_RTX)))
     {
       strcpy (p,
-             ((XINT (note, 0) >= REG_BR_PROB_BASE / 2) ^ far)
+             ((profile_probability::from_reg_br_prob_note (XINT (note, 0))
+              >= profile_probability::even ()) ^ far)
              ? ",pt" : ",pn");
       p += 3;
     }
index fcb85c0ee16c50c8b2e2fecc1234300ebfe8213d..efee614b103974b615226d59bd8567f0433289ca 100644 (file)
@@ -2195,7 +2195,8 @@ get_branch_target (rtx_insn *branch)
            {
              /* If the more probable case is not a fall through, then
                 try a branch hint.  */
-             int prob = XINT (note, 0);
+             int prob = profile_probability::from_reg_br_prob_note
+                           (XINT (note, 0)).to_reg_br_prob_base ();
              if (prob > (REG_BR_PROB_BASE * 6 / 10)
                  && GET_CODE (XEXP (src, 1)) != PC)
                lab = XEXP (src, 1);
@@ -4335,8 +4336,7 @@ ea_load_store_inline (rtx mem, bool is_store, rtx ea_addr, rtx data_addr)
                                      gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
                                                            hit_ref, pc_rtx)));
   /* Say that this branch is very likely to happen.  */
-  v = REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100 - 1;
-  add_int_reg_note (insn, REG_BR_PROB, v);
+  add_reg_br_prob_note (insn, profile_probability::very_likely ());
 
   ea_load_store (mem, is_store, ea_addr, data_addr);
   cont_label = gen_label_rtx ();
index e070e7ee52000e90f5b0d64de3eeb91f345159ab..dafb49daf1fd7fd92dd163b45e7a1bdca915b6b4 100644 (file)
@@ -2619,9 +2619,8 @@ cbranch_predicted_p (rtx_insn *insn)
 
   if (x)
     {
-      int pred_val = XINT (x, 0);
-
-      return pred_val >= REG_BR_PROB_BASE / 2;
+      return profile_probability::from_reg_br_prob_note (XINT (x, 0))
+            >= profile_probability::even ();
     }
 
   return false;
index 81019c13a4cbd3a4abb46d52af75ba27fcf4f825..80475b959eee5de1970d17c100030de674c36a3c 100644 (file)
@@ -2419,9 +2419,8 @@ cbranch_predicted_p (rtx_insn *insn)
 
   if (x)
     {
-      int pred_val = XINT (x, 0);
-
-      return pred_val >= REG_BR_PROB_BASE / 2;
+      return profile_probability::from_reg_br_prob_note (XINT (x, 0))
+            >= profile_probability::even ();
     }
 
   return false;
index b02e5a16bfe712170da40d52f102e1ea9635201d..6e2799a1ce95d96d34ce9741e1ef34969ee4b3ea 100644 (file)
@@ -4022,9 +4022,10 @@ are stored in the @code{REG_NOTES} field of an insn.
 @item REG_BR_PROB
 This is used to specify the ratio of branches to non-branches of a
 branch insn according to the profile data.  The note is represented
-as an @code{int_list} expression whose integer value is between 0 and
-REG_BR_PROB_BASE.  Larger values indicate a higher probability that
-the branch will be taken.
+as an @code{int_list} expression whose integer value is an encoding
+of @code{profile_probability} type.  @code{profile_probability} provide
+member function @code{from_reg_br_prob_note} and @code{to_reg_br_prob_note}
+to extract and store the probability into the RTL encoding.
 
 @findex REG_BR_PRED
 @item REG_BR_PRED
index 041f2a717607fb273b87c0570367f3a9bd40e7ad..2bc5d5669330de0d99be2b83f577f94334e22791 100644 (file)
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtl-iter.h"
 #include "stor-layout.h"
 #include "opts.h"
+#include "predict.h"
 
 struct target_rtl default_target_rtl;
 #if SWITCHABLE_TARGET
@@ -190,9 +191,8 @@ static reg_attrs *get_reg_attrs (tree, int);
 static rtx gen_const_vector (machine_mode, int);
 static void copy_rtx_if_shared_1 (rtx *orig);
 
-/* Probability of the conditional branch currently proceeded by try_split.
-   Set to -1 otherwise.  */
-int split_branch_probability = -1;
+/* Probability of the conditional branch currently proceeded by try_split.  */
+profile_probability split_branch_probability;
 \f
 /* Returns a hash code for X (which is a really a CONST_INT).  */
 
@@ -3662,7 +3662,7 @@ try_split (rtx pat, rtx_insn *trial, int last)
   rtx_insn *before, *after;
   rtx note;
   rtx_insn *seq, *tem;
-  int probability;
+  profile_probability probability;
   rtx_insn *insn_last, *insn;
   int njumps = 0;
   rtx_insn *call_insn = NULL;
@@ -3673,12 +3673,16 @@ try_split (rtx pat, rtx_insn *trial, int last)
 
   if (any_condjump_p (trial)
       && (note = find_reg_note (trial, REG_BR_PROB, 0)))
-    split_branch_probability = XINT (note, 0);
+    split_branch_probability
+      = profile_probability::from_reg_br_prob_note (XINT (note, 0));
+  else
+    split_branch_probability = profile_probability::uninitialized ();
+
   probability = split_branch_probability;
 
   seq = split_insns (pat, trial);
 
-  split_branch_probability = -1;
+  split_branch_probability = profile_probability::uninitialized ();
 
   if (!seq)
     return trial;
@@ -3709,7 +3713,7 @@ try_split (rtx pat, rtx_insn *trial, int last)
            CROSSING_JUMP_P (insn) = CROSSING_JUMP_P (trial);
          mark_jump_label (PATTERN (insn), insn, 0);
          njumps++;
-         if (probability != -1
+         if (probability.initialized_p ()
              && any_condjump_p (insn)
              && !find_reg_note (insn, REG_BR_PROB, 0))
            {
@@ -3718,7 +3722,7 @@ try_split (rtx pat, rtx_insn *trial, int last)
                 is responsible for this step using
                 split_branch_probability variable.  */
              gcc_assert (njumps == 1);
-             add_int_reg_note (insn, REG_BR_PROB, probability);
+             add_reg_br_prob_note (insn, probability);
            }
        }
     }
index fd682a4cf5aae64defa9667f0316caa332c8d563..46a13c41c09d930783b0c27938318397179a9e45 100644 (file)
@@ -84,8 +84,6 @@ static rtx_insn *last_active_insn (basic_block, int);
 static rtx_insn *find_active_insn_before (basic_block, rtx_insn *);
 static rtx_insn *find_active_insn_after (basic_block, rtx_insn *);
 static basic_block block_fallthru (basic_block);
-static int cond_exec_process_insns (ce_if_block *, rtx_insn *, rtx, rtx, int,
-                                   int);
 static rtx cond_exec_get_condition (rtx_insn *);
 static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool);
 static int noce_operand_ok (const_rtx);
@@ -335,7 +333,8 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
                         /* if block information */rtx_insn *start,
                         /* first insn to look at */rtx end,
                         /* last insn to look at */rtx test,
-                        /* conditional execution test */int prob_val,
+                        /* conditional execution test */profile_probability
+                                                           prob_val,
                         /* probability of branch taken. */int mod_ok)
 {
   int must_be_last = FALSE;
@@ -410,10 +409,11 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
 
       validate_change (insn, &PATTERN (insn), pattern, 1);
 
-      if (CALL_P (insn) && prob_val >= 0)
+      if (CALL_P (insn) && prob_val.initialized_p ())
        validate_change (insn, &REG_NOTES (insn),
                         gen_rtx_INT_LIST ((machine_mode) REG_BR_PROB,
-                                          prob_val, REG_NOTES (insn)), 1);
+                                          prob_val.to_reg_br_prob_note (),
+                                          REG_NOTES (insn)), 1);
 
     insn_done:
       if (insn == end)
@@ -472,8 +472,8 @@ cond_exec_process_if_block (ce_if_block * ce_info,
   int then_mod_ok;             /* whether conditional mods are ok in THEN */
   rtx true_expr;               /* test for else block insns */
   rtx false_expr;              /* test for then block insns */
-  int true_prob_val;           /* probability of else block */
-  int false_prob_val;          /* probability of then block */
+  profile_probability true_prob_val;/* probability of else block */
+  profile_probability false_prob_val;/* probability of then block */
   rtx_insn *then_last_head = NULL;     /* Last match at the head of THEN */
   rtx_insn *else_last_head = NULL;     /* Last match at the head of ELSE */
   rtx_insn *then_first_tail = NULL;    /* First match at the tail of THEN */
@@ -618,13 +618,13 @@ cond_exec_process_if_block (ce_if_block * ce_info,
   note = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
   if (note)
     {
-      true_prob_val = XINT (note, 0);
-      false_prob_val = REG_BR_PROB_BASE - true_prob_val;
+      true_prob_val = profile_probability::from_reg_br_prob_note (XINT (note, 0));
+      false_prob_val = true_prob_val.invert ();
     }
   else
     {
-      true_prob_val = -1;
-      false_prob_val = -1;
+      true_prob_val = profile_probability::uninitialized ();
+      false_prob_val = profile_probability::uninitialized ();
     }
 
   /* If we have && or || tests, do them here.  These tests are in the adjacent
@@ -5121,7 +5121,9 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
        return FALSE;
 
       rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
-      int prob_val = (note ? XINT (note, 0) : -1);
+      profile_probability prob_val
+         = (note ? profile_probability::from_reg_br_prob_note (XINT (note, 0))
+            : profile_probability::uninitialized ());
 
       if (reversep)
        {
@@ -5130,8 +5132,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
            return FALSE;
          cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
                                 XEXP (cond, 1));
-         if (prob_val >= 0)
-           prob_val = REG_BR_PROB_BASE - prob_val;
+         prob_val = prob_val.invert ();
        }
 
       if (cond_exec_process_insns (NULL, head, end, cond, prob_val, 0)
index 1dc754124843f044ee22a5e8a829d5a30fb520d4..1c9d1ea2c84c2278bacc27393cf44be1d1e573cc 100644 (file)
@@ -741,7 +741,8 @@ expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
                  && JUMP_P (last)
                  && any_condjump_p (last)
                  && !find_reg_note (last, REG_BR_PROB, 0))
-               add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
+               add_reg_br_prob_note (last,
+                                     profile_probability::very_unlikely ());
              emit_jump (done_label);
              goto do_error_label;
            }
@@ -961,7 +962,8 @@ expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
                && JUMP_P (last)
                && any_condjump_p (last)
                && !find_reg_note (last, REG_BR_PROB, 0))
-             add_int_reg_note (last, REG_BR_PROB, PROB_UNLIKELY);
+             add_reg_br_prob_note (last, 
+                                   profile_probability::very_unlikely ());
            emit_jump (done_label);
            goto do_error_label;
          }
@@ -1110,7 +1112,8 @@ expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
              && JUMP_P (last)
              && any_condjump_p (last)
              && !find_reg_note (last, REG_BR_PROB, 0))
-           add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
+           add_reg_br_prob_note (last, 
+                                 profile_probability::very_unlikely ());
          emit_jump (done_label);
         }
       else
@@ -1431,7 +1434,8 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
              && JUMP_P (last)
              && any_condjump_p (last)
              && !find_reg_note (last, REG_BR_PROB, 0))
-           add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
+           add_reg_br_prob_note (last, 
+                                 profile_probability::very_unlikely ());
          emit_jump (done_label);
         }
       else
index b4995b389bb4009dfaf060391d1f9722e4334d8d..49861b8e3625a36cc318778fe23cff2598d58ce6 100644 (file)
@@ -419,7 +419,6 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
   bool increment_count;
   basic_block loop_end = desc->out_edge->src;
   machine_mode mode;
-  rtx true_prob_val;
   widest_int iterations;
 
   jump_insn = BB_END (loop_end);
@@ -434,10 +433,6 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
       fputs (" iterations).\n", dump_file);
     }
 
-  /* Get the probability of the original branch. If it exists we would
-     need to update REG_BR_PROB of the new jump_insn.  */
-  true_prob_val = find_reg_note (jump_insn, REG_BR_PROB, NULL_RTX);
-
   /* Discard original jump to continue loop.  The original compare
      result may still be live, so it cannot be discarded explicitly.  */
   delete_insn (jump_insn);
@@ -580,12 +575,8 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
     add_reg_note (jump_insn, REG_NONNEG, NULL_RTX);
 
   /* Update the REG_BR_PROB note.  */
-  if (true_prob_val && desc->in_edge->probability.initialized_p ())
-    {
-      /* Seems safer to use the branch probability.  */
-      add_int_reg_note (jump_insn, REG_BR_PROB,
-                       desc->in_edge->probability.to_reg_br_prob_base ());
-    }
+  if (desc->in_edge->probability.initialized_p ())
+    add_reg_br_prob_note (jump_insn, desc->in_edge->probability);
 }
 
 /* Called through note_stores.  */
index 5e2e77a232729188a9e6a62e033eeec5951ef82e..84145bb4a4f0b31e10c311c2d71f68e3f80f45f6 100644 (file)
@@ -816,7 +816,7 @@ compare_and_jump_seq (rtx op0, rtx op1, enum rtx_code comp,
       LABEL_NUSES (label)++;
     }
   if (prob.initialized_p ())
-    add_int_reg_note (jump, REG_BR_PROB, prob.to_reg_br_prob_base ());
+    add_reg_br_prob_note (jump, prob);
 
   seq = get_insns ();
   end_sequence ();
index 8fd5d911ede0367d5521eb1db480d92d2058bd6f..39051326c7a13e0e31a21e581ac2e74571a39077 100644 (file)
@@ -4003,7 +4003,7 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
       && JUMP_P (insn)
       && any_condjump_p (insn)
       && !find_reg_note (insn, REG_BR_PROB, 0))
-    add_int_reg_note (insn, REG_BR_PROB, prob.to_reg_br_prob_base ());
+    add_reg_br_prob_note (insn, prob);
 }
 
 /* Generate code to compare X with Y so that the condition codes are
index 2a7dbfa4d9bda2f160322eb5654171cb0febf3ba..310d9b0acedd88a522e4a01ac7bfbcef74d031e9 100644 (file)
@@ -513,35 +513,11 @@ edge_predicted_by_p (edge e, enum br_predictor predictor, bool taken)
   return false;
 }
 
-/* Return true when the probability of edge is reliable.
-
-   The profile guessing code is good at predicting branch outcome (ie.
-   taken/not taken), that is predicted right slightly over 75% of time.
-   It is however notoriously poor on predicting the probability itself.
-   In general the profile appear a lot flatter (with probabilities closer
-   to 50%) than the reality so it is bad idea to use it to drive optimization
-   such as those disabling dynamic branch prediction for well predictable
-   branches.
-
-   There are two exceptions - edges leading to noreturn edges and edges
-   predicted by number of iterations heuristics are predicted well.  This macro
-   should be able to distinguish those, but at the moment it simply check for
-   noreturn heuristic that is only one giving probability over 99% or bellow
-   1%.  In future we might want to propagate reliability information across the
-   CFG if we find this information useful on multiple places.   */
-static bool
-probability_reliable_p (int prob)
-{
-  return (profile_status_for_fn (cfun) == PROFILE_READ
-         || (profile_status_for_fn (cfun) == PROFILE_GUESSED
-             && (prob <= HITRATE (1) || prob >= HITRATE (99))));
-}
-
 /* Same predicate as above, working on edges.  */
 bool
 edge_probability_reliable_p (const_edge e)
 {
-  return e->probability.reliable_p ();
+  return e->probability.probably_reliable_p ();
 }
 
 /* Same predicate as edge_probability_reliable_p, working on notes.  */
@@ -549,7 +525,8 @@ bool
 br_prob_note_reliable_p (const_rtx note)
 {
   gcc_assert (REG_NOTE_KIND (note) == REG_BR_PROB);
-  return probability_reliable_p (XINT (note, 0));
+  return profile_probability::from_reg_br_prob_note
+                (XINT (note, 0)).probably_reliable_p ();
 }
 
 static void
@@ -723,7 +700,8 @@ invert_br_probabilities (rtx insn)
 
   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
     if (REG_NOTE_KIND (note) == REG_BR_PROB)
-      XINT (note, 0) = REG_BR_PROB_BASE - XINT (note, 0);
+      XINT (note, 0) = profile_probability::from_reg_br_prob_note
+                        (XINT (note, 0)).invert ().to_reg_br_prob_note ();
     else if (REG_NOTE_KIND (note) == REG_BR_PRED)
       XEXP (XEXP (note, 0), 1)
        = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (XEXP (note, 0), 1)));
@@ -870,6 +848,15 @@ set_even_probabilities (basic_block bb,
       e->probability = profile_probability::never ();
 }
 
+/* Add REG_BR_PROB note to JUMP with PROB.  */
+
+void
+add_reg_br_prob_note (rtx_insn *jump, profile_probability prob)
+{
+  gcc_checking_assert (JUMP_P (jump) && !find_reg_note (jump, REG_BR_PROB, 0));
+  add_int_reg_note (jump, REG_BR_PROB, prob.to_reg_br_prob_note ());
+}
+
 /* Combine all REG_BR_PRED notes into single probability and attach REG_BR_PROB
    note if not already present.  Remove now useless REG_BR_PRED notes.  */
 
@@ -968,26 +955,26 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
 
   if (!prob_note)
     {
-      add_int_reg_note (insn, REG_BR_PROB, combined_probability);
+      profile_probability p
+        = profile_probability::from_reg_br_prob_base (combined_probability);
+      add_reg_br_prob_note (insn, p);
 
       /* Save the prediction into CFG in case we are seeing non-degenerated
         conditional jump.  */
       if (!single_succ_p (bb))
        {
-         BRANCH_EDGE (bb)->probability
-           = profile_probability::from_reg_br_prob_base (combined_probability);
+         BRANCH_EDGE (bb)->probability = p;
          FALLTHRU_EDGE (bb)->probability
            = BRANCH_EDGE (bb)->probability.invert ();
        }
     }
   else if (!single_succ_p (bb))
     {
-      int prob = XINT (prob_note, 0);
+      profile_probability prob = profile_probability::from_reg_br_prob_note
+                                       (XINT (prob_note, 0));
 
-      BRANCH_EDGE (bb)->probability
-        = profile_probability::from_reg_br_prob_base (prob);
-      FALLTHRU_EDGE (bb)->probability
-        = BRANCH_EDGE (bb)->probability.invert ();
+      BRANCH_EDGE (bb)->probability = prob;
+      FALLTHRU_EDGE (bb)->probability = prob.invert ();
     }
   else
     single_succ_edge (bb)->probability = profile_probability::always ();
index 1441fa4d8eb86cdc8fcfebe7f532133656c5ba28..a6cf1ee70e18d6930e36138def7a745e256dd68a 100644 (file)
@@ -47,6 +47,9 @@ enum prediction
    TAKEN
 };
 
+/* In emit-rtl.c.  */
+extern profile_probability split_branch_probability;
+
 extern gcov_type get_hot_bb_threshold (void);
 extern void set_hot_bb_threshold (gcov_type);
 extern bool maybe_hot_count_p (struct function *, profile_count);
@@ -96,4 +99,6 @@ extern void rebuild_frequencies (void);
 extern void report_predictor_hitrates (void);
 extern void force_edge_cold (edge, bool);
 
+extern void add_reg_br_prob_note (rtx_insn *, profile_probability);
+
 #endif  /* GCC_PREDICT_H */
index aef9da3bfce9f24ce0df30ee37922fafaca96579..8fd22b8b68abfec72379ac5034edc68abe9b2f98 100644 (file)
@@ -190,6 +190,23 @@ public:
       return RDIV (m_val * REG_BR_PROB_BASE, max_probability);
     }
 
+  /* Conversion to and from RTL representation of profile probabilities.  */
+  static profile_probability from_reg_br_prob_note (int v)
+    {
+      profile_probability ret;
+      ret.m_val = ((unsigned int)v) / 4;
+      ret.m_quality = (enum profile_quality)(v & 3);
+      return ret;
+    }
+  int to_reg_br_prob_note () const
+    {
+      gcc_checking_assert (initialized_p ());
+      int ret = m_val * 4 + m_quality;
+      gcc_checking_assert (profile_probability::from_reg_br_prob_note (ret)
+                          == *this);
+      return ret;
+    }
+
   /* Return VAL1/VAL2.  */
   static profile_probability probability_in_gcov_type
                                 (gcov_type val1, gcov_type val2)
index 8734d26e5b47bf243609d7e8731c7632a145e856..943eff41d307b1a5468edf9f8c6623024b55baff 100644 (file)
@@ -99,20 +99,21 @@ REG_NOTE (DEP_OUTPUT)
 REG_NOTE (DEP_ANTI)
 REG_NOTE (DEP_CONTROL)
 
-/* REG_BR_PROB is attached to JUMP_INSNs and CALL_INSNs.  It has an
+/* REG_BR_PROB is attached to JUMP_INSNs.  It has an
    integer value (in an INT_LIST).  For jumps, it is the probability
-   that this is a taken branch.  For calls, it is the probability that
-   this call won't return.  */
+   that this is a taken branch. The integer represents a value of
+   profile_probability type. Use to_reg_br_prob_note and from_reg_br_prob_note
+   to extract the actual value.  */
 REG_NOTE (BR_PROB)
 
 /* Attached to a call insn; indicates that the call is malloc-like and
    that the pointer returned cannot alias anything else.  */
 REG_NOTE (NOALIAS)
 
-/* REG_BR_PRED is attached to JUMP_INSNs and CALL_INSNSs.  It contains
+/* REG_BR_PRED is attached to JUMP_INSNs.  It contains
    CONCAT of two integer value.  First specifies the branch predictor
    that added the note, second specifies the predicted hitrate of
-   branch in the same format as REG_BR_PROB note uses.  */
+   branch in a fixed point arithmetic based on REG_BR_PROB_BASE.  */
 REG_NOTE (BR_PRED)
 
 /* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
index dbd74ab24045bbc8b51dc9b41226a9832f382270..5914af655b6bbbddc98f23f53c0d1e6e496dc2eb 100644 (file)
@@ -840,7 +840,8 @@ mostly_true_jump (rtx jump_insn)
   rtx note = find_reg_note (jump_insn, REG_BR_PROB, 0);
   if (note)
     {
-      int prob = XINT (note, 0);
+      int prob = profile_probability::from_reg_br_prob_note (XINT (note, 0))
+                       .to_reg_br_prob_base ();
 
       if (prob >= REG_BR_PROB_BASE * 9 / 10)
        return 2;
index 59da995c21aec9dbe99fd49891fb53f182cfb42b..e63dcf042cb6eae5bf2b07ab2e055951c2be90be 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2938,7 +2938,6 @@ extern rtx *find_constant_term_loc (rtx *);
 
 /* In emit-rtl.c  */
 extern rtx_insn *try_split (rtx, rtx_insn *, int);
-extern int split_branch_probability;
 
 /* In insn-recog.c (generated by genrecog).  */
 extern rtx_insn *split_insns (rtx, rtx_insn *);
index 6472e11f4011cfd093a1500ec13e9672ae85b22e..3ede9d83653e2e54ceb89b94cd3fb80d677a4379 100644 (file)
@@ -1,3 +1,7 @@
+2017-07-16  Jan Hubicka  <hubicka@ucw.cz>
+
+       * gcc.dg/predict-8.c: Update.
+
 2017-07-16  Volker Reichelt  <v.reichelt@netcologne.de>
 
        * g++.dg/cpp1z/direct-enum-init1.C: Revert special enum handling.
index edead8d90b10bc8f04d473af7667ba33ad727c72..e13cc006f3af52a05eef908e1d17b0e8646ef40a 100644 (file)
@@ -8,4 +8,4 @@ int foo(float a, float b) {
     return 2;
 }
 
-/* { dg-final { scan-rtl-dump-times "REG_BR_PROB 100" 1 "expand"} } */
+/* { dg-final { scan-rtl-dump-times "REG_BR_PROB 400 " 1 "expand"} } */