diff options
author | Pat Haugen <pthaugen@us.ibm.com> | 2004-06-23 16:07:58 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2004-06-23 12:07:58 -0400 |
commit | 701b17c2dc9a6d35097455e6fd410d4dabce29e7 (patch) | |
tree | 1a89f07a18835e2ff45f39c2a9c51d277d13ed95 /gcc/value-prof.c | |
parent | dcbbf6f31bcbb4a3f03793eb6415c6b8202b9f93 (diff) | |
download | gcc-701b17c2dc9a6d35097455e6fd410d4dabce29e7.zip gcc-701b17c2dc9a6d35097455e6fd410d4dabce29e7.tar.gz gcc-701b17c2dc9a6d35097455e6fd410d4dabce29e7.tar.bz2 |
re PR rtl-optimization/15633 (Failure to propagate FDO counters by vpt results in performance regression)
2004-06-23 Pat Haugen <pthaugen@us.ibm.com>
PR optimization/15633
* value-prof.c (divmod_fixed_value_transform): Compute probability
of taking optimal path and pass along to gen_ routine.
(mod_pow2_value_transform): Same.
(mod_subtract_transform): Same.
(gen_divmod_fixed_value): Add new probability parameter.
Add probability to newly created jump.
(gen_mod_pow2): Same.
(gen_mod_subtract): Same.
From-SVN: r83555
Diffstat (limited to 'gcc/value-prof.c')
-rw-r--r-- | gcc/value-prof.c | 82 |
1 files changed, 62 insertions, 20 deletions
diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 514b98f..17f78f6 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -56,10 +56,10 @@ static void insn_divmod_values_to_profile (rtx, unsigned *, struct histogram_value **); static void insn_values_to_profile (rtx, unsigned *, struct histogram_value **); static rtx gen_divmod_fixed_value (enum machine_mode, enum rtx_code, rtx, rtx, - rtx, gcov_type); -static rtx gen_mod_pow2 (enum machine_mode, enum rtx_code, rtx, rtx, rtx); + rtx, gcov_type, int); +static rtx gen_mod_pow2 (enum machine_mode, enum rtx_code, rtx, rtx, rtx, int); static rtx gen_mod_subtract (enum machine_mode, enum rtx_code, rtx, rtx, rtx, - int); + int, int, int); static bool divmod_fixed_value_transform (rtx insn); static bool mod_pow2_value_transform (rtx); static bool mod_subtract_transform (rtx); @@ -365,12 +365,14 @@ rtl_value_profile_transformations (void) } /* Generate code for transformation 1 (with MODE and OPERATION, operands OP1 - and OP2 whose value is expected to be VALUE and result TARGET). */ + and OP2, whose value is expected to be VALUE, result TARGET and + probability of taking the optimal path PROB). */ static rtx gen_divmod_fixed_value (enum machine_mode mode, enum rtx_code operation, - rtx target, rtx op1, rtx op2, gcov_type value) + rtx target, rtx op1, rtx op2, gcov_type value, + int prob) { - rtx tmp, tmp1; + rtx tmp, tmp1, jump; rtx neq_label = gen_label_rtx (); rtx end_label = gen_label_rtx (); rtx sequence; @@ -387,7 +389,15 @@ gen_divmod_fixed_value (enum machine_mode mode, enum rtx_code operation, do_compare_rtx_and_jump (tmp, GEN_INT (value), NE, 0, mode, NULL_RTX, NULL_RTX, neq_label); - tmp1 = simplify_gen_binary (operation, mode, copy_rtx (op1), GEN_INT (value)); + + /* Add branch probability to jump we just created. */ + jump = get_last_insn (); + REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, + GEN_INT (REG_BR_PROB_BASE - prob), + REG_NOTES (jump)); + + tmp1 = simplify_gen_binary (operation, mode, + copy_rtx (op1), GEN_INT (value)); tmp1 = force_operand (tmp1, target); if (tmp1 != target) emit_move_insn (copy_rtx (target), copy_rtx (tmp1)); @@ -396,7 +406,8 @@ gen_divmod_fixed_value (enum machine_mode mode, enum rtx_code operation, emit_barrier (); emit_label (neq_label); - tmp1 = simplify_gen_binary (operation, mode, copy_rtx (op1), copy_rtx (tmp)); + tmp1 = simplify_gen_binary (operation, mode, + copy_rtx (op1), copy_rtx (tmp)); tmp1 = force_operand (tmp1, target); if (tmp1 != target) emit_move_insn (copy_rtx (target), copy_rtx (tmp1)); @@ -418,6 +429,7 @@ divmod_fixed_value_transform (rtx insn) enum machine_mode mode; gcov_type val, count, all; edge e; + int prob; set = single_set (insn); if (!set) @@ -462,22 +474,26 @@ divmod_fixed_value_transform (rtx insn) fprintf (dump_file, "Div/mod by constant transformation on insn %d\n", INSN_UID (insn)); + /* Compute probability of taking the optimal path. */ + prob = (count * REG_BR_PROB_BASE + all / 2) / all; + e = split_block (BLOCK_FOR_INSN (insn), PREV_INSN (insn)); delete_insn (insn); insert_insn_on_edge ( - gen_divmod_fixed_value (mode, code, set_dest, op1, op2, val), e); + gen_divmod_fixed_value (mode, code, set_dest, + op1, op2, val, prob), e); return true; } /* Generate code for transformation 2 (with MODE and OPERATION, operands OP1 - and OP2 and result TARGET). */ + and OP2, result TARGET and probability of taking the optimal path PROB). */ static rtx gen_mod_pow2 (enum machine_mode mode, enum rtx_code operation, rtx target, - rtx op1, rtx op2) + rtx op1, rtx op2, int prob) { - rtx tmp, tmp1, tmp2, tmp3; + rtx tmp, tmp1, tmp2, tmp3, jump; rtx neq_label = gen_label_rtx (); rtx end_label = gen_label_rtx (); rtx sequence; @@ -498,6 +514,13 @@ gen_mod_pow2 (enum machine_mode mode, enum rtx_code operation, rtx target, 0, OPTAB_WIDEN); do_compare_rtx_and_jump (tmp2, const0_rtx, NE, 0, mode, NULL_RTX, NULL_RTX, neq_label); + + /* Add branch probability to jump we just created. */ + jump = get_last_insn (); + REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, + GEN_INT (REG_BR_PROB_BASE - prob), + REG_NOTES (jump)); + tmp3 = expand_simple_binop (mode, AND, op1, tmp1, target, 0, OPTAB_WIDEN); if (tmp3 != target) @@ -528,7 +551,7 @@ mod_pow2_value_transform (rtx insn) enum machine_mode mode; gcov_type wrong_values, count; edge e; - int i; + int i, all, prob; set = single_set (insn); if (!set) @@ -578,22 +601,27 @@ mod_pow2_value_transform (rtx insn) fprintf (dump_file, "Mod power of 2 transformation on insn %d\n", INSN_UID (insn)); + /* Compute probability of taking the optimal path. */ + all = count + wrong_values; + prob = (count * REG_BR_PROB_BASE + all / 2) / all; + e = split_block (BLOCK_FOR_INSN (insn), PREV_INSN (insn)); delete_insn (insn); insert_insn_on_edge ( - gen_mod_pow2 (mode, code, set_dest, op1, op2), e); + gen_mod_pow2 (mode, code, set_dest, op1, op2, prob), e); return true; } /* Generate code for transformations 3 and 4 (with MODE and OPERATION, - operands OP1 and OP2, result TARGET and at most SUB subtractions). */ + operands OP1 and OP2, result TARGET, at most SUB subtractions, and + probability of taking the optimal path(s) PROB1 and PROB2). */ static rtx gen_mod_subtract (enum machine_mode mode, enum rtx_code operation, - rtx target, rtx op1, rtx op2, int sub) + rtx target, rtx op1, rtx op2, int sub, int prob1, int prob2) { - rtx tmp, tmp1; + rtx tmp, tmp1, jump; rtx end_label = gen_label_rtx (); rtx sequence; int i; @@ -611,7 +639,11 @@ gen_mod_subtract (enum machine_mode mode, enum rtx_code operation, emit_move_insn (target, copy_rtx (op1)); do_compare_rtx_and_jump (target, tmp, LTU, 0, mode, NULL_RTX, NULL_RTX, end_label); - + + /* Add branch probability to jump we just created. */ + jump = get_last_insn (); + REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, + GEN_INT (prob1), REG_NOTES (jump)); for (i = 0; i < sub; i++) { @@ -621,6 +653,11 @@ gen_mod_subtract (enum machine_mode mode, enum rtx_code operation, emit_move_insn (target, tmp1); do_compare_rtx_and_jump (target, tmp, LTU, 0, mode, NULL_RTX, NULL_RTX, end_label); + + /* Add branch probability to jump we just created. */ + jump = get_last_insn (); + REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, + GEN_INT (prob2), REG_NOTES (jump)); } tmp1 = simplify_gen_binary (operation, mode, copy_rtx (target), copy_rtx (tmp)); @@ -645,7 +682,7 @@ mod_subtract_transform (rtx insn) enum machine_mode mode; gcov_type wrong_values, counts[2], count, all; edge e; - int i; + int i, prob1, prob2; set = single_set (insn); if (!set) @@ -704,11 +741,16 @@ mod_subtract_transform (rtx insn) fprintf (dump_file, "Mod subtract transformation on insn %d\n", INSN_UID (insn)); + /* Compute probability of taking the optimal path(s). */ + prob1 = (counts[0] * REG_BR_PROB_BASE + all / 2) / all; + prob2 = (counts[1] * REG_BR_PROB_BASE + all / 2) / all; + e = split_block (BLOCK_FOR_INSN (insn), PREV_INSN (insn)); delete_insn (insn); insert_insn_on_edge ( - gen_mod_subtract (mode, code, set_dest, op1, op2, i), e); + gen_mod_subtract (mode, code, set_dest, + op1, op2, i, prob1, prob2), e); return true; } |