rtlanal.c (commutative_operand_precedence): Correct comments.
authorAlan Modra <amodra@gmail.com>
Tue, 23 Jun 2015 01:05:04 +0000 (10:35 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Tue, 23 Jun 2015 01:05:04 +0000 (10:35 +0930)
* rtlanal.c (commutative_operand_precedence): Correct comments.
* simplify-rtx.c (simplify_plus_minus_op_data_cmp): Delete forward
declaration.  Return an int.  Distinguish REG,REG return from
others.
(struct simplify_plus_minus_op_data): Make local to function.
(simplify_plus_minus): Don't set canonicalized if merely sorting
registers.  Avoid packing ops if nothing changes.  White space fixes.

From-SVN: r224768

gcc/ChangeLog
gcc/rtlanal.c
gcc/simplify-rtx.c

index e5a5764404b999286ea44d7a6a506a97244179e1..540685bc3765e98e9c2da588a35bdced163fca99 100644 (file)
@@ -1,3 +1,13 @@
+2015-06-23  Alan Modra  <amodra@gmail.com>
+
+       * rtlanal.c (commutative_operand_precedence): Correct comments.
+       * simplify-rtx.c (simplify_plus_minus_op_data_cmp): Delete forward
+       declaration.  Return an int.  Distinguish REG,REG return from
+       others.
+       (struct simplify_plus_minus_op_data): Make local to function.
+       (simplify_plus_minus): Don't set canonicalized if merely sorting
+       registers.  Avoid packing ops if nothing changes.  White space fixes.
+
 2015-06-22  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        * gcc.c (default_compilers): Pass "-o %g.s" to cc1 for headers even if
index d4a9eda26297b374b6bea7ff9d2f38e77873d029..86b3b622f89384afb3823b0215de9579da96d96b 100644 (file)
@@ -3132,17 +3132,16 @@ regno_use_in (unsigned int regno, rtx x)
 }
 
 /* Return a value indicating whether OP, an operand of a commutative
-   operation, is preferred as the first or second operand.  The higher
-   the value, the stronger the preference for being the first operand.
-   We use negative values to indicate a preference for the first operand
-   and positive values for the second operand.  */
+   operation, is preferred as the first or second operand.  The more
+   positive the value, the stronger the preference for being the first
+   operand.  */
 
 int
 commutative_operand_precedence (rtx op)
 {
   enum rtx_code code = GET_CODE (op);
 
-  /* Constants always come the second operand.  Prefer "nice" constants.  */
+  /* Constants always become the second operand.  Prefer "nice" constants.  */
   if (code == CONST_INT)
     return -8;
   if (code == CONST_WIDE_INT)
index 521fecf566e7e0ee04c0c343afa255a819ec5d70..ca8310d15563a05be41957df933e302928ba29e6 100644 (file)
@@ -59,7 +59,6 @@ along with GCC; see the file COPYING3.  If not see
 
 static rtx neg_const_int (machine_mode, const_rtx);
 static bool plus_minus_operand_p (const_rtx);
-static bool simplify_plus_minus_op_data_cmp (rtx, rtx);
 static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx);
 static rtx simplify_immed_subreg (machine_mode, rtx, machine_mode,
                                  unsigned int);
@@ -4049,20 +4048,10 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
 
 
 \f
-/* Simplify a PLUS or MINUS, at least one of whose operands may be another
-   PLUS or MINUS.
+/* Return a positive integer if X should sort after Y.  The value
+   returned is 1 if and only if X and Y are both regs.  */
 
-   Rather than test for specific case, we do this by a brute-force method
-   and do all possible simplifications until no more changes occur.  Then
-   we rebuild the operation.  */
-
-struct simplify_plus_minus_op_data
-{
-  rtx op;
-  short neg;
-};
-
-static bool
+static int
 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
 {
   int result;
@@ -4070,20 +4059,33 @@ simplify_plus_minus_op_data_cmp (rtx x, rtx y)
   result = (commutative_operand_precedence (y)
            - commutative_operand_precedence (x));
   if (result)
-    return result > 0;
+    return result + result;
 
   /* Group together equal REGs to do more simplification.  */
   if (REG_P (x) && REG_P (y))
     return REGNO (x) > REGNO (y);
-  else
-    return false;
+
+  return 0;
 }
 
+/* Simplify and canonicalize a PLUS or MINUS, at least one of whose
+   operands may be another PLUS or MINUS.
+
+   Rather than test for specific case, we do this by a brute-force method
+   and do all possible simplifications until no more changes occur.  Then
+   we rebuild the operation.
+
+   May return NULL_RTX when no changes were made.  */
+
 static rtx
 simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
                     rtx op1)
 {
-  struct simplify_plus_minus_op_data ops[16];
+  struct simplify_plus_minus_op_data
+  {
+    rtx op;
+    short neg;
+  } ops[16];
   rtx result, tem;
   int n_ops = 2;
   int changed, n_constants, canonicalized = 0;
@@ -4124,7 +4126,18 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
 
              ops[i].op = XEXP (this_op, 0);
              changed = 1;
-             canonicalized |= this_neg || i != n_ops - 2;
+             /* If this operand was negated then we will potentially
+                canonicalize the expression.  Similarly if we don't
+                place the operands adjacent we're re-ordering the
+                expression and thus might be performing a
+                canonicalization.  Ignore register re-ordering.
+                ??? It might be better to shuffle the ops array here,
+                but then (plus (plus (A, B), plus (C, D))) wouldn't
+                be seen as non-canonical.  */
+             if (this_neg
+                 || (i != n_ops - 2
+                     && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
+               canonicalized = 1;
              break;
 
            case NEG:
@@ -4145,7 +4158,7 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
                  ops[n_ops].neg = this_neg;
                  n_ops++;
                  changed = 1;
-                 canonicalized = 1;
+                 canonicalized = 1;
                }
              break;
 
@@ -4158,7 +4171,7 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
                  ops[i].op = XEXP (this_op, 0);
                  ops[i].neg = !this_neg;
                  changed = 1;
-                 canonicalized = 1;
+                 canonicalized = 1;
                }
              break;
 
@@ -4169,7 +4182,7 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
                  ops[i].op = neg_const_int (mode, this_op);
                  ops[i].neg = 0;
                  changed = 1;
-                 canonicalized = 1;
+                 canonicalized = 1;
                }
              break;
 
@@ -4213,23 +4226,29 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
     }
 
   /* Now simplify each pair of operands until nothing changes.  */
-  do
+  while (1)
     {
       /* Insertion sort is good enough for a small array.  */
       for (i = 1; i < n_ops; i++)
-        {
-          struct simplify_plus_minus_op_data save;
-          j = i - 1;
-          if (!simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op))
+       {
+         struct simplify_plus_minus_op_data save;
+         int cmp;
+
+         j = i - 1;
+         cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
+         if (cmp <= 0)
            continue;
+         /* Just swapping registers doesn't count as canonicalization.  */
+         if (cmp != 1)
+           canonicalized = 1;
 
-          canonicalized = 1;
-          save = ops[i];
-          do
+         save = ops[i];
+         do
            ops[j + 1] = ops[j];
-          while (j-- && simplify_plus_minus_op_data_cmp (ops[j].op, save.op));
-          ops[j + 1] = save;
-        }
+         while (j--
+                && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
+         ops[j + 1] = save;
+       }
 
       changed = 0;
       for (i = n_ops - 1; i > 0; i--)
@@ -4258,7 +4277,8 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
 
                    tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
                    tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
-                   tem = simplify_binary_operation (ncode, mode, tem_lhs, tem_rhs);
+                   tem = simplify_binary_operation (ncode, mode, tem_lhs,
+                                                    tem_rhs);
 
                    if (tem && !CONSTANT_P (tem))
                      tem = gen_rtx_CONST (GET_MODE (tem), tem);
@@ -4296,20 +4316,22 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
              }
          }
 
-      /* If nothing changed, fail.  */
-      if (!canonicalized)
-        return NULL_RTX;
+      if (!changed)
+       break;
 
       /* Pack all the operands to the lower-numbered entries.  */
       for (i = 0, j = 0; j < n_ops; j++)
-        if (ops[j].op)
-          {
+       if (ops[j].op)
+         {
            ops[i] = ops[j];
            i++;
-          }
+         }
       n_ops = i;
     }
-  while (changed);
+
+  /* If nothing changed, fail.  */
+  if (!canonicalized)
+    return NULL_RTX;
 
   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
   if (n_ops == 2