On Thu, May 16, 2013 at 03:38:47PM +0200, Jakub Jelinek wrote:
> Please add here a comment what it does and why, that if si->length
> is non-zero constant, we know that the character at that spot is
> not '\0' and when storing non-'\0' to that location, we can't affect
> size of any strings at all.  Therefore we do the gsi_next + return false
> to signal caller that it shouldn't invalidate anything.
> 
> Ok with that change, thanks.

Thanks, this what I'll commit later today if no objections.

2013-05-16  Marek Polacek  <pola...@redhat.com>

        * tree-ssa-strlen.c (handle_char_store): Don't invalidate
        cached length when doing non-zero store.

        * gcc.dg/strlenopt-25.c: New test.

--- gcc/tree-ssa-strlen.c.mp    2013-05-15 14:11:20.079707492 +0200
+++ gcc/tree-ssa-strlen.c       2013-05-16 16:03:50.373504796 +0200
@@ -1717,6 +1717,27 @@ handle_char_store (gimple_stmt_iterator
            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 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[] = "foobar";
+        size_t len = strlen (p);
+        p[0] = 'X'
+        size_t len2 = strlen (p);
+        
+        where we should be able to optimize away the second strlen call.  */
+      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)))
     {
--- gcc/testsuite/gcc.dg/strlenopt-25.c.mp      2013-05-15 17:15:18.702118637 
+0200
+++ gcc/testsuite/gcc.dg/strlenopt-25.c 2013-05-15 18:26:27.881030317 +0200
@@ -0,0 +1,18 @@
+/* { 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" } } */

        Marek

Reply via email to