Commit ada61c3d by Jakub Jelinek Committed by Jakub Jelinek

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
parent d822f3d5
2017-02-23 Jakub Jelinek <jakub@redhat.com>
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 <bin.cheng@arm.com> 2017-02-23 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/79663 PR tree-optimization/79663
......
...@@ -777,6 +777,9 @@ struct noce_if_info ...@@ -777,6 +777,9 @@ struct noce_if_info
/* The jump condition. */ /* The jump condition. */
rtx cond; rtx cond;
/* Reversed jump condition. */
rtx rev_cond;
/* New insns should be inserted before this one. */ /* New insns should be inserted before this one. */
rtx_insn *cond_earliest; rtx_insn *cond_earliest;
...@@ -843,6 +846,17 @@ static int noce_try_minmax (struct noce_if_info *); ...@@ -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_abs (struct noce_if_info *);
static int noce_try_sign_mask (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 /* Return TRUE if SEQ is a good candidate as a replacement for the
if-convertible sequence described in IF_INFO. */ 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, ...@@ -888,6 +902,14 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
if (if_info->then_else_reversed) if (if_info->then_else_reversed)
reversep = !reversep; 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) if (reversep)
code = reversed_comparison_code (cond, if_info->jump); code = reversed_comparison_code (cond, if_info->jump);
...@@ -1209,8 +1231,7 @@ noce_try_store_flag (struct noce_if_info *if_info) ...@@ -1209,8 +1231,7 @@ noce_try_store_flag (struct noce_if_info *if_info)
else if (if_info->b == const0_rtx else if (if_info->b == const0_rtx
&& CONST_INT_P (if_info->a) && CONST_INT_P (if_info->a)
&& INTVAL (if_info->a) == STORE_FLAG_VALUE && INTVAL (if_info->a) == STORE_FLAG_VALUE
&& (reversed_comparison_code (if_info->cond, if_info->jump) && noce_reversed_cond_code (if_info) != UNKNOWN)
!= UNKNOWN))
reversep = 1; reversep = 1;
else else
return FALSE; return FALSE;
...@@ -1371,9 +1392,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) ...@@ -1371,9 +1392,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
diff = trunc_int_for_mode (diff, mode); diff = trunc_int_for_mode (diff, mode);
can_reverse = (reversed_comparison_code (if_info->cond, if_info->jump) can_reverse = noce_reversed_cond_code (if_info) != UNKNOWN;
!= UNKNOWN);
reversep = false; reversep = false;
if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE) if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
{ {
...@@ -1553,11 +1572,18 @@ noce_try_addcc (struct noce_if_info *if_info) ...@@ -1553,11 +1572,18 @@ noce_try_addcc (struct noce_if_info *if_info)
if (GET_CODE (if_info->a) == PLUS if (GET_CODE (if_info->a) == PLUS
&& rtx_equal_p (XEXP (if_info->a, 0), if_info->b) && rtx_equal_p (XEXP (if_info->a, 0), if_info->b)
&& (reversed_comparison_code (if_info->cond, if_info->jump) && noce_reversed_cond_code (if_info) != UNKNOWN)
!= UNKNOWN))
{ {
rtx cond = if_info->cond; rtx cond = if_info->rev_cond;
enum rtx_code code = reversed_comparison_code (cond, if_info->jump); 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. */ /* First try to use addcc pattern. */
if (general_operand (XEXP (cond, 0), VOIDmode) if (general_operand (XEXP (cond, 0), VOIDmode)
...@@ -1652,9 +1678,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) ...@@ -1652,9 +1678,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
if ((if_info->a == const0_rtx if ((if_info->a == const0_rtx
&& rtx_equal_p (if_info->b, if_info->x)) && rtx_equal_p (if_info->b, if_info->x))
|| ((reversep = (reversed_comparison_code (if_info->cond, || ((reversep = (noce_reversed_cond_code (if_info) != UNKNOWN))
if_info->jump)
!= UNKNOWN))
&& if_info->b == const0_rtx && if_info->b == const0_rtx
&& rtx_equal_p (if_info->a, if_info->x))) && rtx_equal_p (if_info->a, if_info->x)))
{ {
...@@ -2086,6 +2110,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) ...@@ -2086,6 +2110,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
rtx target; rtx target;
int is_mem = 0; int is_mem = 0;
enum rtx_code code; enum rtx_code code;
rtx cond = if_info->cond;
rtx_insn *ifcvt_seq; rtx_insn *ifcvt_seq;
/* A conditional move from two memory sources is equivalent to a /* 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) ...@@ -2117,7 +2142,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
x = y; x = y;
*/ */
code = GET_CODE (if_info->cond); code = GET_CODE (cond);
insn_a = if_info->insn_a; insn_a = if_info->insn_a;
insn_b = if_info->insn_b; insn_b = if_info->insn_b;
...@@ -2127,7 +2152,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) ...@@ -2127,7 +2152,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
return FALSE; return FALSE;
/* Possibly rearrange operands to make things come out more natural. */ /* 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; int reversep = 0;
if (rtx_equal_p (b, x)) if (rtx_equal_p (b, x))
...@@ -2137,7 +2162,13 @@ noce_try_cmove_arith (struct noce_if_info *if_info) ...@@ -2137,7 +2162,13 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
if (reversep) 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 (a, b);
std::swap (insn_a, insn_b); std::swap (insn_a, insn_b);
std::swap (a_simple, b_simple); std::swap (a_simple, b_simple);
...@@ -2286,8 +2317,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info) ...@@ -2286,8 +2317,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
else else
goto end_seq_and_fail; goto end_seq_and_fail;
target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0), target = noce_emit_cmove (if_info, x, code, XEXP (cond, 0), XEXP (cond, 1),
XEXP (if_info->cond, 1), a, b); a, b);
if (! target) if (! target)
goto end_seq_and_fail; goto end_seq_and_fail;
...@@ -2576,6 +2607,7 @@ noce_try_minmax (struct noce_if_info *if_info) ...@@ -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)); emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
if_info->cond = cond; if_info->cond = cond;
if_info->cond_earliest = earliest; if_info->cond_earliest = earliest;
if_info->rev_cond = NULL_RTX;
if_info->transform_name = "noce_try_minmax"; if_info->transform_name = "noce_try_minmax";
return TRUE; return TRUE;
...@@ -2743,6 +2775,7 @@ noce_try_abs (struct noce_if_info *if_info) ...@@ -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)); emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
if_info->cond = cond; if_info->cond = cond;
if_info->cond_earliest = earliest; if_info->cond_earliest = earliest;
if_info->rev_cond = NULL_RTX;
if_info->transform_name = "noce_try_abs"; if_info->transform_name = "noce_try_abs";
return TRUE; return TRUE;
...@@ -4064,6 +4097,11 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, ...@@ -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.else_bb = else_bb;
if_info.join_bb = join_bb; if_info.join_bb = join_bb;
if_info.cond = cond; 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.cond_earliest = cond_earliest;
if_info.jump = jump; if_info.jump = jump;
if_info.then_else_reversed = then_else_reversed; 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) ...@@ -4634,7 +4672,6 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
rtx_insn *trap, *jump; rtx_insn *trap, *jump;
rtx cond; rtx cond;
rtx_insn *cond_earliest; rtx_insn *cond_earliest;
enum rtx_code code;
/* Locate the block with the trap instruction. */ /* Locate the block with the trap instruction. */
/* ??? While we look for no successors, we really ought to allow /* ??? 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) ...@@ -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. */ /* If this is not a standard conditional jump, we can't parse it. */
jump = BB_END (test_bb); 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) if (! cond)
return FALSE; return FALSE;
...@@ -4670,17 +4707,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) ...@@ -4670,17 +4707,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
if (GET_MODE (XEXP (cond, 0)) == BLKmode) if (GET_MODE (XEXP (cond, 0)) == BLKmode)
return FALSE; 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. */ /* 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)), copy_rtx (XEXP (cond, 1)),
TRAP_CODE (PATTERN (trap))); TRAP_CODE (PATTERN (trap)));
if (seq == NULL) if (seq == NULL)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment