Commit f3ce1088 by Adam Nemet Committed by Adam Nemet

combine.c (try_widen_shift_mode): Add COUNT, OUTER_CODE and OUTER_CONST arguments.

	* combine.c (try_widen_shift_mode): Add COUNT, OUTER_CODE and
	OUTER_CONST arguments.
	<LSHIFTRT>: Use them to allow widening if the bits shifted in from
	the new wider mode will be masked off.
	(simplify_shift_const_1): Adjust calls to try_widen_shift_mode.

From-SVN: r149780
parent 3e63dd3a
2009-07-18 Adam Nemet <anemet@caviumnetworks.com> 2009-07-18 Adam Nemet <anemet@caviumnetworks.com>
* combine.c (try_widen_shift_mode): Add COUNT, OUTER_CODE and
OUTER_CONST arguments.
<LSHIFTRT>: Use them to allow widening if the bits shifted in from
the new wider mode will be masked off.
(simplify_shift_const_1): Adjust calls to try_widen_shift_mode.
2009-07-18 Adam Nemet <anemet@caviumnetworks.com>
* combine.c (try_widen_shift_mode) <LSHIFTRT>: Allow widening if the * combine.c (try_widen_shift_mode) <LSHIFTRT>: Allow widening if the
high-order bits are zero. high-order bits are zero.
......
...@@ -8985,11 +8985,14 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, ...@@ -8985,11 +8985,14 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1,
/* A helper to simplify_shift_const_1 to determine the mode we can perform /* A helper to simplify_shift_const_1 to determine the mode we can perform
the shift in. The original shift operation CODE is performed on OP in the shift in. The original shift operation CODE is performed on OP in
ORIG_MODE. Return the wider mode MODE if we can perform the operation ORIG_MODE. Return the wider mode MODE if we can perform the operation
in that mode. Return ORIG_MODE otherwise. */ in that mode. Return ORIG_MODE otherwise. We can also assume that the
result of the shift is subject to operation OUTER_CODE with operand
OUTER_CONST. */
static enum machine_mode static enum machine_mode
try_widen_shift_mode (enum rtx_code code, rtx op, try_widen_shift_mode (enum rtx_code code, rtx op, int count,
enum machine_mode orig_mode, enum machine_mode mode) enum machine_mode orig_mode, enum machine_mode mode,
enum rtx_code outer_code, HOST_WIDE_INT outer_const)
{ {
if (orig_mode == mode) if (orig_mode == mode)
return mode; return mode;
...@@ -9012,6 +9015,21 @@ try_widen_shift_mode (enum rtx_code code, rtx op, ...@@ -9012,6 +9015,21 @@ try_widen_shift_mode (enum rtx_code code, rtx op,
if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& (nonzero_bits (op, mode) & ~GET_MODE_MASK (orig_mode)) == 0) && (nonzero_bits (op, mode) & ~GET_MODE_MASK (orig_mode)) == 0)
return mode; return mode;
/* We can also widen if the bits brought in will be masked off. This
operation is performed in ORIG_MODE. */
if (outer_code == AND
&& GET_MODE_BITSIZE (orig_mode) <= HOST_BITS_PER_WIDE_INT)
{
int care_bits;
outer_const &= GET_MODE_MASK (orig_mode);
care_bits = exact_log2 (outer_const + 1);
if (care_bits >= 0
&& GET_MODE_BITSIZE (orig_mode) - care_bits >= count)
return mode;
}
/* fall through */ /* fall through */
case ROTATE: case ROTATE:
...@@ -9084,7 +9102,8 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode, ...@@ -9084,7 +9102,8 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
count = bitsize - count; count = bitsize - count;
} }
shift_mode = try_widen_shift_mode (code, varop, result_mode, mode); shift_mode = try_widen_shift_mode (code, varop, count, result_mode,
mode, outer_op, outer_const);
/* Handle cases where the count is greater than the size of the mode /* Handle cases where the count is greater than the size of the mode
minus 1. For ASHIFT, use the size minus one as the count (this can minus 1. For ASHIFT, use the size minus one as the count (this can
...@@ -9682,7 +9701,8 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode, ...@@ -9682,7 +9701,8 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
break; break;
} }
shift_mode = try_widen_shift_mode (code, varop, result_mode, mode); shift_mode = try_widen_shift_mode (code, varop, count, result_mode, mode,
outer_op, outer_const);
/* We have now finished analyzing the shift. The result should be /* We have now finished analyzing the shift. The result should be
a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If
......
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