diff options
author | mpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-17 09:32:01 +0000 |
---|---|---|
committer | mpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-17 09:32:01 +0000 |
commit | 1390d90a78741a75a211aa92f5d52ace3052ad4c (patch) | |
tree | 37045e2b3b3747a97aa02b2f03011ed1fee86477 /gcc/tree-ssa-strlen.c | |
parent | 0a015fc7d93763ffacb318ca09ce6ff421c4e116 (diff) | |
download | gcc-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.c | 30 |
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))) { |