This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Optimize (void) stpcpy (s1, s2) and (void) mempcpy (s1, s2)


Hi!

If the result of stpcpy or mempcpy is never used, it is ok to use strcpy
resp. memcpy instead no matter whether they will be further optimized or
not.
Bootstrapped on i686-redhat-linux, no regressions.
Ok to commit?

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.

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

--- gcc/testsuite/gcc.c-torture/execute/string-opt-18.c.jj	2003-04-25 11:50:32.000000000 -0400
+++ gcc/testsuite/gcc.c-torture/execute/string-opt-18.c	2003-05-05 06:47:45.000000000 -0400
@@ -15,6 +15,9 @@ extern int memcmp (const void *, const v
 
 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;
 }
 
--- gcc/builtins.c.jj	2003-05-05 05:56:06.000000000 -0400
+++ gcc/builtins.c	2003-05-05 06:33:04.000000000 -0400
@@ -126,6 +126,8 @@ static rtx expand_builtin_strcspn	PARAMS
 						 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, 
     }
 }
 
+/* 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, 
   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, 
       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;

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]