From 6217c238d53721f35f18268414829edc7c331dd3 Mon Sep 17 00:00:00 2001 From: sayle Date: Sat, 11 Oct 2003 14:09:44 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72335 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 ++++ gcc/builtins.c | 74 +++++++++++++++++++-- gcc/testsuite/ChangeLog | 4 ++ .../gcc.c-torture/execute/string-opt-18.c | 76 ++++++++++++++++++++++ 4 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/string-opt-18.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5bec02..3cfe32a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 2003-10-11 Roger Sayle + * 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 + * combine.c (apply_distributive_law): Enable "distributive" floating point optimizations with -funsafe-math-optimizations. diff --git a/gcc/builtins.c b/gcc/builtins.c index dc20088..1af2a2d 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b8d1d8a..86c18ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-10-11 Roger Sayle + + * gcc.c-torture/execute/string-opt-18.c: New testcase. + 2003-10-10 Ian Lance Taylor * gcc.c-torture/compile/20031010-1.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/string-opt-18.c b/gcc/testsuite/gcc.c-torture/execute/string-opt-18.c new file mode 100644 index 0000000..610c4ca --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/string-opt-18.c @@ -0,0 +1,76 @@ +/* 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; +} + -- 2.7.4