[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