2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-13 16:31:20 +08:00

builtins.c (expand_builtin_memmove): Remove ORIG_EXP argument; don't do conversion from memmove to memcpy here.

* builtins.c (expand_builtin_memmove): Remove ORIG_EXP argument;
	don't do conversion from memmove to memcpy here.
	(expand_builtin_bcopy, expand_builtin): Update call of
	expand_builtin_memmove.
	(fold_builtin_memory_op): Do folding of memmove to memcpy here.

	* gcc.dg/memmove-1.c: New test.

From-SVN: r117979
This commit is contained in:
Jan Hubicka 2006-10-23 20:50:40 +02:00 committed by Jan Hubicka
parent 353293e7f7
commit eaf1912236
4 changed files with 55 additions and 43 deletions

@ -1,3 +1,11 @@
2006-10-23 Jan Hubicka <jh@suse.cz>
* builtins.c (expand_builtin_memmove): Remove ORIG_EXP argument;
don't do conversion from memmove to memcpy here.
(expand_builtin_bcopy, expand_builtin): Update call of
expand_builtin_memmove.
(fold_builtin_memory_op): Do folding of memmove to memcpy here.
2006-10-23 Paul Brook <paul@codesourcery.com>
* stor-layout.c (start_record_layout): maximum_field_alignment

@ -111,7 +111,7 @@ static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
static rtx expand_builtin_bcopy (tree);
static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
@ -3089,20 +3089,13 @@ expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode m
static rtx
expand_builtin_memmove (tree arglist, tree type, rtx target,
enum machine_mode mode, tree orig_exp)
enum machine_mode mode)
{
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0;
else
{
tree dest = TREE_VALUE (arglist);
tree src = TREE_VALUE (TREE_CHAIN (arglist));
tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
unsigned int dest_align
= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
if (result)
@ -3116,38 +3109,6 @@ expand_builtin_memmove (tree arglist, tree type, rtx target,
return expand_expr (result, target, mode, EXPAND_NORMAL);
}
/* If DEST is not a pointer type, call the normal function. */
if (dest_align == 0)
return 0;
/* If either SRC is not a pointer type, don't do this
operation in-line. */
if (src_align == 0)
return 0;
/* If src is categorized for a readonly section we can use
normal memcpy. */
if (readonly_data_expr (src))
{
tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
fn = build_function_call_expr (fn, arglist);
if (TREE_CODE (fn) == CALL_EXPR)
CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
return expand_expr (fn, target, mode, EXPAND_NORMAL);
}
/* If length is 1 and we can expand memcpy call inline,
it is ok to use memcpy as well. */
if (integer_onep (len))
{
rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
/*endp=*/0);
if (ret)
return ret;
}
/* Otherwise, call the normal function. */
return 0;
}
@ -3180,7 +3141,7 @@ expand_builtin_bcopy (tree exp)
newarglist = tree_cons (NULL_TREE, src, newarglist);
newarglist = tree_cons (NULL_TREE, dest, newarglist);
return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
}
#ifndef HAVE_movstr
@ -6073,7 +6034,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_MEMMOVE:
target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
mode, exp);
mode);
if (target)
return target;
break;
@ -8146,6 +8107,27 @@ fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
expr = len;
else
{
if (endp == 3)
{
unsigned int src_align
= get_pointer_alignment (src, BIGGEST_ALIGNMENT);
unsigned int dest_align
= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
/* Both DEST and SRC must be pointer types.
??? This is what old code did. Is the testing for pointer types
really mandatory?
If either SRC is readonly or length is 1, we can use memcpy. */
if (dest_align && src_align
&& (readonly_data_expr (src)
|| integer_onep (len)))
{
tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
return build_function_call_expr (fn, arglist);
}
}
if (! host_integerp (len, 1))
return 0;

@ -1,3 +1,7 @@
2006-10-23 Jan Hubicka <jh@suse.cz>
* gcc.dg/memmove-1.c: New test.
2006-10-23 Paul Brook <paul@codesourcery.com>
* gcc.dg/pragma-pack-5.c: New test.

@ -0,0 +1,18 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "memmove" 0 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
static const char a[100]={1,2,3,4};
char b[1000];
int i,i1;
static inline void
__attribute__ ((always_inline))
domem (void *dest, const void *src, int len)
{
__builtin_memmove (dest, src, len);
}
t()
{
domem (b,a,100);
domem (b+i1,(const void *)b,1);
}