summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-24 20:14:35 +0000
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-24 20:14:35 +0000
commit364de28580a395f3566ca29315bac6e54f7b2b6d (patch)
treebf9957eca52822e3a25fbdd6aed21bf26bfc9eea
parent0eb954ba423b034b151163dc88c03466ed80ec51 (diff)
downloadppe42-gcc-364de28580a395f3566ca29315bac6e54f7b2b6d.tar.gz
ppe42-gcc-364de28580a395f3566ca29315bac6e54f7b2b6d.zip
2011-10-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* tree-ssa-strlen.c (get_string_length): Change assertion to STPCPY. (zero_length_string): Change assertion to accept strinfo without length but with stmt instead. Set the endptr pointer also if starting a new chain. (adjust_related_strinfos): Ignore strinfos marked for delayed length computation. (handle_builtin_strcpy): Mark earlier strinfo elements also for delayed length computation. 2011-10-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * gcc.dg/strlenopt-22.c: New testcase. * gcc.dg/strlenopt-4.c: Change scan value for s390(x). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180402 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-22.c41
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-4.c12
-rw-r--r--gcc/tree-ssa-strlen.c46
5 files changed, 104 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index efe02f745d3..bd04d776c18 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2011-10-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * tree-ssa-strlen.c (get_string_length): Change assertion to STPCPY.
+ (zero_length_string): Change assertion to accept strinfo without
+ length but with stmt instead.
+ Set the endptr pointer also if starting a new chain.
+ (adjust_related_strinfos): Ignore strinfos marked for delayed
+ length computation.
+ (handle_builtin_strcpy): Mark earlier strinfo elements also for
+ delayed length computation.
+
2011-10-24 Georg-Johann Lay <avr@gjlay.de>
PR target/50820
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 822fde544e0..0e7ee4c98e2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-10-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.dg/strlenopt-22.c: New testcase.
+ * gcc.dg/strlenopt-4.c: Change scan value for s390(x).
+
2011-10-24 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/sse-5.c (dg-options): Add -mno-sse.
diff --git a/gcc/testsuite/gcc.dg/strlenopt-22.c b/gcc/testsuite/gcc.dg/strlenopt-22.c
new file mode 100644
index 00000000000..541bfdce467
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-22.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-strlen" } */
+
+#define USE_GNU
+#include "strlenopt.h"
+
+__attribute__((noinline, noclone)) size_t
+bar (char *p, char *q)
+{
+ size_t l1, l2, l3;
+ char *r = strchr (p, '\0');
+ strcpy (r, "abcde");
+ char *s = strchr (r, '\0');
+ strcpy (s, q);
+ l1 = strlen (p);
+ l2 = strlen (r);
+ l3 = strlen (s);
+ return l1 + l2 + l3;
+}
+
+int
+main ()
+{
+ char buf[16] = "01234";
+
+ if (bar (buf, "56789") != 30)
+ abort ();
+
+ if (memcmp (buf, "01234abcde56789", 16) != 0)
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */
+/* { dg-final { cleanup-tree-dump "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-4.c b/gcc/testsuite/gcc.dg/strlenopt-4.c
index beea4959245..5997d31985f 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-4.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-4.c
@@ -66,10 +66,16 @@ main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */
+/* For targets providing a movstr pattern strcat is already decomposed
+ into strlen + strcpy by fold_builtin_strcat. */
+
+/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" { target { ! s390*-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen" { target s390*-*-* } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen" { target { ! s390*-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "strcpy \\(" 6 "strlen" { target s390*-*-* } } } */
+/* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen" { target { ! s390*-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" { target s390*-*-* } } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 697340f535a..72da15e9893 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -397,7 +397,7 @@ get_string_length (strinfo si)
callee = gimple_call_fndecl (stmt);
gcc_assert (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL);
lhs = gimple_call_lhs (stmt);
- gcc_assert (builtin_decl_implicit_p (BUILT_IN_STRCPY));
+ gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY));
/* unshare_strinfo is intentionally not called here. The (delayed)
transformation of strcpy or strcat into stpcpy is done at the place
of the former strcpy/strcat call and so can affect all the strinfos
@@ -588,13 +588,13 @@ zero_length_string (tree ptr, strinfo chainsi)
|| si->prev != chainsi->idx)
break;
}
- gcc_assert (chainsi->length);
+ gcc_assert (chainsi->length || chainsi->stmt);
if (chainsi->endptr == NULL_TREE)
{
chainsi = unshare_strinfo (chainsi);
chainsi->endptr = ptr;
}
- if (integer_zerop (chainsi->length))
+ if (chainsi->length && integer_zerop (chainsi->length))
{
if (chainsi->next)
{
@@ -626,6 +626,8 @@ zero_length_string (tree ptr, strinfo chainsi)
if (chainsi->first == 0)
chainsi->first = chainsi->idx;
chainsi->next = idx;
+ if (chainsi->endptr == NULL_TREE)
+ chainsi->endptr = ptr;
si->prev = chainsi->idx;
si->first = chainsi->first;
si->writable = chainsi->writable;
@@ -654,11 +656,19 @@ adjust_related_strinfos (location_t loc, strinfo origsi, tree adj)
tree tem;
si = unshare_strinfo (si);
- gcc_assert (si->length);
- tem = fold_convert_loc (loc, TREE_TYPE (si->length), adj);
- si->length = fold_build2_loc (loc, PLUS_EXPR,
- TREE_TYPE (si->length), si->length,
- tem);
+ if (si->length)
+ {
+ tem = fold_convert_loc (loc, TREE_TYPE (si->length), adj);
+ si->length = fold_build2_loc (loc, PLUS_EXPR,
+ TREE_TYPE (si->length), si->length,
+ tem);
+ }
+ else if (si->stmt != NULL)
+ /* Delayed length computation is unaffected. */
+ ;
+ else
+ gcc_unreachable ();
+
si->endptr = NULL_TREE;
si->dont_invalidate = true;
}
@@ -1117,10 +1127,30 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi)
if (dsi->length == NULL_TREE)
{
+ strinfo chainsi;
+
/* If string length of src is unknown, use delayed length
computation. If string lenth of dst will be needed, it
can be computed by transforming this strcpy call into
stpcpy and subtracting dst from the return value. */
+
+ /* Look for earlier strings whose length could be determined if
+ this strcpy is turned into an stpcpy. */
+
+ if (dsi->prev != 0 && (chainsi = verify_related_strinfos (dsi)) != NULL)
+ {
+ for (; chainsi && chainsi != dsi; chainsi = get_strinfo (chainsi->next))
+ {
+ /* When setting a stmt for delayed length computation
+ prevent all strinfos through dsi from being
+ invalidated. */
+ chainsi = unshare_strinfo (chainsi);
+ chainsi->stmt = stmt;
+ chainsi->length = NULL_TREE;
+ chainsi->endptr = NULL_TREE;
+ chainsi->dont_invalidate = true;
+ }
+ }
dsi->stmt = stmt;
return;
}
OpenPOWER on IntegriCloud