Commit ea82015c by Roger Sayle Committed by Roger Sayle

builtins.c (expand_builtin_memcpy): Optimize case when the two pointer arguments are the equal...


	* builtins.c (expand_builtin_memcpy): Optimize case when the two
	pointer arguments are the equal, non-volatile and side-effect free.
	(expand_builtin_mempcpy): Likewise.
	(expand_builtin_memmove): Likewise.
	(expand_builtin_strcpy): Likewise.
	(expand_builtin_memcmp): Likewise.
	(expand_builtin_strcmp): Likewise.
	(expand_builtin_strncmp): Likewise.

	* gcc.c-torture/execute/string-opt-18.c: New testcase.

From-SVN: r72335
parent 2981fafe
2003-10-11 Roger Sayle <roger@eyesopen.com>
* builtins.c (expand_builtin_memcpy): Optimize case when the two
pointer arguments are the equal, non-volatile and side-effect free.
(expand_builtin_mempcpy): Likewise.
(expand_builtin_memmove): Likewise.
(expand_builtin_strcpy): Likewise.
(expand_builtin_memcmp): Likewise.
(expand_builtin_strcmp): Likewise.
(expand_builtin_strncmp): Likewise.
2003-10-11 Roger Sayle <roger@eyesopen.com>
* combine.c (apply_distributive_law): Enable "distributive" floating
point optimizations with -funsafe-math-optimizations.
......
......@@ -2561,11 +2561,34 @@ expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
rtx dest_mem, src_mem, len_rtx;
/* If DEST is not a pointer type or LEN is not constant,
call the normal function. */
if (dest_align == 0 || !host_integerp (len, 1))
/* If DEST is not a pointer type, call the normal function. */
if (dest_align == 0)
return 0;
/* If SRC and DEST are the same (and not volatile), do nothing. */
if (operand_equal_p (src, dest, 0))
{
tree expr;
if (endp == 0)
{
/* Evaluate and ignore LEN in case it has side-effects. */
expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
if (endp == 2)
len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
integer_one_node));
len = convert (TREE_TYPE (dest), len);
expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
return expand_expr (expr, target, mode, EXPAND_NORMAL);
}
/* If LEN is not constant, call the normal function. */
if (! host_integerp (len, 1))
return 0;
/* If the LEN parameter is zero, return DEST. */
if (tree_low_cst (len, 1) == 0)
{
......@@ -2574,6 +2597,14 @@ expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
/* If SRC and DEST are the same (and not volatile), return DEST. */
if (operand_equal_p (src, dest, 0))
{
/* Evaluate and ignore LEN in case it has side-effects. */
expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
/* If either SRC is not a pointer type, don't do this
operation in-line. */
if (src_align == 0)
......@@ -2651,6 +2682,14 @@ expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
/* If SRC and DEST are the same (and not volatile), return DEST. */
if (operand_equal_p (src, dest, 0))
{
/* Evaluate and ignore LEN in case it has side-effects. */
expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
/* If either SRC is not a pointer type, don't do this
operation in-line. */
if (src_align == 0)
......@@ -2713,16 +2752,21 @@ expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
src = TREE_VALUE (TREE_CHAIN (arglist));
dst = TREE_VALUE (arglist);
/* If SRC and DST are equal (and not volatile), return DST. */
if (operand_equal_p (src, dst, 0))
return expand_expr (dst, target, mode, EXPAND_NORMAL);
fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
src = TREE_VALUE (TREE_CHAIN (arglist));
len = c_strlen (src, 1);
if (len == 0 || TREE_SIDE_EFFECTS (len))
return 0;
dst = TREE_VALUE (arglist);
len = size_binop (PLUS_EXPR, len, ssize_int (1));
arglist = build_tree_list (NULL_TREE, len);
arglist = tree_cons (NULL_TREE, src, arglist);
......@@ -3063,6 +3107,14 @@ expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
return const0_rtx;
}
/* If both arguments are equal (and not volatile), return zero. */
if (operand_equal_p (arg1, arg2, 0))
{
/* Evaluate and ignore len in case it has side-effects. */
expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
return const0_rtx;
}
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
......@@ -3192,6 +3244,10 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
arg1 = TREE_VALUE (arglist);
arg2 = TREE_VALUE (TREE_CHAIN (arglist));
/* If both arguments are equal (and not volatile), return zero. */
if (operand_equal_p (arg1, arg2, 0))
return const0_rtx;
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
......@@ -3332,6 +3388,14 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
return const0_rtx;
}
/* If arg1 and arg2 are equal (and not volatile), return zero. */
if (operand_equal_p (arg1, arg2, 0))
{
/* Evaluate and ignore arg3 in case it has side-effects. */
expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
return const0_rtx;
}
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
......
2003-10-11 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/string-opt-18.c: New testcase.
2003-10-10 Ian Lance Taylor <ian@wasabisystems.com>
* gcc.c-torture/compile/20031010-1.c: New test.
......
/* Copyright (C) 2003 Free Software Foundation.
Test equal pointer optimizations don't break anything.
Written by Roger Sayle, July 14, 2003. */
extern void abort ();
typedef __SIZE_TYPE__ size_t;
extern void *memcpy(void*, const void*, size_t);
extern void *mempcpy(void*, const void*, size_t);
extern void *memmove(void*, const void*, size_t);
extern char *strcpy(char*, const char*);
extern int memcmp(const void*, const void*, size_t);
extern int strcmp(const char*, const char*);
extern int strncmp(const char*, const char*, size_t);
void test1 (void *ptr)
{
if (memcpy(ptr,ptr,8) != ptr)
abort ();
}
void test2 (char *ptr)
{
if (mempcpy(ptr,ptr,8) != ptr+8)
abort ();
}
void test3 (void *ptr)
{
if (memmove(ptr,ptr,8) != ptr)
abort ();
}
void test4 (char *ptr)
{
if (strcpy(ptr,ptr) != ptr)
abort ();
}
void test5 (void *ptr)
{
if (memcmp(ptr,ptr,8) != 0)
abort ();
}
void test6 (const char *ptr)
{
if (strcmp(ptr,ptr) != 0)
abort ();
}
void test7 (const char *ptr)
{
if (strncmp(ptr,ptr,8) != 0)
abort ();
}
int main ()
{
char buf[10];
test1 (buf);
test2 (buf);
test3 (buf);
test4 (buf);
test5 (buf);
test6 (buf);
test7 (buf);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment