[gcc(refs/users/aldyh/heads/ranger-staging)] Pass gimple context to functions in strlen/sprintf passes.
Aldy Hernandez
aldyh@gcc.gnu.org
Thu Sep 10 08:15:03 GMT 2020
https://gcc.gnu.org/g:08ca0bda645a75690d8589a4c2307bd89a3efeb7
commit 08ca0bda645a75690d8589a4c2307bd89a3efeb7
Author: Aldy Hernandez <aldyh@redhat.com>
Date: Wed Sep 9 09:50:45 2020 +0200
Pass gimple context to functions in strlen/sprintf passes.
Diff:
---
gcc/builtins.c | 14 +++++------
gcc/gimple-ssa-sprintf.c | 8 ++++---
gcc/tree-ssa-strlen.c | 60 ++++++++++++++++++++++++++----------------------
gcc/tree-ssa-strlen.h | 5 ++--
4 files changed, 48 insertions(+), 39 deletions(-)
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 8845816aebd..fc6a0acf842 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3936,7 +3936,7 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
if (!rng1)
rng1 = rng1_buf;
- if (!get_range (size, rng1, rvals))
+ if (!get_range (size, stmt, rng1, rvals))
return NULL_TREE;
if (argidx2 > nargs && TREE_CODE (size) == INTEGER_CST)
@@ -3946,7 +3946,7 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
of the upper bounds as a constant. Ignore anti-ranges. */
tree n = argidx2 < nargs ? gimple_call_arg (stmt, argidx2) : integer_one_node;
wide_int rng2[2];
- if (!get_range (n, rng2, rvals))
+ if (!get_range (n, stmt, rng2, rvals))
return NULL_TREE;
/* Extend to the maximum precision to avoid overflow. */
@@ -3974,11 +3974,11 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
result but accepts offset_int instead. */
static bool
-get_range (tree x, signop sgn, offset_int r[2],
+get_range (tree x, gimple *stmt, signop sgn, offset_int r[2],
const vr_values *rvals /* = NULL */)
{
wide_int wr[2];
- if (!get_range (x, wr, rvals))
+ if (!get_range (x, stmt, wr, rvals))
return false;
r[0] = offset_int::from (wr[0], sgn);
@@ -4100,7 +4100,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
offset_int orng[2];
tree off = TREE_OPERAND (ptr, 1);
- if (!get_range (off, SIGNED, orng, rvals))
+ if (!get_range (off, NULL, SIGNED, orng, rvals))
/* Fail unless the size of the object is zero. */
return pref->sizrng[0] == 0 && pref->sizrng[0] == pref->sizrng[1];
@@ -4181,7 +4181,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
offset to the maximum. */
offset_int orng[2];
tree off = gimple_assign_rhs2 (stmt);
- if (!get_range (off, SIGNED, orng, rvals)
+ if (!get_range (off, stmt, SIGNED, orng, rvals)
|| !wi::les_p (orng[0], orng[1]))
{
orng[0] = wi::to_offset (TYPE_MIN_VALUE (ptrdiff_type_node));
@@ -4206,7 +4206,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
&& !array_at_struct_end_p (ptr))
{
if (tree size = TYPE_SIZE_UNIT (type))
- return get_range (size, UNSIGNED, pref->sizrng, rvals);
+ return get_range (size, NULL, UNSIGNED, pref->sizrng, rvals);
}
return false;
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 70b031fe7b9..f4688a86237 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -2014,7 +2014,8 @@ format_floating (const directive &dir, tree arg, const vr_values *)
Used by the format_string function below. */
static fmtresult
-get_string_length (tree str, unsigned eltsize, const vr_values *vr)
+get_string_length (tree str, gimple *stmt, unsigned eltsize,
+ const vr_values *vr)
{
if (!str)
return fmtresult ();
@@ -2025,7 +2026,7 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr)
c_strlen_data lendata = { };
lendata.maxbound = str;
if (eltsize == 1)
- get_range_strlen_dynamic (str, &lendata, vr);
+ get_range_strlen_dynamic (str, stmt, &lendata, vr);
else
{
/* Determine the length of the shortest and longest string referenced
@@ -2462,7 +2463,8 @@ format_string (const directive &dir, tree arg, const vr_values *vr_values)
gcc_checking_assert (count_by == 2 || count_by == 4);
}
- fmtresult slen = get_string_length (arg, count_by, vr_values);
+ gimple *stmt = dir.info->callstmt;
+ fmtresult slen = get_string_length (arg, stmt, count_by, vr_values);
if (slen.range.min == slen.range.max
&& slen.range.min < HOST_WIDE_INT_MAX)
{
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index fbaee745f7d..62828dfde1e 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -200,7 +200,8 @@ static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *);
to determine the range, otherwise get_range_info. */
tree
-get_range (tree val, wide_int minmax[2], const vr_values *rvals /* = NULL */)
+get_range (tree val, gimple *stmt, wide_int minmax[2],
+ const vr_values *rvals /* = NULL */)
{
if (TREE_CODE (val) == INTEGER_CST)
{
@@ -211,7 +212,7 @@ get_range (tree val, wide_int minmax[2], const vr_values *rvals /* = NULL */)
if (TREE_CODE (val) != SSA_NAME)
return NULL_TREE;
- if (rvals)
+ if (rvals && stmt)
{
/* The range below may be "inaccurate" if a constant has been
substituted earlier for VAL by this pass that hasn't been
@@ -219,7 +220,7 @@ get_range (tree val, wide_int minmax[2], const vr_values *rvals /* = NULL */)
on-demand VRP if/when it becomes available (hopefully in
GCC 11). */
const value_range *vr
- = (CONST_CAST (class vr_values *, rvals)->get_value_range (val));
+ = (CONST_CAST (class vr_values *, rvals)->get_value_range (val, stmt));
value_range_kind rng = vr->kind ();
if (rng != VR_RANGE || !range_int_cst_p (vr))
return NULL_TREE;
@@ -276,7 +277,7 @@ compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
const value_range_equiv *vr
= (CONST_CAST (class vr_values *, rvals)
- ->get_value_range (si->nonzero_chars));
+ ->get_value_range (si->nonzero_chars, si->stmt));
value_range_kind rng = vr->kind ();
if (rng != VR_RANGE || !range_int_cst_p (vr))
@@ -474,7 +475,7 @@ get_stridx (tree exp, wide_int offrng[2] = NULL, const vr_values *rvals = NULL)
return the index corresponding to the SSA_NAME.
Do this irrespective of the whether the offset
is known. */
- if (get_range (off, offrng, rvals))
+ if (get_range (off, def_stmt, offrng, rvals))
{
/* When the offset range is known, increment it
it by the constant offset computed in prior
@@ -911,7 +912,7 @@ dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
{
const value_range *vr
= CONST_CAST (class vr_values *, rvals)
- ->get_value_range (si->nonzero_chars);
+ ->get_value_range (si->nonzero_chars, si->stmt);
rng = vr->kind ();
if (range_int_cst_p (vr))
{
@@ -922,6 +923,7 @@ dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
rng = VR_UNDEFINED;
}
else
+ // FIXME: call ranger
rng = get_range_info (si->nonzero_chars, &min, &max);
if (rng == VR_RANGE || rng == VR_ANTI_RANGE)
@@ -1009,7 +1011,8 @@ dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
recursion. */
static bool
-get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
+get_range_strlen_dynamic (tree src, gimple *stmt,
+ c_strlen_data *pdata, bitmap *visited,
const vr_values *rvals, unsigned *pssa_def_max)
{
int idx = get_stridx (src);
@@ -1042,8 +1045,8 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
continue;
c_strlen_data argdata = { };
- if (get_range_strlen_dynamic (arg, &argdata, visited, rvals,
- pssa_def_max))
+ if (get_range_strlen_dynamic (arg, phi, &argdata, visited,
+ rvals, pssa_def_max))
{
/* Set the DECL of an unterminated array this argument
refers to if one hasn't been found yet. */
@@ -1112,7 +1115,7 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
{
const value_range_equiv *vr
= CONST_CAST (class vr_values *, rvals)
- ->get_value_range (si->nonzero_chars);
+ ->get_value_range (si->nonzero_chars, si->stmt);
if (vr->kind () == VR_RANGE
&& range_int_cst_p (vr))
{
@@ -1158,7 +1161,7 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
{
const value_range_equiv *vr
= CONST_CAST (class vr_values *, rvals)
- ->get_value_range (si->nonzero_chars);
+ ->get_value_range (si->nonzero_chars, stmt);
if (vr->kind () == VR_RANGE
&& range_int_cst_p (vr))
{
@@ -1201,14 +1204,14 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
points to EVRP info. */
void
-get_range_strlen_dynamic (tree src, c_strlen_data *pdata,
+get_range_strlen_dynamic (tree src, gimple *stmt, c_strlen_data *pdata,
const vr_values *rvals)
{
bitmap visited = NULL;
tree maxbound = pdata->maxbound;
unsigned limit = param_ssa_name_def_chain_limit;
- if (!get_range_strlen_dynamic (src, pdata, &visited, rvals, &limit))
+ if (!get_range_strlen_dynamic (src, stmt, pdata, &visited, rvals, &limit))
{
/* On failure extend the length range to an impossible maximum
(a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
@@ -1959,7 +1962,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
tree off = TREE_OPERAND (ref, 1);
ref = TREE_OPERAND (ref, 0);
wide_int rng[2];
- if (get_range (off, rng, rvals))
+ if (get_range (off, stmt, rng, rvals))
{
/* Convert offsets to the maximum precision. */
offrng[0] = widest_int::from (rng[0], SIGNED);
@@ -1977,7 +1980,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
tree mem_off = TREE_OPERAND (ref, 1);
ref = TREE_OPERAND (ref, 0);
wide_int rng[2];
- if (get_range (mem_off, rng, rvals))
+ if (get_range (mem_off, stmt, rng, rvals))
{
offrng[0] += widest_int::from (rng[0], SIGNED);
offrng[1] += widest_int::from (rng[1], SIGNED);
@@ -2049,7 +2052,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
}
wide_int rng[2];
- if (get_range (destsize, rng, rvals))
+ if (get_range (destsize, stmt, rng, rvals))
{
sizrng[0] = widest_int::from (rng[0], UNSIGNED);
sizrng[1] = widest_int::from (rng[1], UNSIGNED);
@@ -2080,7 +2083,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
return;
wide_int rng[2];
- if (!get_range (len, rng, rvals))
+ if (!get_range (len, stmt, rng, rvals))
return;
widest_int lenrng[2] =
@@ -2231,7 +2234,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
if (destoff)
{
wide_int rng[2];
- if (get_range (destoff, rng))
+ if (get_range (destoff, stmt, rng))
{
offrng[0] = widest_int::from (rng[0], SIGNED);
offrng[1] = widest_int::from (rng[1], SIGNED);
@@ -4103,7 +4106,8 @@ handle_builtin_memcmp (gimple_stmt_iterator *gsi)
determine range information. Returns true on success. */
static bool
-get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
+get_len_or_size (gimple *stmt, tree arg, int idx,
+ unsigned HOST_WIDE_INT lenrng[2],
unsigned HOST_WIDE_INT *size, bool *nulterm,
const vr_values *rvals)
{
@@ -4158,7 +4162,7 @@ get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
/* Set MAXBOUND to an arbitrary non-null non-integer node as a request
to have it set to the length of the longest string in a PHI. */
lendata.maxbound = arg;
- get_range_strlen_dynamic (arg, &lendata, rvals);
+ get_range_strlen_dynamic (arg, stmt, &lendata, rvals);
unsigned HOST_WIDE_INT maxbound = HOST_WIDE_INT_M1U;
if (tree_fits_uhwi_p (lendata.maxbound)
@@ -4216,7 +4220,7 @@ get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
Otherwise return null. */
static tree
-strxcmp_eqz_result (tree arg1, int idx1, tree arg2, int idx2,
+strxcmp_eqz_result (gimple *stmt, tree arg1, int idx1, tree arg2, int idx2,
unsigned HOST_WIDE_INT bound, unsigned HOST_WIDE_INT len[2],
unsigned HOST_WIDE_INT *psize, const vr_values *rvals)
{
@@ -4225,8 +4229,8 @@ strxcmp_eqz_result (tree arg1, int idx1, tree arg2, int idx2,
bool nul1, nul2;
unsigned HOST_WIDE_INT siz1, siz2;
unsigned HOST_WIDE_INT len1rng[2], len2rng[2];
- if (!get_len_or_size (arg1, idx1, len1rng, &siz1, &nul1, rvals)
- || !get_len_or_size (arg2, idx2, len2rng, &siz2, &nul2, rvals))
+ if (!get_len_or_size (stmt, arg1, idx1, len1rng, &siz1, &nul1, rvals)
+ || !get_len_or_size (stmt, arg2, idx2, len2rng, &siz2, &nul2, rvals))
return NULL_TREE;
/* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
@@ -4420,7 +4424,7 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi, const vr_values *rvals)
/* Try to determine if the two strings are either definitely equal
or definitely unequal and if so, either fold the result to zero
(when equal) or set the range of the result to ~[0, 0] otherwise. */
- if (tree eqz = strxcmp_eqz_result (arg1, idx1, arg2, idx2, bound,
+ if (tree eqz = strxcmp_eqz_result (stmt, arg1, idx1, arg2, idx2, bound,
len, &siz, rvals))
{
if (integer_zerop (eqz))
@@ -4457,8 +4461,9 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi, const vr_values *rvals)
unsigned HOST_WIDE_INT arsz1, arsz2;
bool nulterm[2];
- if (!get_len_or_size (arg1, idx1, len1rng, &arsz1, nulterm, rvals)
- || !get_len_or_size (arg2, idx2, len2rng, &arsz2, nulterm + 1, rvals))
+ if (!get_len_or_size (stmt, arg1, idx1, len1rng, &arsz1, nulterm, rvals)
+ || !get_len_or_size (stmt, arg2, idx2, len2rng, &arsz2, nulterm + 1,
+ rvals))
return false;
if (len1rng[0] == len1rng[1] && len1rng[0] < HOST_WIDE_INT_MAX)
@@ -4846,7 +4851,8 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
&& TREE_CODE (si->nonzero_chars) == SSA_NAME)
{
vr_values *v = CONST_CAST (vr_values *, rvals);
- const value_range_equiv *vr = v->get_value_range (si->nonzero_chars);
+ const value_range_equiv *vr
+ = v->get_value_range (si->nonzero_chars, si->stmt);
if (vr->kind () != VR_RANGE || !range_int_cst_p (vr))
return false;
diff --git a/gcc/tree-ssa-strlen.h b/gcc/tree-ssa-strlen.h
index a11c4d579a1..0e9c7143308 100644
--- a/gcc/tree-ssa-strlen.h
+++ b/gcc/tree-ssa-strlen.h
@@ -26,10 +26,11 @@ extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree);
extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE);
class vr_values;
-extern tree get_range (tree, wide_int[2], const vr_values * = NULL);
+extern tree get_range (tree, gimple *, wide_int[2], const vr_values * = NULL);
struct c_strlen_data;
-extern void get_range_strlen_dynamic (tree , c_strlen_data *, const vr_values *);
+extern void get_range_strlen_dynamic (tree, gimple *, c_strlen_data *,
+ const vr_values *);
/* APIs internal to strlen pass. Defined in gimple-ssa-sprintf.c. */
extern bool handle_printf_call (gimple_stmt_iterator *, const vr_values *);
More information about the Gcc-cvs
mailing list