[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.

From-SVN: r216996
This commit is contained in:
James Greenhalgh 2014-11-01 08:13:09 +00:00 committed by James Greenhalgh
parent 240decf782
commit 7cbed00872
9 changed files with 207 additions and 15 deletions

View 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

View 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

View 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})

View 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})

View 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
/* 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. */

View 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

View 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 */

View 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)
{

View 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);