Re: [41/77] Split scalar integer handling out of force_to_mode

2017-08-16 Thread Jeff Law
On 07/13/2017 02:53 AM, Richard Sandiford wrote:
> force_to_mode exits partway through for modes that aren't scalar
> integers.  This patch splits the remainder of the function out
> into a subroutine, force_int_to_mode, so that the modes from that
> point on can have type scalar_int_mode.
> 
> The patch also makes sure that xmode is kept up-to-date with x
> and uses xmode instead of GET_MODE (x) throughout.
> 
> 2017-07-13  Richard Sandiford  
>   Alan Hayward  
>   David Sherwood  
> 
> gcc/
>   * combine.c (force_int_to_mode): New function, split out from...
>   (force_to_mode): ...here.  Keep xmode up-to-date and use it
>   instead of GET_MODE (x).
> 
OK.
jeff



[41/77] Split scalar integer handling out of force_to_mode

2017-07-13 Thread Richard Sandiford
force_to_mode exits partway through for modes that aren't scalar
integers.  This patch splits the remainder of the function out
into a subroutine, force_int_to_mode, so that the modes from that
point on can have type scalar_int_mode.

The patch also makes sure that xmode is kept up-to-date with x
and uses xmode instead of GET_MODE (x) throughout.

2017-07-13  Richard Sandiford  
Alan Hayward  
David Sherwood  

gcc/
* combine.c (force_int_to_mode): New function, split out from...
(force_to_mode): ...here.  Keep xmode up-to-date and use it
instead of GET_MODE (x).

Index: gcc/combine.c
===
--- gcc/combine.c   2017-07-13 09:18:42.160519154 +0100
+++ gcc/combine.c   2017-07-13 09:18:42.622481204 +0100
@@ -449,6 +449,8 @@ static rtx extract_left_shift (rtx, int)
 static int get_pos_from_mask (unsigned HOST_WIDE_INT,
  unsigned HOST_WIDE_INT *);
 static rtx canon_reg_for_combine (rtx, rtx);
+static rtx force_int_to_mode (rtx, scalar_int_mode, scalar_int_mode,
+ scalar_int_mode, unsigned HOST_WIDE_INT, int);
 static rtx force_to_mode (rtx, machine_mode,
  unsigned HOST_WIDE_INT, int);
 static rtx if_then_else_cond (rtx, rtx *, rtx *);
@@ -8517,8 +8519,7 @@ force_to_mode (rtx x, machine_mode mode,
   enum rtx_code code = GET_CODE (x);
   int next_select = just_select || code == XOR || code == NOT || code == NEG;
   machine_mode op_mode;
-  unsigned HOST_WIDE_INT fuller_mask, nonzero;
-  rtx op0, op1, temp;
+  unsigned HOST_WIDE_INT nonzero;
 
   /* If this is a CALL or ASM_OPERANDS, don't do anything.  Some of the
  code below will do the wrong thing since the mode of such an
@@ -8546,15 +8547,6 @@ force_to_mode (rtx x, machine_mode mode,
   if (op_mode)
 mask &= GET_MODE_MASK (op_mode);
 
-  /* When we have an arithmetic operation, or a shift whose count we
- do not know, we need to assume that all bits up to the highest-order
- bit in MASK will be needed.  This is how we form such a mask.  */
-  if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)))
-fuller_mask = HOST_WIDE_INT_M1U;
-  else
-fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1))
-  - 1);
-
   /* Determine what bits of X are guaranteed to be (non)zero.  */
   nonzero = nonzero_bits (x, mode);
 
@@ -8592,9 +8584,42 @@ force_to_mode (rtx x, machine_mode mode,
& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))
 return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
 
-  /* The arithmetic simplifications here only work for scalar integer modes.  
*/
-  if (!SCALAR_INT_MODE_P (mode) || !SCALAR_INT_MODE_P (GET_MODE (x)))
-return gen_lowpart_or_truncate (mode, x);
+  scalar_int_mode int_mode, xmode;
+  if (is_a  (mode, &int_mode)
+  && is_a  (GET_MODE (x), &xmode))
+/* OP_MODE is either MODE or XMODE, so it must be a scalar
+   integer too.  */
+return force_int_to_mode (x, int_mode, xmode,
+ as_a  (op_mode),
+ mask, just_select);
+
+  return gen_lowpart_or_truncate (mode, x);
+}
+
+/* Subroutine of force_to_mode that handles cases in which both X and
+   the result are scalar integers.  MODE is the mode of the result,
+   XMODE is the mode of X, and OP_MODE says which of MODE or XMODE
+   is preferred for simplified versions of X.  The other arguments
+   are as for force_to_mode.  */
+
+static rtx
+force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode,
+  scalar_int_mode op_mode, unsigned HOST_WIDE_INT mask,
+  int just_select)
+{
+  enum rtx_code code = GET_CODE (x);
+  int next_select = just_select || code == XOR || code == NOT || code == NEG;
+  unsigned HOST_WIDE_INT fuller_mask;
+  rtx op0, op1, temp;
+
+  /* When we have an arithmetic operation, or a shift whose count we
+ do not know, we need to assume that all bits up to the highest-order
+ bit in MASK will be needed.  This is how we form such a mask.  */
+  if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)))
+fuller_mask = HOST_WIDE_INT_M1U;
+  else
+fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1))
+  - 1);
 
   switch (code)
 {
@@ -8625,14 +8650,14 @@ force_to_mode (rtx x, machine_mode mode,
{
  x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
  mask & INTVAL (XEXP (x, 1)));
+ xmode = op_mode;
 
  /* If X is still an AND, see if it is an AND with a mask that
 is just some low-order bits.  If so, and it is MASK, we don't
 need it.  */
 
  if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))
- && ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x)))
- == mask))
+ && (INTVAL (XEXP (x, 1)) & G