Commit 5b115c1f by Marek Polacek Committed by Marek Polacek

Add tree-ssa-strlen optimization.

From-SVN: r199006
parent 68119618
2013-05-17 Marek Polacek <polacek@redhat.com>
* tree-ssa-strlen.c (handle_char_store): Don't invalidate
cached length when doing non-zero store of storing '\0' to
'\0'.
* gcc.dg/strlenopt-25.c: New test.
* gcc.dg/strlenopt-26.c: Likewise.
2013-05-17 Jakub Jelinek <jakub@redhat.com>
* tree-vect-patterns.c (vect_recog_rotate_pattern): For
......
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-strlen" } */
#include "strlenopt.h"
int
main ()
{
char p[] = "foobar";
int len, len2;
len = strlen (p);
p[0] = 'O';
len2 = strlen (p);
return len - len2;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-strlen" } */
#include "strlenopt.h"
__attribute__((noinline, noclone)) size_t
fn1 (char *p, const char *r)
{
size_t len1 = strlen (r);
char *q = strchr (p, '\0');
*q = '\0';
return len1 - strlen (r); // This strlen should be optimized into len1.
}
int
main (void)
{
char p[] = "foobar";
const char *volatile q = "xyzzy";
fn1 (p, q);
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */
......@@ -1694,7 +1694,8 @@ handle_char_store (gimple_stmt_iterator *gsi)
else
{
si->writable = true;
si->dont_invalidate = true;
gsi_next (gsi);
return false;
}
}
else
......@@ -1717,6 +1718,33 @@ handle_char_store (gimple_stmt_iterator *gsi)
si->endptr = ssaname;
si->dont_invalidate = true;
}
/* If si->length is non-zero constant, we aren't overwriting '\0',
and if we aren't storing '\0', we know that the length of the
string and any other zero terminated string in memory remains
the same. In that case we move to the next gimple statement and
return to signal the caller that it shouldn't invalidate anything.
This is benefical for cases like:
char p[20];
void foo (char *q)
{
strcpy (p, "foobar");
size_t len = strlen (p); // This can be optimized into 6
size_t len2 = strlen (q); // This has to be computed
p[0] = 'X';
size_t len3 = strlen (p); // This can be optimized into 6
size_t len4 = strlen (q); // This can be optimized into len2
bar (len, len2, len3, len4);
}
*/
else if (si != NULL && si->length != NULL_TREE
&& TREE_CODE (si->length) == INTEGER_CST
&& integer_nonzerop (gimple_assign_rhs1 (stmt)))
{
gsi_next (gsi);
return false;
}
}
else if (idx == 0 && initializer_zerop (gimple_assign_rhs1 (stmt)))
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment