diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fc627a150c9..c09938447e6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2003-05-08 Kaveh R. Ghazi + + * builtins.c (readonly_data_expr): New function. + (expand_builtin_memmove): Optimize any rodata source, not just + strings. + 2003-05-07 David Mosberger * unwind-libunwind.c (_Unwind_FindEnclosingFunction): New. diff --git a/gcc/builtins.c b/gcc/builtins.c index c309997fd97..6745300fe80 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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; +} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index baf9936d43d..a11244a602f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-05-08 Kaveh R. Ghazi + + gcc.c-torture/execute/string-opt-19.c: Add general rodata tests. + (bcopy): Call memmove. + 2003-05-08 Roger Sayle * g77.f-torture/compile/8485.f: New test case. diff --git a/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c b/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c index 92b84c6d843..33823162f18 100644 --- a/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c +++ b/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c @@ -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); }