builtins.c (expand_builtin_mempcpy): New function.

* builtins.c (expand_builtin_mempcpy): New function.
	(expand_builtin_stpcpy): Optimize stpcpy whose return value is
	ignored into strcpy no matter what arguments it has.
	(expand_builtin) <case BUILT_IN_MEMPCPY>: Call
	expand_builtin_mempcpy.

	* gcc.c-torture/execute/string-opt-18.c (main): Add 3 new tests.

From-SVN: r66498
This commit is contained in:
Jakub Jelinek 2003-05-05 21:31:35 +02:00 committed by Jakub Jelinek
parent 6035d635b5
commit e3e9f10846
4 changed files with 86 additions and 2 deletions

View File

@ -1,3 +1,11 @@
2003-05-05 Jakub Jelinek <jakub@redhat.com>
* builtins.c (expand_builtin_mempcpy): New function.
(expand_builtin_stpcpy): Optimize stpcpy whose return value is
ignored into strcpy no matter what arguments it has.
(expand_builtin) <case BUILT_IN_MEMPCPY>: Call
expand_builtin_mempcpy.
2003-05-05 Aldy Hernandez <aldyh@redhat.com>
* testsuite/gcc.dg/20030505.c: New.

View File

@ -126,6 +126,8 @@ static rtx expand_builtin_strcspn PARAMS ((tree, rtx,
enum machine_mode));
static rtx expand_builtin_memcpy PARAMS ((tree, rtx,
enum machine_mode, int));
static rtx expand_builtin_mempcpy PARAMS ((tree, rtx,
enum machine_mode));
static rtx expand_builtin_memmove PARAMS ((tree, rtx,
enum machine_mode));
static rtx expand_builtin_bcopy PARAMS ((tree));
@ -2345,6 +2347,43 @@ expand_builtin_memcpy (arglist, target, mode, endp)
}
}
/* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
Return 0 if we failed the caller should emit a normal call,
otherwise try to get the result in TARGET, if convenient (and in
mode MODE if that's convenient). */
static rtx
expand_builtin_mempcpy (arglist, target, mode)
tree arglist;
rtx target;
enum machine_mode mode;
{
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0;
else
{
/* If return value is ignored, transform mempcpy into memcpy. */
if (target == const0_rtx)
{
tree fn;
rtx ret = expand_builtin_memcpy (arglist, target, mode, /*endp=*/0);
if (ret)
return ret;
fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
return expand_expr (build_function_call_expr (fn, arglist),
target, mode, EXPAND_NORMAL);
}
return expand_builtin_memcpy (arglist, target, mode, /*endp=*/1);
}
}
/* Expand expression EXP, which is a call to the memmove builtin. Return 0
if we failed the caller should emit a normal call. */
@ -2469,7 +2508,26 @@ expand_builtin_stpcpy (arglist, target, mode)
else
{
tree newarglist;
tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
tree len;
/* If return value is ignored, transform stpcpy into strcpy. */
if (target == const0_rtx)
{
tree fn;
rtx ret = expand_builtin_strcpy (arglist, target, mode);
if (ret)
return ret;
fn = implicit_built_in_decls[BUILT_IN_STRCPY];
if (!fn)
return 0;
return expand_expr (build_function_call_expr (fn, arglist),
target, mode, EXPAND_NORMAL);
}
len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
if (len == 0)
return 0;
@ -4586,7 +4644,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
break;
case BUILT_IN_MEMPCPY:
target = expand_builtin_memcpy (arglist, target, mode, /*endp=*/1);
target = expand_builtin_mempcpy (arglist, target, mode);
if (target)
return target;
break;

View File

@ -1,3 +1,7 @@
2003-05-05 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/string-opt-18.c (main): Add 3 new tests.
2003-05-05 Geoffrey Keating <geoffk@apple.com>
* gcc.dg/unused-5.c: New test.

View File

@ -15,6 +15,9 @@ extern int memcmp (const void *, const void *, size_t);
const char s1[] = "123";
char p[32] = "";
char *s2 = "defg";
char *s3 = "FGH";
size_t l1 = 1;
int main()
{
@ -60,6 +63,17 @@ int main()
if (__builtin_mempcpy (p, "ABCDE", 6) != p + 6 || memcmp (p, "ABCDE", 6))
abort ();
/* If the result of stpcpy/mempcpy is ignored, gcc should use
strcpy/memcpy. */
stpcpy (p + 3, s2);
if (memcmp (p, "ABCdefg", 8))
abort ();
mempcpy (p + 5, s3, 1);
if (memcmp (p, "ABCdeFg", 8))
abort ();
mempcpy (p + 6, s3 + 1, l1);
if (memcmp (p, "ABCdeFG", 8))
abort ();
return 0;
}