Commit 3e5bcef3 by Roger Sayle Committed by Roger Sayle

re PR target/18002 ('while' loop performace regression on avr target)


	PR target/18002
	PR middle-end/18424
	* dojump.c (do_jump): When attempting to reverse the effects of
	fold_single_bit_test, we need to STRIP_NOPS and narrowing type
	conversions, and handle BIT_XOR_EXPR that's used to invert the
	sense of the single bit test.

From-SVN: r92024
parent aa6cc10d
2004-12-10 Roger Sayle <roger@eyesopen.com>
PR target/18002
PR middle-end/18424
* dojump.c (do_jump): When attempting to reverse the effects of
fold_single_bit_test, we need to STRIP_NOPS and narrowing type
conversions, and handle BIT_XOR_EXPR that's used to invert the
sense of the single bit test.
2004-12-10 Devang Patel <dpatel@apple.com> 2004-12-10 Devang Patel <dpatel@apple.com>
PR 18732 PR 18732
......
...@@ -218,26 +218,54 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) ...@@ -218,26 +218,54 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label)
/* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1. /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
See if the former is preferred for jump tests and restore it See if the former is preferred for jump tests and restore it
if so. */ if so. */
if (TREE_CODE (TREE_OPERAND (exp, 0)) == RSHIFT_EXPR if (integer_onep (TREE_OPERAND (exp, 1)))
&& integer_onep (TREE_OPERAND (exp, 1)))
{ {
tree arg = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); tree exp0 = TREE_OPERAND (exp, 0);
tree shift = TREE_OPERAND (TREE_OPERAND (exp, 0), 1); rtx set_label, clr_label;
tree one = TREE_OPERAND (exp, 1);
/* Strip narrowing integral type conversions. */
while ((TREE_CODE (exp0) == NOP_EXPR
|| TREE_CODE (exp0) == CONVERT_EXPR
|| TREE_CODE (exp0) == NON_LVALUE_EXPR)
&& TREE_OPERAND (exp0, 0) != error_mark_node
&& TYPE_PRECISION (TREE_TYPE (exp0))
<= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
exp0 = TREE_OPERAND (exp0, 0);
/* "exp0 ^ 1" inverts the sense of the single bit test. */
if (TREE_CODE (exp0) == BIT_XOR_EXPR
&& integer_onep (TREE_OPERAND (exp0, 1)))
{
exp0 = TREE_OPERAND (exp0, 0);
clr_label = if_true_label;
set_label = if_false_label;
}
else
{
clr_label = if_false_label;
set_label = if_true_label;
}
if (TREE_CODE (exp0) == RSHIFT_EXPR)
{
tree arg = TREE_OPERAND (exp0, 0);
tree shift = TREE_OPERAND (exp0, 1);
tree argtype = TREE_TYPE (arg); tree argtype = TREE_TYPE (arg);
if (TREE_CODE (shift) == INTEGER_CST if (TREE_CODE (shift) == INTEGER_CST
&& compare_tree_int (shift, 0) > 0 && compare_tree_int (shift, 0) >= 0
&& compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
&& prefer_and_bit_test (TYPE_MODE (argtype), && prefer_and_bit_test (TYPE_MODE (argtype),
TREE_INT_CST_LOW (shift))) TREE_INT_CST_LOW (shift)))
{ {
HOST_WIDE_INT mask = (HOST_WIDE_INT) 1
<< TREE_INT_CST_LOW (shift);
do_jump (build2 (BIT_AND_EXPR, argtype, arg, do_jump (build2 (BIT_AND_EXPR, argtype, arg,
fold (build2 (LSHIFT_EXPR, argtype, build_int_cst_type (argtype, mask)),
one, shift))), clr_label, set_label);
if_false_label, if_true_label);
break; break;
} }
} }
}
/* If we are AND'ing with a small constant, do this comparison in the /* If we are AND'ing with a small constant, do this comparison in the
smallest type that fits. If the machine doesn't have comparisons smallest type that fits. If the machine doesn't have comparisons
......
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