rtlanal.c (find_reg_equal_equiv_note): New function.
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Tue, 13 Feb 2001 20:43:13 +0000 (20:43 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Tue, 13 Feb 2001 20:43:13 +0000 (15:43 -0500)
* rtlanal.c (find_reg_equal_equiv_note): New function.
* simplify-rtx.c (simplify_gen_unary, simplify_gen_ternary): New fns.
(simplify_gen_relational, simplify_replace_rtx): Likewise.
* rtl.h: Add declarations for above functions.

From-SVN: r39644

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

index f48ac5403e6ef4d707f44c816c6786f16ba9420f..ed6a413a3263bb34243c1e308f7ac7cfc640dfc5 100644 (file)
@@ -1,3 +1,10 @@
+Tue Feb 13 15:42:05 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       * rtlanal.c (find_reg_equal_equiv_note): New function.
+       * simplify-rtx.c (simplify_gen_unary, simplify_gen_ternary): New fns.
+       (simplify_gen_relational, simplify_replace_rtx): Likewise.
+       * rtl.h: Add declarations for above functions.
+
 Tue Feb 13 21:09:11 CET 2001  Jan Hubicka  <jh@suse.cz>
 
        * cse.c (cse_main): Converts ifdefs on PIC_OFFSET_TABLE_REGNUM to
index 003e92dc31664867d26ce9bc2de3baebf61f60b5..f6eb251d6ce546f77391d83ed18e47c5729a1e42 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1311,12 +1311,33 @@ extern rtx try_split                    PARAMS ((rtx, rtx, int));
 extern rtx split_insns                 PARAMS ((rtx, rtx));
 
 /* In simplify-rtx.c  */
-extern rtx simplify_unary_operation    PARAMS ((enum rtx_code, enum machine_mode, rtx, enum machine_mode));
-extern rtx simplify_binary_operation   PARAMS ((enum rtx_code, enum machine_mode, rtx, rtx));
-extern rtx simplify_ternary_operation  PARAMS ((enum rtx_code, enum machine_mode, enum machine_mode, rtx, rtx, rtx));
-extern rtx simplify_relational_operation PARAMS ((enum rtx_code, enum machine_mode, rtx, rtx));
-extern rtx simplify_gen_binary         PARAMS ((enum rtx_code, enum machine_mode,
-                                              rtx, rtx));
+extern rtx simplify_unary_operation    PARAMS ((enum rtx_code,
+                                                enum machine_mode, rtx,
+                                                enum machine_mode));
+extern rtx simplify_binary_operation   PARAMS ((enum rtx_code,
+                                                enum machine_mode, rtx,
+                                                rtx));
+extern rtx simplify_ternary_operation  PARAMS ((enum rtx_code,
+                                                enum machine_mode,
+                                                enum machine_mode, rtx, rtx,
+                                                rtx));
+extern rtx simplify_relational_operation PARAMS ((enum rtx_code,
+                                                 enum machine_mode, rtx,
+                                                 rtx));
+extern rtx simplify_gen_binary         PARAMS ((enum rtx_code,
+                                                enum machine_mode,
+                                                rtx, rtx));
+extern rtx simplify_gen_unary          PARAMS ((enum rtx_code,
+                                                enum machine_mode, rtx,
+                                                enum machine_mode));
+extern rtx simplify_gen_ternary                PARAMS ((enum rtx_code,
+                                                enum machine_mode,
+                                                enum machine_mode,
+                                                rtx, rtx, rtx));
+extern rtx simplify_gen_relational     PARAMS ((enum rtx_code,
+                                                enum machine_mode,
+                                                rtx, rtx));
+extern rtx simplify_replace_rtx                PARAMS ((rtx, rtx, rtx));
 extern rtx simplify_rtx                        PARAMS ((rtx));
 
 /* In optabs.c  */
@@ -1388,6 +1409,7 @@ extern int dead_or_set_regno_p            PARAMS ((rtx, unsigned int));
 extern rtx find_reg_note               PARAMS ((rtx, enum reg_note, rtx));
 extern rtx find_regno_note             PARAMS ((rtx, enum reg_note,
                                                 unsigned int));
+extern rtx find_reg_equal_equiv_note   PARAMS ((rtx));
 extern int find_reg_fusage             PARAMS ((rtx, enum rtx_code, rtx));
 extern int find_regno_fusage           PARAMS ((rtx, enum rtx_code,
                                                 unsigned int));
index a738acb28a592ac13a8ea0cf824d3625e8067c74..0eefa70da52f1ec23f26916b10815448aa0571dd 100644 (file)
@@ -1485,6 +1485,23 @@ find_regno_note (insn, kind, regno)
   return 0;
 }
 
+/* Return a REG_EQUIV or REG_EQUAL note if insn has only a single set and
+   has such a note.  */
+
+rtx
+find_reg_equal_equiv_note (insn)
+     rtx insn;
+{
+  rtx note;
+
+  if (single_set (insn) == 0)
+    return 0;
+  else if ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
+    return note;
+  else
+    return find_reg_note (insn, REG_EQUAL, NULL_RTX);
+}
+
 /* Return true if DATUM, or any overlap of DATUM, of kind CODE is found
    in the CALL_INSN_FUNCTION_USAGE information of INSN.  */
 
index fa3dfe17f0f4e1cfd0f0936cbbef7219d110340a..43d650c387db78fb0f9e897087c2c8cdbbe3fdab 100644 (file)
@@ -140,6 +140,128 @@ simplify_gen_binary (code, mode, op0, op1)
     return gen_rtx_fmt_ee (code, mode, op0, op1);
 }
 \f
+/* Make a unary operation by first seeing if it folds and otherwise making
+   the specified operation.  */
+
+rtx
+simplify_gen_unary (code, mode, op, op_mode)
+     enum rtx_code code;
+     enum machine_mode mode;
+     rtx op;
+     enum machine_mode op_mode;
+{
+  rtx tem;
+
+  /* If this simplifies, use it.  */
+  if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
+    return tem;
+
+  return gen_rtx_fmt_e (code, mode, op);
+}
+
+/* Likewise for ternary operations.  */
+
+rtx
+simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2)
+     enum rtx_code code;
+     enum machine_mode mode, op0_mode;
+     rtx op0, op1, op2;
+{
+  rtx tem;
+
+  /* If this simplifies, use it.  */
+  if (0 != (tem = simplify_ternary_operation (code, mode, op0_mode,
+                                             op0, op1, op2)))
+    return tem;
+
+  return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
+}
+\f
+/* Likewise, for relational operations.  */
+
+rtx
+simplify_gen_relational (code, mode, op0, op1)
+     enum rtx_code code;
+     enum machine_mode mode;
+     rtx op0, op1;
+{
+  rtx tem;
+
+  if ((tem = simplify_relational_operation (code, mode, op0, op1)) != 0)
+    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'))
+    tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
+
+  return gen_rtx_fmt_ee (code, mode, op0, op1);
+}
+\f
+/* Replace all occurrences of OLD in X with NEW and try to simplify the
+   resulting RTX.  Return a new RTX which is as simplified as possible.  */
+
+rtx
+simplify_replace_rtx (x, old, new)
+     rtx x;
+     rtx old;
+     rtx new;
+{
+  enum rtx_code code = GET_CODE (x);
+  enum machine_mode mode = GET_MODE (x);
+
+  /* If X is OLD, return NEW.  Otherwise, if this is an expression, try
+     to build a new expression substituting recursively.  If we can't do
+     anything, return our input.  */
+
+  if (x == old)
+    return new;
+
+  switch (GET_RTX_CLASS (code))
+    {
+    case '1':
+      {
+       enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
+       rtx op = (XEXP (x, 0) == old
+                 ? new : simplify_replace_rtx (XEXP (x, 0), old, new));
+
+       return simplify_gen_unary (code, mode, op, op_mode);
+      }
+
+    case '2':
+    case 'c':
+      return
+       simplify_gen_binary (code, mode,
+                            simplify_replace_rtx (XEXP (x, 0), old, new),
+                            simplify_replace_rtx (XEXP (x, 1), old, new));
+
+    case '3':
+    case 'b':
+      return
+       simplify_gen_ternary (code, mode, GET_MODE (XEXP (x, 0)),
+                             simplify_replace_rtx (XEXP (x, 0), old, new),
+                             simplify_replace_rtx (XEXP (x, 1), old, new),
+                             simplify_replace_rtx (XEXP (x, 2), old, new));
+
+    case 'x':
+      /* The only case we try to handle is a lowpart SUBREG of a single-word
+        CONST_INT.  */
+      if (code == SUBREG && subreg_lowpart_p (x) && old == SUBREG_REG (x)
+         && GET_CODE (new) == CONST_INT
+         && GET_MODE_SIZE (GET_MODE (old)) <= UNITS_PER_WORD)
+       return GEN_INT (INTVAL (new) & GET_MODE_MASK (mode));
+
+      return x;
+
+    default:
+      return x;
+    }
+}
+\f
 /* Try to simplify a unary operation CODE whose output mode is to be
    MODE with input operand OP whose mode was originally OP_MODE.
    Return zero if no simplification can be made.  */
@@ -2063,11 +2185,8 @@ rtx
 simplify_rtx (x)
      rtx x;
 {
-  enum rtx_code code;
-  enum machine_mode mode;
-
-  mode = GET_MODE (x);
-  code = GET_CODE (x);
+  enum rtx_code code = GET_CODE (x);
+  enum machine_mode mode = GET_MODE (x);
 
   switch (GET_RTX_CLASS (code))
     {
@@ -2081,11 +2200,13 @@ simplify_rtx (x)
     case '3':
     case 'b':
       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
-                                        XEXP (x, 0), XEXP (x, 1), XEXP (x, 2));
+                                        XEXP (x, 0), XEXP (x, 1),
+                                        XEXP (x, 2));
 
     case '<':
       return simplify_relational_operation (code,
-                                           (GET_MODE (XEXP (x, 0)) != VOIDmode
+                                           ((GET_MODE (XEXP (x, 0))
+                                             != VOIDmode)
                                             ? GET_MODE (XEXP (x, 0))
                                             : GET_MODE (XEXP (x, 1))),
                                            XEXP (x, 0), XEXP (x, 1));