rtl.h (truncated_to_mode): Declare it.
authorPaolo Bonzini <bonzini@gnu.org>
Tue, 28 Feb 2006 20:32:20 +0000 (20:32 +0000)
committerAdam Nemet <nemet@gcc.gnu.org>
Tue, 28 Feb 2006 20:32:20 +0000 (20:32 +0000)
* rtl.h (truncated_to_mode): Declare it.
(struct rtl_hooks): Add reg_truncated_to_mode hook.
* rtlhooks-def.h (RTL_HOOKS_REG_TRUNCATED_TO_MODE): New macro.
(RTL_HOOKS_INITIALIZER): Include it.
* rtlhooks.c (reg_truncated_to_mode_general): New function.
* combine.c (RTL_HOOKS_REG_TRUNCATED_TO_MODE): Override to
reg_truncated_to_mode.
* rtlanal.c (truncated_to_mode): Define it.
* simplify-rtx.c (simplify_unary_operation_1): Use it.

Co-Authored-By: Adam Nemet <anemet@caviumnetworks.com>
From-SVN: r111573

gcc/ChangeLog
gcc/combine.c
gcc/rtl.h
gcc/rtlanal.c
gcc/rtlhooks-def.h
gcc/rtlhooks.c
gcc/simplify-rtx.c

index 7ba31346670429aa8907f6bfb5c158426db4d605..d37067c114234c635a980c48f288896d412b3c9a 100644 (file)
@@ -1,3 +1,16 @@
+2006-02-28  Paolo Bonzini  <bonzini@gnu.org>
+           Adam Nemet  <anemet@caviumnetworks.com>
+
+       * rtl.h (truncated_to_mode): Declare it.
+       (struct rtl_hooks): Add reg_truncated_to_mode hook.
+       * rtlhooks-def.h (RTL_HOOKS_REG_TRUNCATED_TO_MODE): New macro.
+       (RTL_HOOKS_INITIALIZER): Include it.
+       * rtlhooks.c (reg_truncated_to_mode_general): New function.
+       * combine.c (RTL_HOOKS_REG_TRUNCATED_TO_MODE): Override to
+       reg_truncated_to_mode.
+       * rtlanal.c (truncated_to_mode): Define it.
+       * simplify-rtx.c (simplify_unary_operation_1): Use it.
+
 2006-02-28  Jeff Law  <law@redhat.com>
 
        * tree-chrec.c (chrec_convert_aggressive): Do not eliminate
index 443b429976eeac0de3af43770550d0210b617fa8..32d3f67df4fc2d5c6f38be9ec9f3fbfbd50a718a 100644 (file)
@@ -457,6 +457,9 @@ static rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
 #undef RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES
 #define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES  reg_num_sign_bit_copies_for_combine
 
+#undef RTL_HOOKS_REG_TRUNCATED_TO_MODE
+#define RTL_HOOKS_REG_TRUNCATED_TO_MODE    reg_truncated_to_mode
+
 static const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER;
 
 \f
index 6e17a224621a6996e70c86a1cd323008d2b1d4ae..9c088e92598d90875b91616d2669258485f0bed3 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1047,6 +1047,7 @@ extern unsigned int subreg_regno (rtx);
 extern unsigned HOST_WIDE_INT nonzero_bits (rtx, enum machine_mode);
 extern unsigned int num_sign_bit_copies (rtx, enum machine_mode);
 extern bool constant_pool_constant_p (rtx);
+extern bool truncated_to_mode (enum machine_mode, rtx);
 
 
 /* 1 if RTX is a subreg containing a reg that is already known to be
@@ -2277,8 +2278,9 @@ struct rtl_hooks
                           unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT *);
   rtx (*reg_num_sign_bit_copies) (rtx, enum machine_mode, rtx, enum machine_mode,
                                  unsigned int, unsigned int *);
+  bool (*reg_truncated_to_mode) (enum machine_mode, rtx);
 
-  /* Whenever you add entries here, make sure you adjust hosthooks-def.h.  */
+  /* Whenever you add entries here, make sure you adjust rtlhooks-def.h.  */
 };
 
 /* Each pass can provide its own.  */
index d8c9fb8a1bf35756b86352d1d92553641f4c42af..bbf7e71bf736349f9dc4812a0675eee14a703913 100644 (file)
@@ -4808,6 +4808,16 @@ get_condition (rtx jump, rtx *earliest, int allow_cc_mode, int valid_at_insn_p)
                                 allow_cc_mode, valid_at_insn_p);
 }
 
+/* Suppose that truncation from the machine mode of X to MODE is not a
+   no-op.  See if there is anything special about X so that we can
+   assume it already contains a truncated value of MODE.  */
+
+bool
+truncated_to_mode (enum machine_mode mode, rtx x)
+{
+  return REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x);
+}
+
 \f
 /* Initialize non_rtx_starting_operands, which is used to speed up
    for_each_rtx.  */
index b6c07fb76c1b6294a7d82866414fa8532564bcd7..748666c2dd0d9d498bea22cc1f8349b5722f2a9a 100644 (file)
@@ -27,6 +27,7 @@ Boston, MA 02110-1301, USA.  */
 #define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_no_emit_general
 #define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_general
 #define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_general
+#define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode_general
 
 /* The structure is defined in rtl.h.  */
 #define RTL_HOOKS_INITIALIZER {                        \
@@ -34,6 +35,7 @@ Boston, MA 02110-1301, USA.  */
   RTL_HOOKS_GEN_LOWPART_NO_EMIT,               \
   RTL_HOOKS_REG_NONZERO_REG_BITS,              \
   RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES,           \
+  RTL_HOOKS_REG_TRUNCATED_TO_MODE,             \
 }
 
 extern rtx gen_lowpart_general (enum machine_mode, rtx);
@@ -45,5 +47,6 @@ extern rtx reg_nonzero_bits_general (rtx, enum machine_mode, rtx,
 extern rtx reg_num_sign_bit_copies_general (rtx, enum machine_mode, rtx,
                                            enum machine_mode,
                                            unsigned int, unsigned int *);
+extern bool reg_truncated_to_mode_general (enum machine_mode, rtx);
 
 #endif /* GCC_RTL_HOOKS_DEF_H */
index 0034da783fac85b882f5919e6d169be71cbebcaf..ece7198f9a2fc1a12130cfa7b104304a716131ca 100644 (file)
@@ -117,6 +117,13 @@ reg_nonzero_bits_general (rtx x ATTRIBUTE_UNUSED,
   return NULL;
 }
 
+bool
+reg_truncated_to_mode_general (enum machine_mode mode ATTRIBUTE_UNUSED,
+                              rtx x ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point
    number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
    least-significant part of X.
index e84beda68b47f27128efb2b077498ac600879c53..aded68e52df9943dc33ed5a705e8f73e0bafa4a4 100644 (file)
@@ -631,14 +631,17 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
                                   GET_MODE (XEXP (SUBREG_REG (op), 0)));
 
       /* If we know that the value is already truncated, we can
-         replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION
-         is nonzero for the corresponding modes.  But don't do this
-         for an (LSHIFTRT (MULT ...)) since this will cause problems
-         with the umulXi3_highpart patterns.  */
-      if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+         replace the TRUNCATE with a SUBREG.  Note that this is also
+         valid if TRULY_NOOP_TRUNCATION is false for the corresponding
+         modes we just have to apply a different definition for
+         truncation.  But don't do this for an (LSHIFTRT (MULT ...)) 
+         since this will cause problems with the umulXi3_highpart
+         patterns.  */
+      if ((TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
                                 GET_MODE_BITSIZE (GET_MODE (op)))
-         && num_sign_bit_copies (op, GET_MODE (op))
-            >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1)
+          ? (num_sign_bit_copies (op, GET_MODE (op))
+             >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1))
+          : truncated_to_mode (mode, op))
          && ! (GET_CODE (op) == LSHIFTRT
                && GET_CODE (XEXP (op, 0)) == MULT))
        return rtl_hooks.gen_lowpart_no_emit (mode, op);