summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/strlenopt-9.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-09-27 18:15:46 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-09-27 18:15:46 +0200
commit8b57bfebe0bf2344c0eba3e17941a87e6dd2bbdf (patch)
treec8200cc6b87f6842f33b4c4ff883b03d7a81bc54 /gcc/testsuite/gcc.dg/strlenopt-9.c
parentbaaa40aeca4a95a6e250e14e8f1e8b2e1239c864 (diff)
downloadgcc-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.c109
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" } } */