diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-09-27 18:15:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-09-27 18:15:46 +0200 |
commit | 8b57bfebe0bf2344c0eba3e17941a87e6dd2bbdf (patch) | |
tree | c8200cc6b87f6842f33b4c4ff883b03d7a81bc54 /gcc/testsuite/gcc.dg/strlenopt-9.c | |
parent | baaa40aeca4a95a6e250e14e8f1e8b2e1239c864 (diff) | |
download | gcc-8b57bfebe0bf2344c0eba3e17941a87e6dd2bbdf.tar.gz |
common.opt: Add -foptimize-strlen option.
* common.opt: Add -foptimize-strlen option.
* Makefile.in (OBJS): Add tree-ssa-strlen.o.
(tree-sssa-strlen.o): Add dependencies.
* opts.c (default_options_table): Enable -foptimize-strlen
by default at -O2 if not -Os.
* passes.c (init_optimization_passes): Add pass_strlen
after pass_object_sizes.
* timevar.def (TV_TREE_STRLEN): New timevar.
* params.def (PARAM_MAX_TRACKED_STRLENS): New parameter.
* tree-pass.h (pass_strlen): Declare.
* tree-ssa-strlen.c: New file.
* c-decl.c (merge_decls): If compatible stpcpy prototype
is seen, set implicit_built_in_decls[BUILT_IN_STPCPY].
cp/
* decl.c (duplicate_decls): If compatible stpcpy prototype
is seen, set implicit_built_in_decls[BUILT_IN_STPCPY].
testsuite/
* gcc.dg/strlenopt-1.c: New test.
* gcc.dg/strlenopt-1f.c: New test.
* gcc.dg/strlenopt-2.c: New test.
* gcc.dg/strlenopt-2f.c: New test.
* gcc.dg/strlenopt-3.c: New test.
* gcc.dg/strlenopt-4.c: New test.
* gcc.dg/strlenopt-4g.c: New test.
* gcc.dg/strlenopt-4gf.c: New test.
* gcc.dg/strlenopt-5.c: New test.
* gcc.dg/strlenopt-6.c: New test.
* gcc.dg/strlenopt-7.c: New test.
* gcc.dg/strlenopt-8.c: New test.
* gcc.dg/strlenopt-9.c: New test.
* gcc.dg/strlenopt-10.c: New test.
* gcc.dg/strlenopt-11.c: New test.
* gcc.dg/strlenopt-12.c: New test.
* gcc.dg/strlenopt-12g.c: New test.
* gcc.dg/strlenopt-13.c: New test.
* gcc.dg/strlenopt-14g.c: New test.
* gcc.dg/strlenopt-14gf.c: New test.
* gcc.dg/strlenopt-15.c: New test.
* gcc.dg/strlenopt-16g.c: New test.
* gcc.dg/strlenopt-17g.c: New test.
* gcc.dg/strlenopt-18g.c: New test.
* gcc.dg/strlenopt.h: New file.
From-SVN: r179277
Diffstat (limited to 'gcc/testsuite/gcc.dg/strlenopt-9.c')
-rw-r--r-- | gcc/testsuite/gcc.dg/strlenopt-9.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/strlenopt-9.c b/gcc/testsuite/gcc.dg/strlenopt-9.c new file mode 100644 index 00000000000..6590d708ec7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-9.c @@ -0,0 +1,109 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-tree-strlen -fdump-tree-optimized" } */ + +#include "strlenopt.h" + +__attribute__((noinline, noclone)) char * +fn1 (int r) +{ + char *p = r ? "a" : "bc"; + /* String length for p varies, therefore strchr below isn't + optimized away. */ + return strchr (p, '\0'); +} + +__attribute__((noinline, noclone)) size_t +fn2 (int r) +{ + char *p, q[10]; + strcpy (q, "abc"); + p = r ? "a" : q; + /* String length for p varies, therefore strlen below isn't + optimized away. */ + return strlen (p); +} + +__attribute__((noinline, noclone)) size_t +fn3 (char *p, int n) +{ + int i; + p = strchr (p, '\0'); + /* strcat here can be optimized into memcpy. */ + strcat (p, "abcd"); + for (i = 0; i < n; i++) + if ((i % 123) == 53) + /* strcat here is optimized into strlen and memcpy. */ + strcat (p, "efg"); + /* The strlen here can't be optimized away, as in the loop string + length of p might change. */ + return strlen (p); +} + +char buf[64]; + +__attribute__((noinline, noclone)) size_t +fn4 (char *x, int n) +{ + int i; + size_t l; + char a[64]; + char *p = strchr (x, '\0'); + /* strcpy here is optimized into memcpy, length computed as p - x + 1. */ + strcpy (a, x); + /* strcat here is optimized into memcpy. */ + strcat (p, "abcd"); + for (i = 0; i < n; i++) + if ((i % 123) == 53) + /* strcat here is optimized into strlen and memcpy. */ + strcat (a, "efg"); + /* The strlen should be optimized here into 4. */ + l = strlen (p); + /* This stays strcpy. */ + strcpy (buf, a); + return l; +} + +int +main () +{ + volatile int l = 1; + char b[64]; + + if (memcmp (fn1 (l) - 1, "a", 2) != 0) + abort (); + if (memcmp (fn1 (!l) - 2, "bc", 3) != 0) + abort (); + if (fn2 (l) != 1 || fn2 (!l) != 3) + abort (); + memset (b, '\0', sizeof b); + memset (b, 'a', 3); + if (fn3 (b, 10) != 4 || memcmp (b, "aaaabcd", 8) != 0) + abort (); + if (fn3 (b, 128) != 7 || memcmp (b, "aaaabcdabcdefg", 15) != 0) + abort (); + if (fn3 (b, 256) != 10 || memcmp (b, "aaaabcdabcdefgabcdefgefg", 25) != 0) + abort (); + if (fn4 (b, 10) != 4 + || memcmp (b, "aaaabcdabcdefgabcdefgefgabcd", 29) != 0 + || memcmp (buf, "aaaabcdabcdefgabcdefgefg", 25) != 0) + abort (); + if (fn4 (b, 128) != 4 + || memcmp (b, "aaaabcdabcdefgabcdefgefgabcdabcd", 33) != 0 + || memcmp (buf, "aaaabcdabcdefgabcdefgefgabcdefg", 32) != 0) + abort (); + if (fn4 (b, 256) != 4 + || memcmp (b, "aaaabcdabcdefgabcdefgefgabcdabcdabcd", 37) != 0 + || memcmp (buf, "aaaabcdabcdefgabcdefgefgabcdabcdefgefg", 39) != 0) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 3 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { cleanup-tree-dump "strlen" } } */ +/* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ |