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 expand_builtin_memmove: optimize any rodata source, not just strings


As a followup to my own suggestion here:
http://gcc.gnu.org/ml/gcc-patches/2003-04/msg02095.html

I think I've figured out how to optimize memmove for any rodata
source, not just for strings as originally implemented.  There's a
handy function in varasm.c called decl_readonly_section which does
exactly what I want.  :-)

Note, I'm not sure whether decl_readonly_section's second parameter
`reloc' is significant for this usage.  Reading through a subfunction
categorize_decl_for_section, it seems that `reloc' is only used to
distinguish between different RO section types, but since we only care
if it's any of the various RO sections, I hardcoded zero.  Still, I'd
appreciate a second pair of eyeballs on that point.  If we have to
calculate a correct value, I'm not sure how to do that.  We may have
to expose some currently static functions in varasm.c to the outside
world in order to accomplish this.  Guidance welcome.

WRT testing, currently both java and c++ are not buildable on mainline
on sparc-solaris2.7.  So I'm running a C-only bootstrap and testsuite
run.  That's not much of a test because there's exactly one call to
memmove in stmt.c in the top level sources.  The testcase additions to
string-opt-19.c do work though.  And I hand-verified the negative case
where if I remove the "const" from the static data, that the testcase
calls the local memmove implementation and aborts.

Also, while updating the testcase, I decided we didn't need backup
implementations for both bcopy and memmove, instead I made the local
bcopy call the local memmove.

Ok for mainline?

		Thanks,
		--Kaveh


2003-05-06  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

gcc:
	* builtins.c (expand_builtin_memmove): Optimize any rodata source,
	not just strings.
	
testsuite
	gcc.c-torture/execute/string-opt-19.c: Add general rodata tests.
	(bcopy): Call memmove.

diff -rup orig/egcc-CVS20030505/gcc/builtins.c egcc-CVS20030505/gcc/builtins.c
--- orig/egcc-CVS20030505/gcc/builtins.c	Mon May  5 17:13:46 2003
+++ egcc-CVS20030505/gcc/builtins.c	Tue May  6 00:22:19 2003
@@ -2423,10 +2423,17 @@ expand_builtin_memmove (arglist, target,
       if (src_align == 0)
 	return 0;
 
-      /* If src is a string constant and strings are not writable,
-	 we can use normal memcpy.  */
-      if (!flag_writable_strings && c_getstr (src))
-	return expand_builtin_memcpy (arglist, target, mode, 0);
+      /* If src is categorized for a readonly section we can use
+	 normal memcpy.  */
+      STRIP_NOPS (src);
+      if (decl_readonly_section (TREE_OPERAND (src, 0), 0))
+        {
+	  tree const 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);
+	}
 
       /* Otherwise, call the normal function.  */
       return 0;
diff -rup orig/egcc-CVS20030505/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c egcc-CVS20030505/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c
--- orig/egcc-CVS20030505/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c	Mon Apr 28 08:10:35 2003
+++ egcc-CVS20030505/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c	Tue May  6 01:14:36 2003
@@ -13,10 +13,61 @@ extern int memcmp (const void *, const v
 const char s1[] = "123";
 char p[32] = "";
 
+static const struct foo
+{
+  char *s;
+  double d;
+  long l;
+} foo[] =
+{
+  { "hello world1", 3.14159, 101L },
+  { "hello world2", 3.14159, 102L },
+  { "hello world3", 3.14159, 103L },
+  { "hello world4", 3.14159, 104L },
+  { "hello world5", 3.14159, 105L },
+  { "hello world6", 3.14159, 106L }
+};
+
+static const struct bar
+{
+  char *s;
+  const struct foo f[3];
+} bar[] =
+{
+  {
+    "hello world10",
+    {
+      { "hello1", 3.14159, 201L },
+      { "hello2", 3.14159, 202L },
+      { "hello3", 3.14159, 203L },
+    }
+  },
+  {
+    "hello world11",
+    {
+      { "hello4", 3.14159, 204L },
+      { "hello5", 3.14159, 205L },
+      { "hello6", 3.14159, 206L },
+    }
+  }
+};
+
+static const int baz[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+
 int main()
 {
-  int i;
   const char *s;
+  struct foo f1[sizeof foo/sizeof*foo];
+  struct bar b1[sizeof bar/sizeof*bar];
+  int bz[sizeof baz/sizeof*baz];
+
+  if (memmove (f1, foo, sizeof (foo)) != f1 || memcmp (f1, foo, sizeof(foo)))
+    abort();
+  if (memmove (b1, bar, sizeof (bar)) != b1 || memcmp (b1, bar, sizeof(bar)))
+    abort();
+  bcopy (baz, bz, sizeof (baz));
+  if (memcmp (bz, baz, sizeof(baz)))
+    abort();
 
   if (memmove (p, "abcde", 6) != p || memcmp (p, "abcde", 6))
     abort ();
@@ -70,20 +121,5 @@ __attribute__ ((noinline))
 static void
 bcopy (const void *s, void *d, size_t n)
 {
-#ifdef __OPTIMIZE__
-  abort ();
-#else
-  char *dst = (char *) d;
-  const char *src = (const char *) s;
-  if (src < dst)
-    {
-      dst += n;
-      src += n;
-      while (n--)
-        *--dst = *--src;
-    }
-  else
-    while (n--)
-      *dst++ = *src++;
-#endif
+  memmove (d, s, n);
 }


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