summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-strlen.c
diff options
context:
space:
mode:
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-17 09:32:01 +0000
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-17 09:32:01 +0000
commit1390d90a78741a75a211aa92f5d52ace3052ad4c (patch)
tree37045e2b3b3747a97aa02b2f03011ed1fee86477 /gcc/tree-ssa-strlen.c
parent0a015fc7d93763ffacb318ca09ce6ff421c4e116 (diff)
downloadgcc-1390d90a78741a75a211aa92f5d52ace3052ad4c.tar.gz
Add tree-ssa-strlen optimization.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199006 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-strlen.c')
-rw-r--r--gcc/tree-ssa-strlen.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 5ab37645ec6..c0f9ccd5642 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -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)))
{