[PATCH] Convert strlen pass from evrp to ranger.
Martin Sebor
msebor@gmail.com
Thu Oct 14 22:07:21 GMT 2021
On 10/9/21 12:47 PM, Aldy Hernandez via Gcc-patches wrote:
> We seem to be passing a lot of context around in the strlen code. I
> certainly don't want to contribute to more.
>
> Most of the handle_* functions are passing the gsi as well as either
> ptr_qry or rvals. That looks a bit messy. May I suggest putting all
> of that in the strlen pass object (well, the dom walker object, but we
> can rename it to be less dom centric)?
>
> Something like the attached (untested) patch could be the basis for
> further cleanups.
>
> Jakub, would this line of work interest you?
You didn't ask me but since no one spoke up against it let me add
some encouragement: this is exactly what I was envisioning and in
line with other such modernization we have been doing elsewhere.
Could you please submit it for review?
Martin
>
> Aldy
>
> On Fri, Oct 8, 2021 at 5:12 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>>
>> The following patch converts the strlen pass from evrp to ranger,
>> leaving DOM as the last remaining user.
>>
>> No additional cleanups have been done. For example, the strlen pass
>> still has uses of VR_ANTI_RANGE, and the sprintf still passes around
>> pairs of integers instead of using a proper range. Fixing this
>> could further improve these passes.
>>
>> As a further enhancement, if the relevant maintainers deem useful,
>> the domwalk could be removed from strlen. That is, unless the pass
>> needs it for something else.
>>
>> With ranger we are now able to remove the range calculation from
>> before_dom_children entirely. Just working with the ranger on-demand
>> catches all the strlen and sprintf testcases with the exception of
>> builtin-sprintf-warn-22.c which is due to a limitation of the sprintf
>> code. I have XFAILed the test and documented what the problem is.
>>
>> It looks like the same problem in the sprintf test triggers a false
>> positive in gimple-ssa-warn-access.cc so I have added
>> -Wno-format-overflow until it can be fixed.
>>
>> I can expand on the false positive if necessary, but the gist is that
>> this:
>>
>> _17 = strlen (_132);
>> _18 = strlen (_136);
>> _19 = _18 + _17;
>> if (_19 > 75)
>> goto <bb 59>; [0.00%]
>> else
>> goto <bb 61>; [100.00%]
>>
>> ...dominates the sprintf in BB61. This means that ranger can figure
>> out that the _17 and _18 are [0, 75]. On the other hand, evrp
>> returned a range of [0, 9223372036854775805] which presumably the
>> sprintf code was ignoring as a false positive here:
>>
>> char sizstr[80];
>> ...
>> ...
>> char *s1 = print_generic_expr_to_str (sizrng[1]);
>> gcc_checking_assert (strlen (s0) + strlen (s1)
>> < sizeof sizstr - 4);
>> sprintf (sizstr, "[%s, %s]", s0, s1);
>>
>> The warning triggers with:
>>
>> gimple-ssa-warn-access.cc: In member function ‘void {anonymous}::pass_waccess::maybe_check_access_sizes(rdwr_map*, tree, tree, gimple*)’:
>> gimple-ssa-warn-access.cc:2916:32: warning: ‘%s’ directive writing up to 75 bytes into a region of size between 2 and 77 [-Wformat-overflow=]
>> 2916 | sprintf (sizstr, "[%s, %s]", s0, s1);
>> | ^~~~~~~~~~
>> gimple-ssa-warn-access.cc:2916:23: note: ‘sprintf’ output between 5 and 155 bytes into a destination of size 80
>> 2916 | sprintf (sizstr, "[%s, %s]", s0, s1);
>> | ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>
>> On a positive note, these changes found two possible sprintf overflow
>> bugs in the C++ and Fortran front-ends which I have fixed below.
>>
>> Bootstrap and regtested on x86-64 Linux. I also ran it through our
>> callgrind harness and there was no overall change in overall
>> compilation time.
>>
>> OK?
>>
>> gcc/ChangeLog:
>>
>> * Makefile.in: Disable -Wformat-overflow for
>> gimple-ssa-warn-access.o.
>> * tree-ssa-strlen.c (compare_nonzero_chars): Pass statement
>> context to ranger.
>> (get_addr_stridx): Same.
>> (get_stridx): Same.
>> (get_range_strlen_dynamic): Same.
>> (handle_builtin_strlen): Same.
>> (handle_builtin_strchr): Same.
>> (handle_builtin_strcpy): Same.
>> (maybe_diag_stxncpy_trunc): Same.
>> (handle_builtin_stxncpy_strncat):
>> (handle_builtin_memcpy): Same.
>> (handle_builtin_strcat): Same.
>> (handle_alloc_call): Same.
>> (handle_builtin_memset): Same.
>> (handle_builtin_string_cmp): Same.
>> (handle_pointer_plus): Same.
>> (count_nonzero_bytes_addr): Same.
>> (count_nonzero_bytes): Same.
>> (handle_store): Same.
>> (fold_strstr_to_strncmp): Same.
>> (handle_integral_assign): Same.
>> (check_and_optimize_stmt): Same.
>> (class strlen_dom_walker): Replace evrp with ranger.
>> (strlen_dom_walker::before_dom_children): Remove evrp.
>> (strlen_dom_walker::after_dom_children): Remove evrp.
>>
>> gcc/cp/ChangeLog:
>>
>> * ptree.c (cxx_print_xnode): Add more space to pfx array.
>>
>> gcc/fortran/ChangeLog:
>>
>> * misc.c (gfc_dummy_typename): Make sure ts->kind is
>> non-negative.
>>
>> gcc/testsuite/ChangeLog:
>>
>> * gcc.dg/tree-ssa/builtin-sprintf-warn-22.c: XFAIL.
>> ---
>> gcc/Makefile.in | 1 +
>> gcc/cp/ptree.c | 2 +-
>> gcc/fortran/misc.c | 2 +-
>> .../gcc.dg/tree-ssa/builtin-sprintf-warn-22.c | 13 +-
>> gcc/tree-ssa-strlen.c | 145 ++++++++++--------
>> 5 files changed, 92 insertions(+), 71 deletions(-)
>>
>> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
>> index f36ffa4740b..dfd2a40e80a 100644
>> --- a/gcc/Makefile.in
>> +++ b/gcc/Makefile.in
>> @@ -222,6 +222,7 @@ libgcov-merge-tool.o-warn = -Wno-error
>> gimple-match.o-warn = -Wno-unused
>> generic-match.o-warn = -Wno-unused
>> dfp.o-warn = -Wno-strict-aliasing
>> +gimple-ssa-warn-access.o-warn = -Wno-format-overflow
>>
>> # All warnings have to be shut off in stage1 if the compiler used then
>> # isn't gcc; configure determines that. WARN_CFLAGS will be either
>> diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c
>> index 1dcd764af01..ca7884db39b 100644
>> --- a/gcc/cp/ptree.c
>> +++ b/gcc/cp/ptree.c
>> @@ -292,7 +292,7 @@ cxx_print_xnode (FILE *file, tree node, int indent)
>> for (unsigned ix = 0; ix != len; ix++)
>> {
>> binding_cluster *cluster = &BINDING_VECTOR_CLUSTER (node, ix);
>> - char pfx[24];
>> + char pfx[32];
>> for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++)
>> if (cluster->indices[jx].span)
>> {
>> diff --git a/gcc/fortran/misc.c b/gcc/fortran/misc.c
>> index 3d449ae17fe..c1520307c90 100644
>> --- a/gcc/fortran/misc.c
>> +++ b/gcc/fortran/misc.c
>> @@ -284,7 +284,7 @@ gfc_dummy_typename (gfc_typespec *ts)
>> {
>> if (ts->kind == gfc_default_character_kind)
>> sprintf(buffer, "CHARACTER(*)");
>> - else if (ts->kind < 10)
>> + else if (ts->kind >= 0 && ts->kind < 10)
>> sprintf(buffer, "CHARACTER(*,%d)", ts->kind);
>> else
>> sprintf(buffer, "CHARACTER(*,?)");
>> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c
>> index 685a4fd8c89..82eb5851c59 100644
>> --- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c
>> +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c
>> @@ -18,7 +18,18 @@ void g (char *s1, char *s2)
>> if (n + d + 1 >= 1025)
>> return;
>>
>> - sprintf (b, "%s.%s", s1, s2); // { dg-bogus "\\\[-Wformat-overflow" }
>> + /* Ranger can find ranges here:
>> + [1] n_6: size_t [0, 1023]
>> + [2] d_8: size_t [0, 1023]
>> +
>> + Whereas evrp can't really:
>> + [1] n_6: size_t [0, 9223372036854775805]
>> + [2] d_8: size_t [0, 9223372036854775805]
>> +
>> + This is causing the sprintf warning pass to issue a false
>> + positive here. */
>> +
>> + sprintf (b, "%s.%s", s1, s2); // { dg-bogus "\\\[-Wformat-overflow" "" { xfail *-*-* } }
>>
>> f (b);
>> }
>> diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
>> index 7c568a42d49..df0c2d5ee7a 100644
>> --- a/gcc/tree-ssa-strlen.c
>> +++ b/gcc/tree-ssa-strlen.c
>> @@ -59,7 +59,7 @@ along with GCC; see the file COPYING3. If not see
>> #include "tree-ssa-loop.h"
>> #include "tree-scalar-evolution.h"
>> #include "vr-values.h"
>> -#include "gimple-ssa-evrp-analyze.h"
>> +#include "gimple-range.h"
>> #include "tree-ssa.h"
>>
>> /* A vector indexed by SSA_NAME_VERSION. 0 means unknown, positive value
>> @@ -256,7 +256,8 @@ compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off)
>> Uses RVALS to determine length range. */
>>
>> static int
>> -compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
>> +compare_nonzero_chars (strinfo *si, gimple *stmt,
>> + unsigned HOST_WIDE_INT off,
>> range_query *rvals)
>> {
>> if (!si->nonzero_chars)
>> @@ -269,7 +270,7 @@ compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
>> return -1;
>>
>> value_range vr;
>> - if (!rvals->range_of_expr (vr, si->nonzero_chars, si->stmt))
>> + if (!rvals->range_of_expr (vr, si->nonzero_chars, stmt))
>> return -1;
>> value_range_kind rng = vr.kind ();
>> if (rng != VR_RANGE)
>> @@ -324,7 +325,8 @@ get_next_strinfo (strinfo *si)
>> information. */
>>
>> static int
>> -get_addr_stridx (tree exp, tree ptr, unsigned HOST_WIDE_INT *offset_out,
>> +get_addr_stridx (tree exp, gimple *stmt,
>> + tree ptr, unsigned HOST_WIDE_INT *offset_out,
>> range_query *rvals = NULL)
>> {
>> HOST_WIDE_INT off;
>> @@ -363,7 +365,7 @@ get_addr_stridx (tree exp, tree ptr, unsigned HOST_WIDE_INT *offset_out,
>> unsigned HOST_WIDE_INT rel_off
>> = (unsigned HOST_WIDE_INT) off - last->offset;
>> strinfo *si = get_strinfo (last->idx);
>> - if (si && compare_nonzero_chars (si, rel_off, rvals) >= 0)
>> + if (si && compare_nonzero_chars (si, stmt, rel_off, rvals) >= 0)
>> {
>> if (offset_out)
>> {
>> @@ -385,7 +387,8 @@ get_addr_stridx (tree exp, tree ptr, unsigned HOST_WIDE_INT *offset_out,
>> When nonnull, uses RVALS to determine range information. */
>>
>> static int
>> -get_stridx (tree exp, wide_int offrng[2] = NULL, range_query *rvals = NULL)
>> +get_stridx (tree exp, gimple *stmt,
>> + wide_int offrng[2] = NULL, range_query *rvals = NULL)
>> {
>> if (offrng)
>> offrng[0] = offrng[1] = wi::zero (TYPE_PRECISION (ptrdiff_type_node));
>> @@ -522,7 +525,7 @@ get_stridx (tree exp, wide_int offrng[2] = NULL, range_query *rvals = NULL)
>>
>> if (TREE_CODE (exp) == ADDR_EXPR)
>> {
>> - int idx = get_addr_stridx (TREE_OPERAND (exp, 0), exp, NULL);
>> + int idx = get_addr_stridx (TREE_OPERAND (exp, 0), stmt, exp, NULL);
>> if (idx != 0)
>> return idx;
>> }
>> @@ -1016,7 +1019,7 @@ get_range_strlen_dynamic (tree src, gimple *stmt,
>> c_strlen_data *pdata, bitmap *visited,
>> range_query *rvals, unsigned *pssa_def_max)
>> {
>> - int idx = get_stridx (src);
>> + int idx = get_stridx (src, stmt);
>> if (!idx)
>> {
>> if (TREE_CODE (src) == SSA_NAME)
>> @@ -2124,7 +2127,7 @@ handle_builtin_strlen (gimple_stmt_iterator *gsi)
>> tree src = gimple_call_arg (stmt, 0);
>> tree bound = (DECL_FUNCTION_CODE (callee) == BUILT_IN_STRNLEN
>> ? gimple_call_arg (stmt, 1) : NULL_TREE);
>> - int idx = get_stridx (src);
>> + int idx = get_stridx (src, stmt);
>> if (idx || (bound && integer_zerop (bound)))
>> {
>> strinfo *si = NULL;
>> @@ -2304,7 +2307,7 @@ handle_builtin_strchr (gimple_stmt_iterator *gsi)
>> if (!check_nul_terminated_array (NULL_TREE, src))
>> return;
>>
>> - int idx = get_stridx (src);
>> + int idx = get_stridx (src, stmt);
>> if (idx)
>> {
>> strinfo *si = NULL;
>> @@ -2411,12 +2414,12 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
>> src = gimple_call_arg (stmt, 1);
>> dst = gimple_call_arg (stmt, 0);
>> lhs = gimple_call_lhs (stmt);
>> - idx = get_stridx (src);
>> + idx = get_stridx (src, stmt);
>> si = NULL;
>> if (idx > 0)
>> si = get_strinfo (idx);
>>
>> - didx = get_stridx (dst);
>> + didx = get_stridx (dst, stmt);
>> olddsi = NULL;
>> oldlen = NULL_TREE;
>> if (didx > 0)
>> @@ -2818,7 +2821,7 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
>> when ssa_ver_to_stridx is empty. That implies the caller isn't
>> running under the control of this pass and ssa_ver_to_stridx hasn't
>> been created yet. */
>> - int sidx = ssa_ver_to_stridx.length () ? get_stridx (src) : 0;
>> + int sidx = ssa_ver_to_stridx.length () ? get_stridx (src, stmt) : 0;
>> if (sidx < 0 && wi::gtu_p (cntrange[0], ~sidx))
>> return false;
>>
>> @@ -3092,7 +3095,7 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi)
>> a lower bound). */
>> tree dstlenp1 = NULL_TREE, srclenp1 = NULL_TREE;;
>>
>> - int didx = get_stridx (dst);
>> + int didx = get_stridx (dst, stmt);
>> if (strinfo *sidst = didx > 0 ? get_strinfo (didx) : NULL)
>> {
>> /* Compute the size of the destination string including the nul
>> @@ -3118,7 +3121,7 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi)
>> dst = sidst->ptr;
>> }
>>
>> - int sidx = get_stridx (src);
>> + int sidx = get_stridx (src, stmt);
>> strinfo *sisrc = sidx > 0 ? get_strinfo (sidx) : NULL;
>> if (sisrc)
>> {
>> @@ -3228,7 +3231,7 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
>> tree src = gimple_call_arg (stmt, 1);
>> tree dst = gimple_call_arg (stmt, 0);
>>
>> - int didx = get_stridx (dst);
>> + int didx = get_stridx (dst, stmt);
>> strinfo *olddsi = NULL;
>> if (didx > 0)
>> olddsi = get_strinfo (didx);
>> @@ -3242,7 +3245,7 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
>> adjust_last_stmt (olddsi, stmt, false, ptr_qry);
>> }
>>
>> - int idx = get_stridx (src);
>> + int idx = get_stridx (src, stmt);
>> if (idx == 0)
>> return;
>>
>> @@ -3418,7 +3421,7 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi,
>>
>> tree lhs = gimple_call_lhs (stmt);
>>
>> - didx = get_stridx (dst);
>> + didx = get_stridx (dst, stmt);
>> if (didx < 0)
>> return;
>>
>> @@ -3428,7 +3431,7 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi,
>>
>> srclen = NULL_TREE;
>> si = NULL;
>> - idx = get_stridx (src);
>> + idx = get_stridx (src, stmt);
>> if (idx < 0)
>> srclen = build_int_cst (size_type_node, ~idx);
>> else if (idx > 0)
>> @@ -3650,7 +3653,7 @@ handle_alloc_call (enum built_in_function bcode, gimple_stmt_iterator *gsi)
>> if (lhs == NULL_TREE)
>> return;
>>
>> - gcc_assert (get_stridx (lhs) == 0);
>> + gcc_assert (get_stridx (lhs, stmt) == 0);
>> int idx = new_stridx (lhs);
>> tree length = NULL_TREE;
>> if (bcode == BUILT_IN_CALLOC)
>> @@ -3687,7 +3690,7 @@ handle_builtin_memset (gimple_stmt_iterator *gsi, bool *zero_write,
>> tree ptr = gimple_call_arg (memset_stmt, 0);
>> /* Set to the non-constant offset added to PTR. */
>> wide_int offrng[2];
>> - int idx1 = get_stridx (ptr, offrng, ptr_qry.rvals);
>> + int idx1 = get_stridx (ptr, memset_stmt, offrng, ptr_qry.rvals);
>> if (idx1 <= 0)
>> return false;
>> strinfo *si1 = get_strinfo (idx1);
>> @@ -4178,8 +4181,8 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi, range_query *rvals)
>>
>> tree arg1 = gimple_call_arg (stmt, 0);
>> tree arg2 = gimple_call_arg (stmt, 1);
>> - int idx1 = get_stridx (arg1);
>> - int idx2 = get_stridx (arg2);
>> + int idx1 = get_stridx (arg1, stmt);
>> + int idx2 = get_stridx (arg2, stmt);
>>
>> /* For strncmp set to the value of the third argument if known. */
>> HOST_WIDE_INT bound = -1;
>> @@ -4318,7 +4321,7 @@ handle_pointer_plus (gimple_stmt_iterator *gsi)
>> {
>> gimple *stmt = gsi_stmt (*gsi);
>> tree lhs = gimple_assign_lhs (stmt), off;
>> - int idx = get_stridx (gimple_assign_rhs1 (stmt));
>> + int idx = get_stridx (gimple_assign_rhs1 (stmt), stmt);
>> strinfo *si, *zsi;
>>
>> if (idx == 0)
>> @@ -4396,7 +4399,8 @@ nonzero_bytes_for_type (tree type, unsigned lenrange[3],
>> }
>>
>> static bool
>> -count_nonzero_bytes_addr (tree, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
>> +count_nonzero_bytes_addr (tree, gimple *stmt,
>> + unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
>> unsigned [3], bool *, bool *, bool *,
>> range_query *, ssa_name_limit_t &);
>>
>> @@ -4416,7 +4420,8 @@ count_nonzero_bytes_addr (tree, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
>> Returns true on success and false otherwise. */
>>
>> static bool
>> -count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
>> +count_nonzero_bytes (tree exp, gimple *stmt,
>> + unsigned HOST_WIDE_INT offset,
>> unsigned HOST_WIDE_INT nbytes,
>> unsigned lenrange[3], bool *nulterm,
>> bool *allnul, bool *allnonnul, range_query *rvals,
>> @@ -4435,7 +4440,8 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
>> exact value is not known) recurse once to set the range
>> for an arbitrary constant. */
>> exp = build_int_cst (type, 1);
>> - return count_nonzero_bytes (exp, offset, 1, lenrange,
>> + return count_nonzero_bytes (exp, stmt,
>> + offset, 1, lenrange,
>> nulterm, allnul, allnonnul, rvals, snlim);
>> }
>>
>> @@ -4462,7 +4468,8 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
>> for (unsigned i = 0; i != n; i++)
>> {
>> tree def = gimple_phi_arg_def (stmt, i);
>> - if (!count_nonzero_bytes (def, offset, nbytes, lenrange, nulterm,
>> + if (!count_nonzero_bytes (def, stmt,
>> + offset, nbytes, lenrange, nulterm,
>> allnul, allnonnul, rvals, snlim))
>> return false;
>> }
>> @@ -4519,7 +4526,8 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
>> return false;
>>
>> /* Handle MEM_REF = SSA_NAME types of assignments. */
>> - return count_nonzero_bytes_addr (arg, offset, nbytes, lenrange, nulterm,
>> + return count_nonzero_bytes_addr (arg, stmt,
>> + offset, nbytes, lenrange, nulterm,
>> allnul, allnonnul, rvals, snlim);
>> }
>>
>> @@ -4631,13 +4639,14 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
>> bytes that are pointed to by EXP, which should be a pointer. */
>>
>> static bool
>> -count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
>> +count_nonzero_bytes_addr (tree exp, gimple *stmt,
>> + unsigned HOST_WIDE_INT offset,
>> unsigned HOST_WIDE_INT nbytes,
>> unsigned lenrange[3], bool *nulterm,
>> bool *allnul, bool *allnonnul,
>> range_query *rvals, ssa_name_limit_t &snlim)
>> {
>> - int idx = get_stridx (exp);
>> + int idx = get_stridx (exp, stmt);
>> if (idx > 0)
>> {
>> strinfo *si = get_strinfo (idx);
>> @@ -4653,7 +4662,7 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
>> && TREE_CODE (si->nonzero_chars) == SSA_NAME)
>> {
>> value_range vr;
>> - rvals->range_of_expr (vr, si->nonzero_chars, si->stmt);
>> + rvals->range_of_expr (vr, si->nonzero_chars, stmt);
>> if (vr.kind () != VR_RANGE)
>> return false;
>>
>> @@ -4699,7 +4708,8 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
>> }
>>
>> if (TREE_CODE (exp) == ADDR_EXPR)
>> - return count_nonzero_bytes (TREE_OPERAND (exp, 0), offset, nbytes,
>> + return count_nonzero_bytes (TREE_OPERAND (exp, 0), stmt,
>> + offset, nbytes,
>> lenrange, nulterm, allnul, allnonnul, rvals,
>> snlim);
>>
>> @@ -4719,7 +4729,8 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
>> for (unsigned i = 0; i != n; i++)
>> {
>> tree def = gimple_phi_arg_def (stmt, i);
>> - if (!count_nonzero_bytes_addr (def, offset, nbytes, lenrange,
>> + if (!count_nonzero_bytes_addr (def, stmt,
>> + offset, nbytes, lenrange,
>> nulterm, allnul, allnonnul, rvals,
>> snlim))
>> return false;
>> @@ -4747,7 +4758,8 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
>> (the results of strlen). */
>>
>> static bool
>> -count_nonzero_bytes (tree expr_or_type, unsigned lenrange[3], bool *nulterm,
>> +count_nonzero_bytes (tree expr_or_type, gimple *stmt,
>> + unsigned lenrange[3], bool *nulterm,
>> bool *allnul, bool *allnonnul, range_query *rvals)
>> {
>> if (TYPE_P (expr_or_type))
>> @@ -4765,7 +4777,8 @@ count_nonzero_bytes (tree expr_or_type, unsigned lenrange[3], bool *nulterm,
>>
>> ssa_name_limit_t snlim;
>> tree expr = expr_or_type;
>> - return count_nonzero_bytes (expr, 0, 0, lenrange, nulterm, allnul, allnonnul,
>> + return count_nonzero_bytes (expr, stmt,
>> + 0, 0, lenrange, nulterm, allnul, allnonnul,
>> rvals, snlim);
>> }
>>
>> @@ -4818,18 +4831,19 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
>> least OFFSET nonzero characters. This is trivially true if
>> OFFSET is zero. */
>> offset = tree_to_uhwi (mem_offset);
>> - idx = get_stridx (TREE_OPERAND (lhs, 0));
>> + idx = get_stridx (TREE_OPERAND (lhs, 0), stmt);
>> if (idx > 0)
>> si = get_strinfo (idx);
>> if (offset == 0)
>> ssaname = TREE_OPERAND (lhs, 0);
>> - else if (si == NULL || compare_nonzero_chars (si, offset, rvals) < 0)
>> + else if (si == NULL
>> + || compare_nonzero_chars (si, stmt, offset, rvals) < 0)
>> {
>> *zero_write = rhs ? initializer_zerop (rhs) : false;
>>
>> bool dummy;
>> unsigned lenrange[] = { UINT_MAX, 0, 0 };
>> - if (count_nonzero_bytes (rhs ? rhs : storetype, lenrange,
>> + if (count_nonzero_bytes (rhs ? rhs : storetype, stmt, lenrange,
>> &dummy, &dummy, &dummy, rvals))
>> maybe_warn_overflow (stmt, true, lenrange[2], ptr_qry);
>>
>> @@ -4839,7 +4853,7 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
>> }
>> else
>> {
>> - idx = get_addr_stridx (lhs, NULL_TREE, &offset, rvals);
>> + idx = get_addr_stridx (lhs, stmt, NULL_TREE, &offset, rvals);
>> if (idx > 0)
>> si = get_strinfo (idx);
>> }
>> @@ -4862,7 +4876,8 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
>> bool full_string_p;
>>
>> const bool ranges_valid
>> - = count_nonzero_bytes (rhs ? rhs : storetype, lenrange, &full_string_p,
>> + = count_nonzero_bytes (rhs ? rhs : storetype, stmt,
>> + lenrange, &full_string_p,
>> &storing_all_zeros_p, &storing_all_nonzero_p,
>> rvals);
>>
>> @@ -4895,15 +4910,18 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
>> {
>> /* The offset of the last stored byte. */
>> unsigned HOST_WIDE_INT endoff = offset + lenrange[2] - 1;
>> - store_before_nul[0] = compare_nonzero_chars (si, offset, rvals);
>> + store_before_nul[0]
>> + = compare_nonzero_chars (si, stmt, offset, rvals);
>> if (endoff == offset)
>> store_before_nul[1] = store_before_nul[0];
>> else
>> - store_before_nul[1] = compare_nonzero_chars (si, endoff, rvals);
>> + store_before_nul[1]
>> + = compare_nonzero_chars (si, stmt, endoff, rvals);
>> }
>> else
>> {
>> - store_before_nul[0] = compare_nonzero_chars (si, offset, rvals);
>> + store_before_nul[0]
>> + = compare_nonzero_chars (si, stmt, offset, rvals);
>> store_before_nul[1] = store_before_nul[0];
>> gcc_assert (offset == 0 || store_before_nul[0] >= 0);
>> }
>> @@ -5128,7 +5146,7 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
>> {
>> tree arg1 = gimple_call_arg (call_stmt, 1);
>> tree arg1_len = NULL_TREE;
>> - int idx = get_stridx (arg1);
>> + int idx = get_stridx (arg1, call_stmt);
>>
>> if (idx)
>> {
>> @@ -5342,7 +5360,7 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
>> tree rhs1 = gimple_assign_rhs1 (stmt);
>> if (code == MEM_REF)
>> {
>> - idx = get_stridx (TREE_OPERAND (rhs1, 0));
>> + idx = get_stridx (TREE_OPERAND (rhs1, 0), stmt);
>> if (idx > 0)
>> {
>> strinfo *si = get_strinfo (idx);
>> @@ -5359,7 +5377,7 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
>> }
>> }
>> if (idx <= 0)
>> - idx = get_addr_stridx (rhs1, NULL_TREE, &coff);
>> + idx = get_addr_stridx (rhs1, stmt, NULL_TREE, &coff);
>> if (idx > 0)
>> {
>> strinfo *si = get_strinfo (idx);
>> @@ -5421,7 +5439,8 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
>> unsigned lenrange[] = { UINT_MAX, 0, 0 };
>> tree rhs = gimple_assign_rhs1 (stmt);
>> const bool ranges_valid
>> - = count_nonzero_bytes (rhs, lenrange, &full_string_p,
>> + = count_nonzero_bytes (rhs, stmt,
>> + lenrange, &full_string_p,
>> &storing_all_zeros_p, &storing_all_nonzero_p,
>> rvals);
>> if (ranges_valid)
>> @@ -5520,7 +5539,7 @@ check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
>> || (gimple_assign_cast_p (stmt)
>> && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
>> {
>> - int idx = get_stridx (gimple_assign_rhs1 (stmt));
>> + int idx = get_stridx (gimple_assign_rhs1 (stmt), stmt);
>> ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = idx;
>> }
>> else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
>> @@ -5602,20 +5621,20 @@ class strlen_dom_walker : public dom_walker
>> public:
>> strlen_dom_walker (cdi_direction direction)
>> : dom_walker (direction),
>> - evrp (false),
>> - ptr_qry (&evrp, &var_cache),
>> - var_cache (),
>> - m_cleanup_cfg (false)
>> - { }
>> + ptr_qry (&m_ranger, &var_cache),
>> + var_cache (),
>> + m_cleanup_cfg (false)
>> + {
>> + }
>>
>> ~strlen_dom_walker ();
>>
>> virtual edge before_dom_children (basic_block);
>> virtual void after_dom_children (basic_block);
>>
>> - /* EVRP analyzer used for printf argument range processing, and
>> + /* Ranger used for printf argument range processing, and
>> to track strlen results across integer variable assignments. */
>> - evrp_range_analyzer evrp;
>> + gimple_ranger m_ranger;
>>
>> /* A pointer_query object and its cache to store information about
>> pointers and their targets in. */
>> @@ -5640,8 +5659,6 @@ strlen_dom_walker::~strlen_dom_walker ()
>> edge
>> strlen_dom_walker::before_dom_children (basic_block bb)
>> {
>> - evrp.enter (bb);
>> -
>> basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
>>
>> if (dombb == NULL)
>> @@ -5698,12 +5715,12 @@ strlen_dom_walker::before_dom_children (basic_block bb)
>> tree result = gimple_phi_result (phi);
>> if (!virtual_operand_p (result) && POINTER_TYPE_P (TREE_TYPE (result)))
>> {
>> - int idx = get_stridx (gimple_phi_arg_def (phi, 0));
>> + int idx = get_stridx (gimple_phi_arg_def (phi, 0), phi);
>> if (idx != 0)
>> {
>> unsigned int i, n = gimple_phi_num_args (phi);
>> for (i = 1; i < n; i++)
>> - if (idx != get_stridx (gimple_phi_arg_def (phi, i)))
>> + if (idx != get_stridx (gimple_phi_arg_def (phi, i), phi))
>> break;
>> if (i == n)
>> ssa_ver_to_stridx[SSA_NAME_VERSION (result)] = idx;
>> @@ -5716,12 +5733,6 @@ strlen_dom_walker::before_dom_children (basic_block bb)
>> /* Attempt to optimize individual statements. */
>> for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
>> {
>> - gimple *stmt = gsi_stmt (gsi);
>> -
>> - /* First record ranges generated by this statement so they
>> - can be used by printf argument processing. */
>> - evrp.record_ranges_from_stmt (stmt, false);
>> -
>> /* Reset search depth preformance counter. */
>> ptr_qry.depth = 0;
>>
>> @@ -5744,8 +5755,6 @@ strlen_dom_walker::before_dom_children (basic_block bb)
>> void
>> strlen_dom_walker::after_dom_children (basic_block bb)
>> {
>> - evrp.leave (bb);
>> -
>> if (bb->aux)
>> {
>> stridx_to_strinfo = ((vec<strinfo *, va_heap, vl_embed> *) bb->aux);
>> --
>> 2.31.1
>>
More information about the Gcc-patches
mailing list