From patchwork Fri Oct 31 15:08:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 405339 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 826A5140077 for ; Sat, 1 Nov 2014 02:08:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; q=dns; s=default; b=wRVEkqp9TIRKAaJV PpnJTGhvd1mEZJ2fArRxGKsalbNONZ7bKIe8odQmJplefsX6iKarQsYBSNnzvtag KTOSlrLVerTD/dSFIznKXm3x48nZgJ2vojUQGr9RaWgwPWSg/QMfYwozhijZn9AA ATsC0k5WX45XfpFwGjzr+cH4iHI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=default; bh=K0Zl1RaLBlHgleXQnqSczY aJUG4=; b=dMVVEbAsA6JcJ3Tk2jkePOEGt14czfQt9YHtEIbw87JblEjsgMdfs/ 5MaYTjhmYYvvlsCDrNZv9TDGGlFxIvOrScfsyhJ3XEq8Y3sYbuYNIt/pKiT3tmZw KAqNxzFs5QN7qa3ozeUeucjSU5JrkdC3qQqAT+KCjOGEMdyQkfoJ0= Received: (qmail 24317 invoked by alias); 31 Oct 2014 15:08:41 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 24242 invoked by uid 89); 31 Oct 2014 15:08:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: service87.mimecast.com Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 31 Oct 2014 15:08:37 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Fri, 31 Oct 2014 15:08:33 +0000 Received: from e106375-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 31 Oct 2014 15:08:33 +0000 From: James Greenhalgh To: gcc-patches@gcc.gnu.org Cc: richard.guenther@gmail.com, stevenb.gcc@gmail.com, law@redhat.com, matthew.fortune@imgtec.com Subject: [Patch 1/7] Hookize *_BY_PIECES_P Date: Fri, 31 Oct 2014 15:08:20 +0000 Message-Id: <1414768100-27840-2-git-send-email-james.greenhalgh@arm.com> In-Reply-To: <1414768100-27840-1-git-send-email-james.greenhalgh@arm.com> References: <20141029153153.GA26747@arm.com> <1414768100-27840-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-MC-Unique: 114103115083311001 X-IsSubscribed: yes Hi, This patch prepares for removing all the *BY_PIECES_P macros by introducing a new target hook TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. Tested on ARM/AArch64/x86_64 with no issues. Ok for trunk? Thanks, James --- gcc/ 2014-10-31 James Greenhalgh * 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. diff --git a/gcc/defaults.h b/gcc/defaults.h index c1776b0..d2609e7 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 bb04401..cfb8388 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 aa19360..3f66543 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 9b81e62..ef85177 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 14e19e8..23cae25 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 7be94b8..40d7841 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 e482991..eef3d45 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 25f4fed..4bbf492 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);