[Patch 1/7] Hookize *_BY_PIECES_P
authorjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Nov 2014 08:13:09 +0000 (08:13 +0000)
committerjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Nov 2014 08:13:09 +0000 (08:13 +0000)
gcc/

* target.def (use_by_pieces_infrastructure_p): New.
* doc/tm.texi.in (MOVE_BY_PIECES_P): Describe that this macro
is deprecated.
(STORE_BY_PIECES_P): Likewise.
(CLEAR_BY_PIECES_P): Likewise.
(SET_BY_PIECES_P): Likewise.
(TARGET_MOVE_BY_PIECES_PROFITABLE_P): Add hook.
* doc/tm.texi: Regenerate.
* expr.c (MOVE_BY_PIECES_P): Rewrite in terms of
TARGET_USE_BY_PIECES_INFRASTRUCTURE_P.
(STORE_BY_PIECES_P): Likewise.
(CLEAR_BY_PIECES_P): Likewise.
(SET_BY_PIECES_P): Likewise.
(STORE_MAX_PIECES): Move to...
* defaults.h (STORE_MAX_PIECES): ...here.
* targhooks.c (get_move_ratio): New.
(default_use_by_pieces_infrastructure_p): Likewise.
* targhooks.h (default_use_by_pieces_infrastructure_p): New.
* target.h (by_pieces_operation): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216996 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/defaults.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/expr.c
gcc/target.def
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h

index a4d5b58..7ed09eb 100644 (file)
@@ -1,3 +1,25 @@
+2014-11-01  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       * target.def (use_by_pieces_infrastructure_p): New.
+       * doc/tm.texi.in (MOVE_BY_PIECES_P): Describe that this macro
+       is deprecated.
+       (STORE_BY_PIECES_P): Likewise.
+       (CLEAR_BY_PIECES_P): Likewise.
+       (SET_BY_PIECES_P): Likewise.
+       (TARGET_MOVE_BY_PIECES_PROFITABLE_P): Add hook.
+       * doc/tm.texi: Regenerate.
+       * expr.c (MOVE_BY_PIECES_P): Rewrite in terms of
+       TARGET_USE_BY_PIECES_INFRASTRUCTURE_P.
+       (STORE_BY_PIECES_P): Likewise.
+       (CLEAR_BY_PIECES_P): Likewise.
+       (SET_BY_PIECES_P): Likewise.
+       (STORE_MAX_PIECES): Move to...
+       * defaults.h (STORE_MAX_PIECES): ...here.
+       * targhooks.c (get_move_ratio): New.
+       (default_use_by_pieces_infrastructure_p): Likewise.
+       * targhooks.h (default_use_by_pieces_infrastructure_p): New.
+       * target.h (by_pieces_operation): New.
+
 2014-10-31  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/63702
index c1776b0..d2609e7 100644 (file)
@@ -1006,6 +1006,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define MOVE_MAX_PIECES   MOVE_MAX
 #endif
 
+/* STORE_MAX_PIECES is the number of bytes at a time that we can
+   store efficiently.  Due to internal GCC limitations, this is
+   MOVE_MAX_PIECES limited by the number of bytes GCC can represent
+   for an immediate constant.  */
+
+#ifndef STORE_MAX_PIECES
+#define STORE_MAX_PIECES  MIN (MOVE_MAX_PIECES, 2 * sizeof (HOST_WIDE_INT))
+#endif
+
 #ifndef MAX_MOVE_MAX
 #define MAX_MOVE_MAX MOVE_MAX
 #endif
index bb04401..cfb8388 100644 (file)
@@ -6128,8 +6128,45 @@ A C expression used to determine whether @code{move_by_pieces} will be used to
 copy a chunk of memory, or whether some other block move mechanism
 will be used.  Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{MOVE_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
+@deftypefn {Target Hook} bool TARGET_USE_BY_PIECES_INFRASTRUCTURE_P (unsigned int @var{size}, unsigned int @var{alignment}, enum by_pieces_operation @var{op}, bool @var{speed_p})
+GCC will attempt several strategies when asked to copy between
+two areas of memory, or to set, clear or store to memory, for example
+when copying a @code{struct}. The @code{by_pieces} infrastructure
+implements such memory operations as a sequence of load, store or move
+insns.  Alternate strategies are to expand the
+@code{movmem} or @code{setmem} optabs, to emit a library call, or to emit
+unit-by-unit, loop-based operations.
+
+This target hook should return true if, for a memory operation with a
+given @var{size} and @var{alignment}, using the @code{by_pieces}
+infrastructure is expected to result in better code generation.
+Both @var{size} and @var{alignment} are measured in terms of storage
+units.
+
+The parameter @var{op} is one of: @code{CLEAR_BY_PIECES},
+@code{MOVE_BY_PIECES}, @code{SET_BY_PIECES}, @code{STORE_BY_PIECES}.
+These describe the type of memory operation under consideration.
+
+The parameter @var{speed_p} is true if the code is currently being
+optimized for speed rather than size.
+
+Returning true for higher values of @var{size} can improve code generation
+for speed if the target does not provide an implementation of the
+@code{movmem} or @code{setmem} standard names, if the @code{movmem} or
+@code{setmem} implementation would be more expensive than a sequence of
+insns, or if the overhead of a library call would dominate that of
+the body of the memory operation.
+
+Returning true for higher values of @code{size} may also cause an increase
+in code size, for example where the number of insns emitted to perform a
+move would be greater than that of a library call.
+@end deftypefn
+
 @defmac MOVE_MAX_PIECES
 A C expression used by @code{move_by_pieces} to determine the largest unit
 a load or store used to copy memory is.  Defaults to @code{MOVE_MAX}.
@@ -6152,6 +6189,9 @@ A C expression used to determine whether @code{clear_by_pieces} will be used
 to clear a chunk of memory, or whether some other block clear mechanism
 will be used.  Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{CLEAR_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
 @defmac SET_RATIO (@var{speed})
@@ -6174,6 +6214,9 @@ other mechanism will be used.  Used by @code{__builtin_memset} when
 storing values other than constant zero.
 Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{SET_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
 @defmac STORE_BY_PIECES_P (@var{size}, @var{alignment})
@@ -6183,6 +6226,9 @@ other mechanism will be used.  Used by @code{__builtin_strcpy} when
 called with a constant source string.
 Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{MOVE_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
 @defmac USE_LOAD_POST_INCREMENT (@var{mode})
index aa19360..3f66543 100644 (file)
@@ -4605,8 +4605,13 @@ A C expression used to determine whether @code{move_by_pieces} will be used to
 copy a chunk of memory, or whether some other block move mechanism
 will be used.  Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{MOVE_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
+@hook TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
+
 @defmac MOVE_MAX_PIECES
 A C expression used by @code{move_by_pieces} to determine the largest unit
 a load or store used to copy memory is.  Defaults to @code{MOVE_MAX}.
@@ -4629,6 +4634,9 @@ A C expression used to determine whether @code{clear_by_pieces} will be used
 to clear a chunk of memory, or whether some other block clear mechanism
 will be used.  Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{CLEAR_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
 @defmac SET_RATIO (@var{speed})
@@ -4651,6 +4659,9 @@ other mechanism will be used.  Used by @code{__builtin_memset} when
 storing values other than constant zero.
 Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{SET_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
 @defmac STORE_BY_PIECES_P (@var{size}, @var{alignment})
@@ -4660,6 +4671,9 @@ other mechanism will be used.  Used by @code{__builtin_strcpy} when
 called with a constant source string.
 Defaults to 1 if @code{move_by_pieces_ninsns} returns less
 than @code{MOVE_RATIO}.
+
+This macro is deprecated.  New ports should implement
+@code{TARGET_USE_BY_PIECES_INFRASTRUCTURE_P} instead.
 @end defmac
 
 @defmac USE_LOAD_POST_INCREMENT (@var{mode})
index 9b81e62..ef85177 100644 (file)
@@ -171,32 +171,32 @@ static void write_complex_part (rtx, rtx, bool);
    to perform a structure copy.  */
 #ifndef MOVE_BY_PIECES_P
 #define MOVE_BY_PIECES_P(SIZE, ALIGN) \
-  (move_by_pieces_ninsns (SIZE, ALIGN, MOVE_MAX_PIECES + 1) \
-   < (unsigned int) MOVE_RATIO (optimize_insn_for_speed_p ()))
+  (targetm.use_by_pieces_infrastructure_p (SIZE, ALIGN, MOVE_BY_PIECES, \
+                                          optimize_insn_for_speed_p ()))
 #endif
 
 /* This macro is used to determine whether clear_by_pieces should be
    called to clear storage.  */
 #ifndef CLEAR_BY_PIECES_P
 #define CLEAR_BY_PIECES_P(SIZE, ALIGN) \
-  (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
-   < (unsigned int) CLEAR_RATIO (optimize_insn_for_speed_p ()))
+  (targetm.use_by_pieces_infrastructure_p (SIZE, ALIGN, CLEAR_BY_PIECES, \
+                                          optimize_insn_for_speed_p ()))
 #endif
 
 /* This macro is used to determine whether store_by_pieces should be
    called to "memset" storage with byte values other than zero.  */
 #ifndef SET_BY_PIECES_P
 #define SET_BY_PIECES_P(SIZE, ALIGN) \
-  (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
-   < (unsigned int) SET_RATIO (optimize_insn_for_speed_p ()))
+  (targetm.use_by_pieces_infrastructure_p (SIZE, ALIGN, SET_BY_PIECES, \
+                                          optimize_insn_for_speed_p ()))
 #endif
 
 /* This macro is used to determine whether store_by_pieces should be
    called to "memcpy" storage when the source is a constant string.  */
 #ifndef STORE_BY_PIECES_P
 #define STORE_BY_PIECES_P(SIZE, ALIGN) \
-  (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
-   < (unsigned int) MOVE_RATIO (optimize_insn_for_speed_p ()))
+  (targetm.use_by_pieces_infrastructure_p (SIZE, ALIGN, STORE_BY_PIECES, \
+                                          optimize_insn_for_speed_p ()))
 #endif
 \f
 /* This is run to set up which modes can be used
@@ -827,13 +827,6 @@ widest_int_mode_for_size (unsigned int size)
   return mode;
 }
 
-/* STORE_MAX_PIECES is the number of bytes at a time that we can
-   store efficiently.  Due to internal GCC limitations, this is
-   MOVE_MAX_PIECES limited by the number of bytes GCC can represent
-   for an immediate constant.  */
-
-#define STORE_MAX_PIECES  MIN (MOVE_MAX_PIECES, 2 * sizeof (HOST_WIDE_INT))
-
 /* Determine whether the LEN bytes can be moved by using several move
    instructions.  Return nonzero if a call to move_by_pieces should
    succeed.  */
index 14e19e8..23cae25 100644 (file)
@@ -3049,6 +3049,43 @@ are the same as to this target hook.",
  int, (machine_mode mode, reg_class_t rclass, bool in),
  default_memory_move_cost)
 
+DEFHOOK
+(use_by_pieces_infrastructure_p,
+ "GCC will attempt several strategies when asked to copy between\n\
+two areas of memory, or to set, clear or store to memory, for example\n\
+when copying a @code{struct}. The @code{by_pieces} infrastructure\n\
+implements such memory operations as a sequence of load, store or move\n\
+insns.  Alternate strategies are to expand the\n\
+@code{movmem} or @code{setmem} optabs, to emit a library call, or to emit\n\
+unit-by-unit, loop-based operations.\n\
+\n\
+This target hook should return true if, for a memory operation with a\n\
+given @var{size} and @var{alignment}, using the @code{by_pieces}\n\
+infrastructure is expected to result in better code generation.\n\
+Both @var{size} and @var{alignment} are measured in terms of storage\n\
+units.\n\
+\n\
+The parameter @var{op} is one of: @code{CLEAR_BY_PIECES},\n\
+@code{MOVE_BY_PIECES}, @code{SET_BY_PIECES}, @code{STORE_BY_PIECES}.\n\
+These describe the type of memory operation under consideration.\n\
+\n\
+The parameter @var{speed_p} is true if the code is currently being\n\
+optimized for speed rather than size.\n\
+\n\
+Returning true for higher values of @var{size} can improve code generation\n\
+for speed if the target does not provide an implementation of the\n\
+@code{movmem} or @code{setmem} standard names, if the @code{movmem} or\n\
+@code{setmem} implementation would be more expensive than a sequence of\n\
+insns, or if the overhead of a library call would dominate that of\n\
+the body of the memory operation.\n\
+\n\
+Returning true for higher values of @code{size} may also cause an increase\n\
+in code size, for example where the number of insns emitted to perform a\n\
+move would be greater than that of a library call.",
+ bool, (unsigned int size, unsigned int alignment,
+        enum by_pieces_operation op, bool speed_p),
+ default_use_by_pieces_infrastructure_p)
+
 /* True for MODE if the target expects that registers in this mode will
    be allocated to registers in a small register class.  The compiler is
    allowed to use registers explicitly used in the rtl as spill registers
index 7be94b8..40d7841 100644 (file)
@@ -80,6 +80,17 @@ enum print_switch_type
   SWITCH_TYPE_LINE_END         /* Please emit a line terminator.  */
 };
 
+/* Types of memory operation understood by the "by_pieces" infrastructure.
+   Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook.  */
+
+enum by_pieces_operation
+{
+  CLEAR_BY_PIECES,
+  MOVE_BY_PIECES,
+  SET_BY_PIECES,
+  STORE_BY_PIECES
+};
+
 typedef int (* print_switch_fn_type) (print_switch_type, const char *);
 
 /* An example implementation for ELF targets.  Defined in varasm.c  */
index e482991..eef3d45 100644 (file)
@@ -1406,6 +1406,61 @@ default_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
 #endif
 }
 
+/* For hooks which use the MOVE_RATIO macro, this gives the legacy default
+   behaviour.  SPEED_P is true if we are compiling for speed.  */
+
+static unsigned int
+get_move_ratio (bool speed_p ATTRIBUTE_UNUSED)
+{
+  unsigned int move_ratio;
+#ifdef MOVE_RATIO
+  move_ratio = (unsigned int) MOVE_RATIO (speed_p);
+#else
+#if defined (HAVE_movmemqi) || defined (HAVE_movmemhi) || defined (HAVE_movmemsi) || defined (HAVE_movmemdi) || defined (HAVE_movmemti)
+  move_ratio = 2;
+#else /* No movmem patterns, pick a default.  */
+  move_ratio = ((speed_p) ? 15 : 3);
+#endif
+#endif
+  return move_ratio;
+}
+
+/* Return TRUE if the move_by_pieces/set_by_pieces infrastructure should be
+   used; return FALSE if the movmem/setmem optab should be expanded, or
+   a call to memcpy emitted.  */
+
+bool
+default_use_by_pieces_infrastructure_p (unsigned int size,
+                                       unsigned int alignment,
+                                       enum by_pieces_operation op,
+                                       bool speed_p)
+{
+  unsigned int max_size = 0;
+  unsigned int ratio = 0;
+
+  switch (op)
+    {
+      case CLEAR_BY_PIECES:
+       max_size = STORE_MAX_PIECES;
+       ratio = CLEAR_RATIO (speed_p);
+       break;
+      case MOVE_BY_PIECES:
+       max_size = MOVE_MAX_PIECES;
+       ratio = get_move_ratio (speed_p);
+       break;
+      case SET_BY_PIECES:
+       max_size = STORE_MAX_PIECES;
+       ratio = SET_RATIO (speed_p);
+       break;
+      case STORE_BY_PIECES:
+       max_size = STORE_MAX_PIECES;
+       ratio = get_move_ratio (speed_p);
+       break;
+    }
+
+  return move_by_pieces_ninsns (size, alignment, max_size + 1) < ratio;
+}
+
 bool
 default_profile_before_prologue (void)
 {
index 25f4fed..4bbf492 100644 (file)
@@ -181,6 +181,11 @@ extern int default_memory_move_cost (machine_mode, reg_class_t, bool);
 extern int default_register_move_cost (machine_mode, reg_class_t,
                                       reg_class_t);
 
+extern bool default_use_by_pieces_infrastructure_p (unsigned int,
+                                                   unsigned int,
+                                                   enum by_pieces_operation,
+                                                   bool);
+
 extern bool default_profile_before_prologue (void);
 extern reg_class_t default_preferred_reload_class (rtx, reg_class_t);
 extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t);