aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2006-10-23 20:50:40 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2006-10-23 18:50:40 +0000
commiteaf1912236bac3d5b6182a551f2d294478e3d83c (patch)
treed8fd80b47f68bac6cd4e41ae69cc7c05702cc8c0 /gcc
parent353293e7f758be575d88aa78edb9ccddb7816cba (diff)
downloadgcc-eaf1912236bac3d5b6182a551f2d294478e3d83c.zip
gcc-eaf1912236bac3d5b6182a551f2d294478e3d83c.tar.gz
gcc-eaf1912236bac3d5b6182a551f2d294478e3d83c.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/builtins.c68
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/memmove-1.c18
4 files changed, 55 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6e9c9f5..c304f18 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index ecee42b..b2a8647 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d6acf66..ebbae93 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/memmove-1.c b/gcc/testsuite/gcc.dg/memmove-1.c
new file mode 100644
index 0000000..46918ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memmove-1.c
@@ -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);
+}