integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg.
authorJan Hubicka <jh@suse.cz>
Thu, 17 May 2001 21:21:21 +0000 (23:21 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 17 May 2001 21:21:21 +0000 (21:21 +0000)
* integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg.
(simplify_subreg): Handle complex types represented as CONCAT.

* recog.c (validate_replace_rtx_1): Properly canonicalize expression
* rtl.h (swap_commutative_operands_p): Declare.
* rtlanal.c (swap_commutative_operands_p): New.
(operand_preference): New static function.

* combine.c (combine_simplify_rtx): Use swap_commutative_operands_p.
(gen_binary): Likewise.
* optabs.c (emit_cmp_and_jump_insns, emit_conditional_move): Likewise.
* simplify-rtx.c (simplify_gen_binary,
simplify_gen_relational): Likewise.

From-SVN: r42224

gcc/ChangeLog
gcc/combine.c
gcc/emit-rtl.c
gcc/integrate.c
gcc/optabs.c
gcc/rtl.h
gcc/rtlanal.c
gcc/simplify-rtx.c

index b5be8d8..1bd75c2 100644 (file)
@@ -1,3 +1,19 @@
+Thu May 17 23:19:46 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg.
+       (simplify_subreg): Handle complex types represented as CONCAT.
+
+       * recog.c (validate_replace_rtx_1): Properly canonicalize expression
+       * rtl.h (swap_commutative_operands_p): Declare.
+       * rtlanal.c (swap_commutative_operands_p): New.
+       (operand_preference): New static function.
+
+       * combine.c (combine_simplify_rtx): Use swap_commutative_operands_p.
+       (gen_binary): Likewise.
+       * optabs.c (emit_cmp_and_jump_insns, emit_conditional_move): Likewise.
+       * simplify-rtx.c (simplify_gen_binary,
+       simplify_gen_relational): Likewise.
+
 Thu May 17 20:43:36 CEST 2001  Jan Hubicka  <jh@suse.cz>
 
        * cse.c (fold_rtx): Use simplify_subreg.
index 53df2f5..ceb6dc7 100644 (file)
@@ -3514,12 +3514,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
   /* If this is a commutative operation, put a constant last and a complex
      expression first.  We don't need to do this for comparisons here.  */
   if (GET_RTX_CLASS (code) == 'c'
-      && ((CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
-         || (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == 'o'
-             && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o')
-         || (GET_CODE (XEXP (x, 0)) == SUBREG
-             && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == 'o'
-             && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o')))
+      && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
     {
       temp = XEXP (x, 0);
       SUBST (XEXP (x, 0), XEXP (x, 1));
@@ -9818,12 +9813,7 @@ gen_binary (code, mode, op0, op1)
 
   /* Put complex operands first and constants second.  */
   if (GET_RTX_CLASS (code) == 'c'
-      && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
-         || (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
-             && GET_RTX_CLASS (GET_CODE (op1)) != 'o')
-         || (GET_CODE (op0) == SUBREG
-             && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
-             && GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
+      && swap_commutative_operands_p (op0, op1))
     return gen_rtx_fmt_ee (code, mode, op1, op0);
 
   /* If we are turning off bits already known off in OP0, we need not do
index b22e346..e1e26df 100644 (file)
@@ -1308,10 +1308,6 @@ int
 subreg_lowpart_p (x)
      rtx x;
 {
-  unsigned int offset = 0;
-  int difference = (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
-                   - GET_MODE_SIZE (GET_MODE (x)));
-
   if (GET_CODE (x) != SUBREG)
     return 1;
   else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
index 6795d82..29acaf2 100644 (file)
@@ -1902,35 +1902,9 @@ copy_rtx_and_substitute (orig, map, for_lhs)
 
     case SUBREG:
       copy = copy_rtx_and_substitute (SUBREG_REG (orig), map, for_lhs);
-      /* SUBREG is ordinary, but don't make nested SUBREGs.  */
-      if (GET_CODE (copy) == SUBREG)
-       {
-         int final_offset = SUBREG_BYTE (orig) + SUBREG_BYTE (copy);
-
-         /* When working with SUBREGs the rule is that the byte
-            offset must be a multiple of the SUBREG's mode.  */
-         final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig)));
-         final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig)));
-         return gen_rtx_SUBREG (GET_MODE (orig), SUBREG_REG (copy),
-                                final_offset);
-       }
-      else if (GET_CODE (copy) == CONCAT)
-       {
-         rtx retval = subreg_realpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1);
-         int final_offset;
-
-         if (GET_MODE (retval) == GET_MODE (orig))
-           return retval;
-         
-         final_offset = SUBREG_BYTE (orig) %
-                        GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (orig)));
-         final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig)));
-         final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig)));
-         return gen_rtx_SUBREG (GET_MODE (orig), retval, final_offset);
-       }
-      else
-       return gen_rtx_SUBREG (GET_MODE (orig), copy,
-                              SUBREG_BYTE (orig));
+      return simplify_gen_subreg (GET_MODE (orig), copy,
+                                 GET_MODE (SUBREG_REG (orig)),
+                                 SUBREG_BYTE (orig));
 
     case ADDRESSOF:
       copy = gen_rtx_ADDRESSOF (mode,
index c28b4d9..a2a42c6 100644 (file)
@@ -3290,8 +3290,7 @@ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
   rtx op0;
   rtx op1;
          
-  if ((CONSTANT_P (x) && ! CONSTANT_P (y))
-      || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
+  if (swap_commutative_operands_p (x, y))
     {
       /* Swap operands and condition to ensure canonical RTL.  */
       op0 = y;
@@ -3609,12 +3608,12 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
 {
   rtx tem, subtarget, comparison, insn;
   enum insn_code icode;
+  enum rtx_code reversed;
 
   /* If one operand is constant, make it the second one.  Only do this
      if the other operand is not constant as well.  */
 
-  if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
-      || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
+  if (swap_commutative_operands_p (op0, op1))
     {
       tem = op0;
       op0 = op1;
@@ -3633,16 +3632,14 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
   if (cmode == VOIDmode)
     cmode = GET_MODE (op0);
 
-  if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
-       || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
-      && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
-         || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 
-         || flag_unsafe_math_optimizations))
+  if (swap_commutative_operands_p (op2, op3)
+      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
+          != UNKNOWN))
     {
       tem = op2;
       op2 = op3;
       op3 = tem;
-      code = reverse_condition (code);
+      code = reversed;
     }
 
   if (mode == VOIDmode)
index 7ba5440..44c61ef 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1370,6 +1370,7 @@ extern int reg_used_between_p             PARAMS ((rtx, rtx, rtx));
 extern int reg_referenced_between_p    PARAMS ((rtx, rtx, rtx));
 extern int reg_set_between_p           PARAMS ((rtx, rtx, rtx));
 extern int regs_set_between_p          PARAMS ((rtx, rtx, rtx));
+extern int swap_commutative_operands_p PARAMS ((rtx, rtx));
 extern int modified_between_p          PARAMS ((rtx, rtx, rtx));
 extern int no_labels_between_p         PARAMS ((rtx, rtx));
 extern int no_jumps_between_p          PARAMS ((rtx, rtx));
index b0e2f4e..af0f81f 100644 (file)
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA.  */
 static void set_of_1           PARAMS ((rtx, rtx, void *));
 static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
 static int computed_jump_p_1   PARAMS ((rtx));
+static int operand_preference  PARAMS ((rtx));
 
 /* Bit flags that specify the machine subtype we are compiling for.
    Bits are tested using macros TARGET_... defined in the tm.h file
@@ -2533,6 +2534,52 @@ regno_use_in (regno, x)
   return NULL_RTX;
 }
 
+/* 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.  */
+
+static int
+operand_preference (op)
+     rtx op;
+{
+  /* Constants always come the second operand.  Prefer "nice" constants.  */
+  if (GET_CODE (op) == CONST_INT)
+    return -4;
+  if (GET_CODE (op) == CONST_DOUBLE)
+    return -3;
+  if (CONSTANT_P (op))
+    return -2;
+
+  /* SUBREGs of objects should come second.  */
+  if (GET_CODE (op) == SUBREG
+      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op))) == 'o')
+    return -1;
+
+  /* If only one operand is a `neg', `not',
+    `mult', `plus', or `minus' expression, it will be the first
+    operand.  */
+  if (GET_CODE (op) == NEG || GET_CODE (op) == NOT
+      || GET_CODE (op) == MULT || GET_CODE (op) == PLUS
+      || GET_CODE (op) == MINUS)
+    return 2;
+
+  /* Complex expressions should be the first.  */
+  if (GET_RTX_CLASS (GET_CODE (op)) == 'o')
+    return 1;
+  return 0;
+}
+
+/* Return 1 iff it is neccesary to swap operands of commutative operation
+   in order to canonicalize expression.  */
+
+int
+swap_commutative_operands_p (x, y)
+     rtx x, y;
+{
+  return operand_preference (x) < operand_preference (y);
+}
 
 /* Return 1 if X is an autoincrement side effect and the register is
    not the stack pointer.  */
index a64b33e..e586b01 100644 (file)
@@ -113,12 +113,7 @@ simplify_gen_binary (code, mode, op0, op1)
 
   /* Put complex operands first and constants second if commutative.  */
   if (GET_RTX_CLASS (code) == 'c'
-      && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
-         || (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
-             && GET_RTX_CLASS (GET_CODE (op1)) != 'o')
-         || (GET_CODE (op0) == SUBREG
-             && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
-             && GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
+      && swap_commutative_operands_p (op0, op1))
     tem = op0, op0 = op1, op1 = tem;
 
   /* If this simplifies, do it.  */
@@ -194,12 +189,7 @@ simplify_gen_relational (code, mode, cmp_mode, op0, op1)
     return tem;
 
   /* Put complex operands first and constants second.  */
-  if ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
-      || (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
-         && GET_RTX_CLASS (GET_CODE (op1)) != 'o')
-      || (GET_CODE (op0) == SUBREG
-         && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
-         && GET_RTX_CLASS (GET_CODE (op1)) != 'o'))
+  if (swap_commutative_operands_p (op0, op1))
     tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
 
   return gen_rtx_fmt_ee (code, mode, op0, op1);
@@ -2212,6 +2202,9 @@ simplify_subreg (outermode, op, innermode, byte)
       || byte >= GET_MODE_SIZE (innermode))
     abort ();
 
+  if (outermode == innermode && !byte)
+    return op;
+
   /* Attempt to simplify constant to non-SUBREG expression.  */
   if (CONSTANT_P (op))
     {
@@ -2388,6 +2381,19 @@ simplify_subreg (outermode, op, innermode, byte)
       MEM_COPY_ATTRIBUTES (new, op);
       return new;
     }
+
+  /* Handle complex values represented as CONCAT
+     of real and imaginary part.  */
+  if (GET_CODE (op) == CONCAT)
+    {
+      int is_realpart = byte < GET_MODE_UNIT_SIZE (innermode) / 2;
+      rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
+      unsigned int final_offset;
+
+      final_offset = SUBREG_BYTE (op) % (GET_MODE_UNIT_SIZE (innermode) / 2);
+      return simplify_subreg (outermode, part, GET_MODE (part), final_offset);
+    }
+
   return NULL_RTX;
 }
 /* Make a SUBREG operation or equivalent if it folds.  */