Make tree-ssa-strlen.c handle partial unterminated strings
authorRichard Sandiford <richard.sandiford@linaro.org>
Sun, 2 Jul 2017 08:52:42 +0000 (08:52 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 2 Jul 2017 08:52:42 +0000 (08:52 +0000)
commite3f9a279f5694d662771553180f9fa8e85716e3a
tree079e2f73722db5b22edac56d2ca41ca45acd7c3a
parent862088aa6349851465388eb0c691a79325c5eb7a
Make tree-ssa-strlen.c handle partial unterminated strings

tree-ssa-strlen.c looks for cases in which a string is built up using
operations like:

    memcpy (a, "foo", 4);
    memcpy (a + 3, "bar", 4);
    int x = strlen (a);

As a side-effect, it optimises the non-final memcpys so that they don't
include the nul terminator.

However, after removing some "& ~0x1"s from tree-ssa-dse.c, the DSE pass
does this optimisation itself (because it can tell that later memcpys
overwrite the terminators).  The strlen pass wasn't able to handle these
pre-optimised calls in the same way as the unoptimised ones.

This patch adds support for tracking unterminated strings.

[Based on the code ARM contributed in branches/ARM/sve-branch@246236]

2017-07-02  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* tree-ssa-strlen.c (strinfo): Rename the length field to
nonzero_chars.  Add a full_string_p field.
(compare_nonzero_chars, zero_length_string_p): New functions.
(get_addr_stridx): Add an offset_out parameter.
Use compare_nonzero_chars.
(get_stridx): Update accordingly.  Use compare_nonzero_chars.
(new_strinfo): Update after above changes to strinfo.
(set_endptr_and_length): Set full_string_p.
(get_string_length): Update after above changes to strinfo.
(unshare_strinfo): Update call to new_strinfo.
(maybe_invalidate): Likewise.
(get_stridx_plus_constant): Change off to unsigned HOST_WIDE_INT.
Use compare_nonzero_chars and zero_string_p.  Treat nonzero_chars
as a uhwi instead of an shwi.  Update after above changes to
strinfo and new_strinfo.
(zero_length_string): Assert that chainsi contains full strings.
Use zero_length_string_p.  Update call to new_strinfo.
(adjust_related_strinfos): Update after above changes to strinfo.
Copy full_string_p from origsi.
(adjust_last_stmt): Use zero_length_string_p.
(handle_builtin_strlen): Update after above changes to strinfo and
new_strinfo.  Install the lhs as the string length if the previous
entry didn't describe a full string.
(handle_builtin_strchr): Update after above changes to strinfo
and new_strinfo.
(handle_builtin_strcpy): Likewise.
(handle_builtin_strcat): Likewise.
(handle_builtin_malloc): Likewise.
(handle_pointer_plus): Likewise.
(handle_builtin_memcpy): Likewise.  Track nonzero characters
that aren't necessarily followed by a nul terminator.
(handle_char_store): Likewise.

gcc/testsuite/
* gcc.dg/strlenopt-32.c: New testcase.
* gcc.dg/strlenopt-33.c: Likewise.
* gcc.dg/strlenopt-33g.c: Likewise.
* gcc.dg/strlenopt-34.c: Likewise.
* gcc.dg/strlenopt-35.c: Likewise.

From-SVN: r249880
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/strlenopt-32.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strlenopt-33.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strlenopt-33g.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strlenopt-34.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strlenopt-35.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c