aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorAaron Sawdey <acsawdey@linux.ibm.com>2019-10-02 14:23:51 +0000
committerAaron Sawdey <acsawdey@gcc.gnu.org>2019-10-02 09:23:51 -0500
commit03a9b90aa6df28dde083efd17e8b7ae76b943fe7 (patch)
treecf2c7debb8c890c231f2b9b46d142d78e10e2f4c /gcc/builtins.c
parent629387a6586a753166f5cf53d587026a34362523 (diff)
downloadgcc-03a9b90aa6df28dde083efd17e8b7ae76b943fe7.zip
gcc-03a9b90aa6df28dde083efd17e8b7ae76b943fe7.tar.gz
gcc-03a9b90aa6df28dde083efd17e8b7ae76b943fe7.tar.bz2
builtins.c (expand_builtin_memory_copy_args): Add might_overlap parm.
2019-10-02 Aaron Sawdey <acsawdey@linux.ibm.com> * builtins.c (expand_builtin_memory_copy_args): Add might_overlap parm. (expand_builtin_memcpy): Use might_overlap parm. (expand_builtin_mempcpy_args): Use might_overlap parm. (expand_builtin_memmove): Call expand_builtin_memory_copy_args. (expand_builtin_memory_copy_args): Add might_overlap parm. * expr.c (emit_block_move_via_cpymem): Rename to emit_block_move_via_pattern, add might_overlap parm, use cpymem or movmem optab as appropriate. (emit_block_move_hints): Add might_overlap parm, do the right thing for might_overlap==true. * expr.h (emit_block_move_hints): Update prototype. From-SVN: r276461
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1fd4b88..fa17afd 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -127,7 +127,8 @@ static rtx expand_builtin_memchr (tree, rtx);
static rtx expand_builtin_memcpy (tree, rtx);
static rtx expand_builtin_memory_copy_args (tree dest, tree src, tree len,
rtx target, tree exp,
- memop_ret retmode);
+ memop_ret retmode,
+ bool might_overlap);
static rtx expand_builtin_memmove (tree, rtx);
static rtx expand_builtin_mempcpy (tree, rtx);
static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, tree, memop_ret);
@@ -3790,14 +3791,14 @@ expand_builtin_memcpy (tree exp, rtx target)
check_memop_access (exp, dest, src, len);
return expand_builtin_memory_copy_args (dest, src, len, target, exp,
- /*retmode=*/ RETURN_BEGIN);
+ /*retmode=*/ RETURN_BEGIN, false);
}
/* Check a call EXP to the memmove built-in for validity.
Return NULL_RTX on both success and failure. */
static rtx
-expand_builtin_memmove (tree exp, rtx)
+expand_builtin_memmove (tree exp, rtx target)
{
if (!validate_arglist (exp,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
@@ -3809,7 +3810,8 @@ expand_builtin_memmove (tree exp, rtx)
check_memop_access (exp, dest, src, len);
- return NULL_RTX;
+ return expand_builtin_memory_copy_args (dest, src, len, target, exp,
+ /*retmode=*/ RETURN_BEGIN, true);
}
/* Expand a call EXP to the mempcpy builtin.
@@ -3858,7 +3860,8 @@ expand_builtin_mempcpy (tree exp, rtx target)
static rtx
expand_builtin_memory_copy_args (tree dest, tree src, tree len,
- rtx target, tree exp, memop_ret retmode)
+ rtx target, tree exp, memop_ret retmode,
+ bool might_overlap)
{
const char *src_str;
unsigned int src_align = get_pointer_alignment (src);
@@ -3894,9 +3897,12 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
&probable_max_size);
src_str = c_getstr (src);
- /* If SRC is a string constant and block move would be done
- by pieces, we can avoid loading the string from memory
- and only stored the computed constants. */
+ /* If SRC is a string constant and block move would be done by
+ pieces, we can avoid loading the string from memory and only
+ stored the computed constants. This works in the overlap
+ (memmove) case as well because store_by_pieces just generates a
+ series of stores of constants from the string constant returned
+ by c_getstr(). */
if (src_str
&& CONST_INT_P (len_rtx)
&& (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
@@ -3923,13 +3929,14 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
method = BLOCK_OP_TAILCALL;
bool use_mempcpy_call = (targetm.libc_has_fast_function (BUILT_IN_MEMPCPY)
&& retmode == RETURN_END
+ && !might_overlap
&& target != const0_rtx);
if (use_mempcpy_call)
method = BLOCK_OP_NO_LIBCALL_RET;
dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method,
expected_align, expected_size,
min_size, max_size, probable_max_size,
- use_mempcpy_call, &is_move_done);
+ use_mempcpy_call, &is_move_done, might_overlap);
/* Bail out when a mempcpy call would be expanded as libcall and when
we have a target that provides a fast implementation
@@ -3962,7 +3969,7 @@ expand_builtin_mempcpy_args (tree dest, tree src, tree len,
rtx target, tree orig_exp, memop_ret retmode)
{
return expand_builtin_memory_copy_args (dest, src, len, target, orig_exp,
- retmode);
+ retmode, false);
}
/* Expand into a movstr instruction, if one is available. Return NULL_RTX if