summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-01 08:13:09 +0000
committerjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-01 08:13:09 +0000
commit0ec3791cc4bd4c2a78dc7a4fb4de992797ec095e (patch)
treec478897b6815f2a9b6b21d0aca73130690f0b5fd
parentaa975831372897ea35121b7b14d40572f4dbdb98 (diff)
downloadgcc-0ec3791cc4bd4c2a78dc7a4fb4de992797ec095e.tar.gz
[Patch 1/7] Hookize *_BY_PIECES_P
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
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/defaults.h9
-rw-r--r--gcc/doc/tm.texi46
-rw-r--r--gcc/doc/tm.texi.in14
-rw-r--r--gcc/expr.c23
-rw-r--r--gcc/target.def37
-rw-r--r--gcc/target.h11
-rw-r--r--gcc/targhooks.c55
-rw-r--r--gcc/targhooks.h5
9 files changed, 207 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a4d5b58adb4..7ed09eb093e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/defaults.h b/gcc/defaults.h
index c1776b05690..d2609e761c2 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -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
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index bb04401209a..cfb838897aa 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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})
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index aa19360d5b7..3f66543753f 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -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})
diff --git a/gcc/expr.c b/gcc/expr.c
index 9b81e628cb0..ef851777c47 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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
/* 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. */
diff --git a/gcc/target.def b/gcc/target.def
index 14e19e838a8..23cae25cafe 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -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
diff --git a/gcc/target.h b/gcc/target.h
index 7be94b82558..40d784164b8 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -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 */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index e482991d6eb..eef3d457b4e 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -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)
{
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 25f4feda940..4bbf49253b9 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -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);