From: Jakub Jelinek Date: Thu, 23 Feb 2017 22:05:19 +0000 (+0100) Subject: re PR tree-optimization/79389 (30% performance regression in SciMark2 MonteCarlo) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ada61c3d4774b98d42b53e99836abd695969fbc6;p=gcc.git re PR tree-optimization/79389 (30% performance regression in SciMark2 MonteCarlo) PR tree-optimization/79389 * ifcvt.c (struct noce_if_info): Add rev_cond field. (noce_reversed_cond_code): New function. (noce_emit_store_flag): Use rev_cond if non-NULL instead of reversed_comparison_code. Formatting fix. (noce_try_store_flag): Test rev_cond != NULL in addition to reversed_comparison_code. (noce_try_store_flag_constants): Likewise. (noce_try_store_flag_mask): Likewise. (noce_try_addcc): Use rev_cond if non-NULL instead of reversed_comparison_code. (noce_try_cmove_arith): Likewise. Formatting fixes. (noce_try_minmax, noce_try_abs): Clear rev_cond. (noce_find_if_block): Initialize rev_cond. (find_cond_trap): Call noce_get_condition with then_bb == trap_bb instead of false as last argument never attempt to reverse it afterwards. From-SVN: r245690 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 906607f4123..ffb5e25510e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2017-02-23 Jakub Jelinek + + PR tree-optimization/79389 + * ifcvt.c (struct noce_if_info): Add rev_cond field. + (noce_reversed_cond_code): New function. + (noce_emit_store_flag): Use rev_cond if non-NULL instead of + reversed_comparison_code. Formatting fix. + (noce_try_store_flag): Test rev_cond != NULL in addition to + reversed_comparison_code. + (noce_try_store_flag_constants): Likewise. + (noce_try_store_flag_mask): Likewise. + (noce_try_addcc): Use rev_cond if non-NULL instead of + reversed_comparison_code. + (noce_try_cmove_arith): Likewise. Formatting fixes. + (noce_try_minmax, noce_try_abs): Clear rev_cond. + (noce_find_if_block): Initialize rev_cond. + (find_cond_trap): Call noce_get_condition with then_bb == trap_bb + instead of false as last argument never attempt to reverse it + afterwards. + 2017-02-23 Bin Cheng PR tree-optimization/79663 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index e2d6c6fcc51..4fd1744643e 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -777,6 +777,9 @@ struct noce_if_info /* The jump condition. */ rtx cond; + /* Reversed jump condition. */ + rtx rev_cond; + /* New insns should be inserted before this one. */ rtx_insn *cond_earliest; @@ -843,6 +846,17 @@ static int noce_try_minmax (struct noce_if_info *); static int noce_try_abs (struct noce_if_info *); static int noce_try_sign_mask (struct noce_if_info *); +/* Return the comparison code for reversed condition for IF_INFO, + or UNKNOWN if reversing the condition is not possible. */ + +static inline enum rtx_code +noce_reversed_cond_code (struct noce_if_info *if_info) +{ + if (if_info->rev_cond) + return GET_CODE (if_info->rev_cond); + return reversed_comparison_code (if_info->cond, if_info->jump); +} + /* Return TRUE if SEQ is a good candidate as a replacement for the if-convertible sequence described in IF_INFO. */ @@ -888,6 +902,14 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep, if (if_info->then_else_reversed) reversep = !reversep; } + else if (reversep + && if_info->rev_cond + && general_operand (XEXP (if_info->rev_cond, 0), VOIDmode) + && general_operand (XEXP (if_info->rev_cond, 1), VOIDmode)) + { + cond = if_info->rev_cond; + reversep = false; + } if (reversep) code = reversed_comparison_code (cond, if_info->jump); @@ -898,7 +920,7 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep, && (normalize == 0 || STORE_FLAG_VALUE == normalize)) { rtx src = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0), - XEXP (cond, 1)); + XEXP (cond, 1)); rtx set = gen_rtx_SET (x, src); start_sequence (); @@ -1209,8 +1231,7 @@ noce_try_store_flag (struct noce_if_info *if_info) else if (if_info->b == const0_rtx && CONST_INT_P (if_info->a) && INTVAL (if_info->a) == STORE_FLAG_VALUE - && (reversed_comparison_code (if_info->cond, if_info->jump) - != UNKNOWN)) + && noce_reversed_cond_code (if_info) != UNKNOWN) reversep = 1; else return FALSE; @@ -1371,9 +1392,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) diff = trunc_int_for_mode (diff, mode); - can_reverse = (reversed_comparison_code (if_info->cond, if_info->jump) - != UNKNOWN); - + can_reverse = noce_reversed_cond_code (if_info) != UNKNOWN; reversep = false; if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE) { @@ -1553,11 +1572,18 @@ noce_try_addcc (struct noce_if_info *if_info) if (GET_CODE (if_info->a) == PLUS && rtx_equal_p (XEXP (if_info->a, 0), if_info->b) - && (reversed_comparison_code (if_info->cond, if_info->jump) - != UNKNOWN)) + && noce_reversed_cond_code (if_info) != UNKNOWN) { - rtx cond = if_info->cond; - enum rtx_code code = reversed_comparison_code (cond, if_info->jump); + rtx cond = if_info->rev_cond; + enum rtx_code code; + + if (cond == NULL_RTX) + { + cond = if_info->cond; + code = reversed_comparison_code (cond, if_info->jump); + } + else + code = GET_CODE (cond); /* First try to use addcc pattern. */ if (general_operand (XEXP (cond, 0), VOIDmode) @@ -1652,9 +1678,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) if ((if_info->a == const0_rtx && rtx_equal_p (if_info->b, if_info->x)) - || ((reversep = (reversed_comparison_code (if_info->cond, - if_info->jump) - != UNKNOWN)) + || ((reversep = (noce_reversed_cond_code (if_info) != UNKNOWN)) && if_info->b == const0_rtx && rtx_equal_p (if_info->a, if_info->x))) { @@ -2086,6 +2110,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) rtx target; int is_mem = 0; enum rtx_code code; + rtx cond = if_info->cond; rtx_insn *ifcvt_seq; /* A conditional move from two memory sources is equivalent to a @@ -2117,7 +2142,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) x = y; */ - code = GET_CODE (if_info->cond); + code = GET_CODE (cond); insn_a = if_info->insn_a; insn_b = if_info->insn_b; @@ -2127,7 +2152,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) return FALSE; /* Possibly rearrange operands to make things come out more natural. */ - if (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN) + if (noce_reversed_cond_code (if_info) != UNKNOWN) { int reversep = 0; if (rtx_equal_p (b, x)) @@ -2137,7 +2162,13 @@ noce_try_cmove_arith (struct noce_if_info *if_info) if (reversep) { - code = reversed_comparison_code (if_info->cond, if_info->jump); + if (if_info->rev_cond) + { + cond = if_info->rev_cond; + code = GET_CODE (cond); + } + else + code = reversed_comparison_code (cond, if_info->jump); std::swap (a, b); std::swap (insn_a, insn_b); std::swap (a_simple, b_simple); @@ -2173,7 +2204,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) rtx emit_b = NULL_RTX; rtx_insn *tmp_insn = NULL; bool modified_in_a = false; - bool modified_in_b = false; + bool modified_in_b = false; /* If either operand is complex, load it into a register first. The best way to do this is to copy the original insn. In this way we preserve any clobbers etc that the insn may have had. @@ -2231,7 +2262,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) rtx tmp_reg = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b)); emit_b = gen_rtx_SET (tmp_reg, b); b = tmp_reg; - } + } } } @@ -2286,8 +2317,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info) else goto end_seq_and_fail; - target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0), - XEXP (if_info->cond, 1), a, b); + target = noce_emit_cmove (if_info, x, code, XEXP (cond, 0), XEXP (cond, 1), + a, b); if (! target) goto end_seq_and_fail; @@ -2576,6 +2607,7 @@ noce_try_minmax (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->cond = cond; if_info->cond_earliest = earliest; + if_info->rev_cond = NULL_RTX; if_info->transform_name = "noce_try_minmax"; return TRUE; @@ -2743,6 +2775,7 @@ noce_try_abs (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->cond = cond; if_info->cond_earliest = earliest; + if_info->rev_cond = NULL_RTX; if_info->transform_name = "noce_try_abs"; return TRUE; @@ -4064,6 +4097,11 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, if_info.else_bb = else_bb; if_info.join_bb = join_bb; if_info.cond = cond; + rtx_insn *rev_cond_earliest; + if_info.rev_cond = noce_get_condition (jump, &rev_cond_earliest, + !then_else_reversed); + gcc_assert (if_info.rev_cond == NULL_RTX + || rev_cond_earliest == cond_earliest); if_info.cond_earliest = cond_earliest; if_info.jump = jump; if_info.then_else_reversed = then_else_reversed; @@ -4634,7 +4672,6 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) rtx_insn *trap, *jump; rtx cond; rtx_insn *cond_earliest; - enum rtx_code code; /* Locate the block with the trap instruction. */ /* ??? While we look for no successors, we really ought to allow @@ -4654,7 +4691,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) /* If this is not a standard conditional jump, we can't parse it. */ jump = BB_END (test_bb); - cond = noce_get_condition (jump, &cond_earliest, false); + cond = noce_get_condition (jump, &cond_earliest, then_bb == trap_bb); if (! cond) return FALSE; @@ -4670,17 +4707,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) if (GET_MODE (XEXP (cond, 0)) == BLKmode) return FALSE; - /* Reverse the comparison code, if necessary. */ - code = GET_CODE (cond); - if (then_bb == trap_bb) - { - code = reversed_comparison_code (cond, jump); - if (code == UNKNOWN) - return FALSE; - } - /* Attempt to generate the conditional trap. */ - rtx_insn *seq = gen_cond_trap (code, copy_rtx (XEXP (cond, 0)), + rtx_insn *seq = gen_cond_trap (GET_CODE (cond), copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)), TRAP_CODE (PATTERN (trap))); if (seq == NULL)