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:
parent
353293e7f7
commit
eaf1912236
gcc
@ -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.
|
||||
|
18
gcc/testsuite/gcc.dg/memmove-1.c
Normal file
18
gcc/testsuite/gcc.dg/memmove-1.c
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user