From 701b17c2dc9a6d35097455e6fd410d4dabce29e7 Mon Sep 17 00:00:00 2001 From: Pat Haugen Date: Wed, 23 Jun 2004 16:07:58 +0000 Subject: [PATCH] re PR rtl-optimization/15633 (Failure to propagate FDO counters by vpt results in performance regression) 2004-06-23 Pat Haugen 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 --- gcc/ChangeLog | 12 +++++++ gcc/value-prof.c | 82 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index db45e7e2e9e..b907be90ed2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2004-06-23 Pat Haugen + + 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. + 2004-06-23 Richard Earnshaw * PR target/15948 diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 514b98f5190..17f78f6cbbd 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; } -- 2.30.2