This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add new target-hook truncated_to_mode


This patch adds a new target hook, truncated_to_mode.  Currently,
aside from some very special cases we cannot optimize TRUNCATEs for
!TRULY_NOOP_TRUNCATION targets because the semantics of the operation
is target-specific and is not exposed to the middle-end.  With this
new target-hook the backend can specify when a TRUNCATE operation can
be replaced with a SUBREG operation.

The patch includes the definition for MIPS64 where 32-bit operations
require their operands to be sign-extended.

I thought about it for a while whether to make mips_truncated_to_mode
deal with any machine mode or not.  At the end I decided not to do
that.  The definition of TRUNCATE is only target-specific if
TRULY_NOOP_TRUNCATION returns zero for the corresponding modes and the
back-end should not be able to change the definition of TRUNCATE
otherwise.

Richard, This is the patch I was referring to that helps the first
testcase from http://gcc.gnu.org/ml/gcc-patches/2006-03/msg00593.html.

The difference of the generated assembly for gcc.c-torture/execute
before and after the patch is:

 43 files changed, 2005 insertions(+), 2544 deletions(-)

Out of which 464 are removed truncations (sll X,X,0).

Bootstrapped and tested on i686-pc-linux-gnu and tested on
mipsisa64-elf.  The documentation change was tested with make dvi.

OK to apply?

Adam

	* target.h (struct gcc_target): Add truncated_to_mode.
	* rtlanal.c (truncated_to_mode): Use it.
	* target-def.h (TARGET_TRUNCATED_TO_MODE): New macro.  Default it.
	(TARGET_INITIALIZER): Include it.
	* doc/tm.texi (Misc): Document it.
	* config/mips/mips.c (TARGET_TRUNCATED_TO_MODE): Override it.
	(mips_truncated_to_mode): New function.

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 111596)
+++ doc/tm.texi	(working copy)
@@ -9063,6 +9063,13 @@ If this is the case, making @code{TRULY_
 such cases may improve things.
 @end defmac
 
+@deftypefn {Target Hook} bool TARGET_TRUNCATED_TO_MODE (enum machine_mode @var{mode}, rtx @var{x})
+If @var{x} is already truncated it might be safe to operate on it in
+@var{mode} even though @code{TRULY_NOOP_TRUNCATION} returns 0 for the
+corresponding precisions.  This target hook should return true in this
+case.  The default implementation always returns false.
+@end deftypefn
+
 @defmac STORE_FLAG_VALUE
 A C expression describing the value returned by a comparison operator
 with an integral mode and stored by a store-flag instruction
Index: target.h
===================================================================
--- target.h	(revision 111596)
+++ target.h	(working copy)
@@ -462,6 +462,11 @@ struct gcc_target
      the reciprocal.  */
   unsigned int (* min_divisions_for_recip_mul) (enum machine_mode mode);
 
+  /* In general, truncating from mode of X to MODE would require
+     explicit truncation according to TRULY_NOOP_TRUNCATION.  Return
+     true if X is already suitable for MODE.  */
+  bool (* truncated_to_mode) (enum machine_mode mode, rtx x);
+
   /* True if MODE is valid for a pointer in __attribute__((mode("MODE"))).  */
   bool (* valid_pointer_mode) (enum machine_mode mode);
 
Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 111596)
+++ rtlanal.c	(working copy)
@@ -4815,7 +4815,8 @@ get_condition (rtx jump, rtx *earliest, 
 bool
 truncated_to_mode (enum machine_mode mode, rtx x)
 {
-  return REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x);
+  return ((REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x))
+	  || targetm.truncated_to_mode (mode, x));
 }
 
 
Index: target-def.h
===================================================================
--- target-def.h	(revision 111596)
+++ target-def.h	(working copy)
@@ -354,6 +354,10 @@ Foundation, 51 Franklin Street, Fifth Fl
 #define TARGET_MIN_DIVISIONS_FOR_RECIP_MUL default_min_divisions_for_recip_mul
 #endif
 
+#ifndef TARGET_TRUNCATED_TO_MODE
+#define TARGET_TRUNCATED_TO_MODE hook_bool_mode_rtx_false
+#endif
+
 #ifndef TARGET_VALID_POINTER_MODE
 #define TARGET_VALID_POINTER_MODE default_valid_pointer_mode
 #endif
@@ -616,6 +620,7 @@ Foundation, 51 Franklin Street, Fifth Fl
   TARGET_STRIP_NAME_ENCODING,			\
   TARGET_SHIFT_TRUNCATION_MASK,			\
   TARGET_MIN_DIVISIONS_FOR_RECIP_MUL,		\
+  TARGET_TRUNCATED_TO_MODE,			\
   TARGET_VALID_POINTER_MODE,                    \
   TARGET_SCALAR_MODE_SUPPORTED_P,		\
   TARGET_VECTOR_MODE_SUPPORTED_P,               \
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 111596)
+++ config/mips/mips.c	(working copy)
@@ -409,6 +409,7 @@ static rtx mips_expand_builtin_compare (
 static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
 static void mips_encode_section_info (tree, rtx, int);
 static void mips_extra_live_on_entry (bitmap);
+static bool mips_truncated_to_mode (enum machine_mode, rtx);
 
 /* Structure to be filled in by compute_frame_size with register
    save masks, and offsets for the current function.  */
@@ -1142,6 +1143,9 @@ static struct mips_rtx_cost_data const m
 #undef TARGET_ARG_PARTIAL_BYTES
 #define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
 
+#undef TARGET_TRUNCATED_TO_MODE
+#define TARGET_TRUNCATED_TO_MODE mips_truncated_to_mode
+
 #undef TARGET_VECTOR_MODE_SUPPORTED_P
 #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
 
@@ -10783,5 +10787,17 @@ mips_extra_live_on_entry (bitmap regs)
     bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);
 }
 
+/* Explicit truncation ensures that in 64-bit mode SImode or smaller
+   values have identical upper 33 bits.  */
+
+static bool
+mips_truncated_to_mode (enum machine_mode mode, rtx x)
+{
+  gcc_assert (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+				      GET_MODE_BITSIZE (GET_MODE (x)))
+	      && GET_MODE (x) == DImode);
+
+  return num_sign_bit_copies (x, GET_MODE (x)) >= 33;
+}
 
 #include "gt-mips.h"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]