From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qt1-x82e.google.com (mail-qt1-x82e.google.com [IPv6:2607:f8b0:4864:20::82e]) by sourceware.org (Postfix) with ESMTPS id EB36F3858419 for ; Thu, 14 Oct 2021 22:07:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org EB36F3858419 Received: by mail-qt1-x82e.google.com with SMTP id b12so7187115qtq.3 for ; Thu, 14 Oct 2021 15:07:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=hzAnACTH13PYXwjN4dJTWHzlpYlx7Hc49DhDllfcYWs=; b=5RkipT+U5zKvT7PvXazaQXOx4+a1jbseLxyg1vjqfb8i+p0/hEZ7+FNpaFHH9oo8FJ u3oWQX0v4x4gwJVCT8IcPOabe5JbFNiBanmZkp+o2Sw6nmo8OxHAceXCG/2vUb4Ox0hM eoDWxj2KXcrhjipaWngPAGV9MRleLXp88azpxXqNqR292M10f9Kd6AQpO7p/1pYNfqpI je1wWvU6SWHRB5q+msTJya3YGdnjC4yhLrCcYlPWyYm3AUlgUdWzYWYHoLPS30Jhja12 py5JRYW0cF5aJuTtpB5doatxlGerJJAyX3XHes9turnLaUK9u+NkwAr9Co8d3W5CfxWk ZSrg== X-Gm-Message-State: AOAM530tnt4Gr6geC0Fko7SWdG1UBpQCtAg4Tj6O0EU7C3oq0ZEsktsk 82aBEICrIFhvPk5HIpkYV4DXmV5JEt0= X-Google-Smtp-Source: ABdhPJwVKt3h9g21aw3fKUELIRzBFDMqYAYohmLxoNjpm7d9Sb2mSeLnOCbufotM37Nk/1p44spljQ== X-Received: by 2002:a05:622a:c7:: with SMTP id p7mr9870529qtw.356.1634249242983; Thu, 14 Oct 2021 15:07:22 -0700 (PDT) Received: from [192.168.0.41] (184-96-250-116.hlrn.qwest.net. [184.96.250.116]) by smtp.gmail.com with ESMTPSA id u189sm1811981qkh.14.2021.10.14.15.07.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 14 Oct 2021 15:07:22 -0700 (PDT) Subject: Re: [PATCH] Convert strlen pass from evrp to ranger. To: Aldy Hernandez , Jakub Jelinek Cc: Martin Sebor , GCC patches References: <20211008151222.37790-1-aldyh@redhat.com> From: Martin Sebor Message-ID: <2952e615-3607-7d6a-d214-739c90744397@gmail.com> Date: Thu, 14 Oct 2021 16:07:21 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Oct 2021 22:07:27 -0000 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 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 ; [0.00%] >> else >> goto ; [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 *) bb->aux); >> -- >> 2.31.1 >>