profile-count.h (profile_probability::from_reg_br_prob_note, [...]): New functions.

* 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
This commit is contained in:
Jan Hubicka 2017-07-16 18:10:58 +02:00 committed by Jan Hubicka
parent 519087cf74
commit 5fa396ad6c
38 changed files with 261 additions and 184 deletions

View 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.

View 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

View 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;
}

View 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)

View 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. */

View 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

View 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

View 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. */

View 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;

View 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);
}

View 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

View 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

View 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;

View 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);

View 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);

View 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)
{

View 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);

View 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))
&& 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 / 2U;
msw_skip_prob
= REG_BR_PROB_BASE * rev_prob / (REG_BR_PROB_BASE + rev_prob);
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;

View File

@ -1188,7 +1188,7 @@
(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;
})

View 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;
}

View 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 ();

View 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;

View 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;

View 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

View 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;
/* 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);
}
}
}

View 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)

View 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

View 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. */

View 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 ();

View 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

View 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 ();

View 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 */

View 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)

View 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

View 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;

View File

@ -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 *);

View 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.

View 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"} } */