diff options
author | Aaron Sawdey <acsawdey@linux.ibm.com> | 2019-10-02 14:23:51 +0000 |
---|---|---|
committer | Aaron Sawdey <acsawdey@gcc.gnu.org> | 2019-10-02 09:23:51 -0500 |
commit | 03a9b90aa6df28dde083efd17e8b7ae76b943fe7 (patch) | |
tree | cf2c7debb8c890c231f2b9b46d142d78e10e2f4c /gcc/builtins.c | |
parent | 629387a6586a753166f5cf53d587026a34362523 (diff) | |
download | gcc-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.c | 27 |
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 |