mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-21 14:41:07 +08:00
[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:
parent
240decf782
commit
7cbed00872
@ -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
|
||||
|
@ -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
|
||||
|
@ -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})
|
||||
|
@ -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})
|
||||
|
23
gcc/expr.c
23
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. */
|
||||
|
@ -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
|
||||
|
11
gcc/target.h
11
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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user