builtins.c (readonly_data_expr): New function.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Thu, 8 May 2003 13:45:38 +0000 (13:45 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Thu, 8 May 2003 13:45:38 +0000 (13:45 +0000)
gcc:
* builtins.c (readonly_data_expr): New function.
(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.

From-SVN: r66597

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/string-opt-19.c

index fc627a1..c099384 100644 (file)
@@ -1,3 +1,9 @@
+2003-05-08  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * builtins.c (readonly_data_expr): New function.
+       (expand_builtin_memmove): Optimize any rodata source, not just
+       strings.
+
 2003-05-07  David Mosberger <davidm@hpl.hp.com>
 
         * unwind-libunwind.c (_Unwind_FindEnclosingFunction): New.
index c309997..6745300 100644 (file)
@@ -168,6 +168,7 @@ static tree fold_builtin_inf                PARAMS ((tree, int));
 static tree fold_builtin_nan           PARAMS ((tree, tree, int));
 static int validate_arglist            PARAMS ((tree, ...));
 static tree fold_trunc_transparent_mathfn PARAMS ((tree));
+static bool readonly_data_expr         PARAMS ((tree));
 
 /* Return the alignment in bits of EXP, a pointer valued expression.
    But don't return more than MAX_ALIGN no matter what.
@@ -2423,10 +2424,16 @@ expand_builtin_memmove (arglist, target, mode)
       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.  */
+      if (readonly_data_expr (src))
+        {
+         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;
@@ -5449,3 +5456,16 @@ purge_builtin_constant_p ()
       }
 }
 
+/* Returns true is EXP represents data that would potentially reside
+   in a readonly section.  */
+
+static bool
+readonly_data_expr (tree exp)
+{
+  STRIP_NOPS (exp);
+
+  if (TREE_CODE (exp) == ADDR_EXPR)
+    return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
+  else
+    return false;
+}
index baf9936..a11244a 100644 (file)
@@ -1,3 +1,8 @@
+2003-05-08  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       gcc.c-torture/execute/string-opt-19.c: Add general rodata tests.
+       (bcopy): Call memmove.
+
 2003-05-08  Roger Sayle  <roger@eyesopen.com>
 
        * g77.f-torture/compile/8485.f: New test case.
index 92b84c6..3382316 100644 (file)
@@ -13,10 +13,61 @@ extern int memcmp (const void *, const void *, size_t);
 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);
 }