This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][committed][PR tree-optimization/82123] 04/06 Make vr_values available where needed
- From: Jeff Law <law at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 20 Feb 2018 11:56:10 -0700
- Subject: [PATCH][committed][PR tree-optimization/82123] 04/06 Make vr_values available where needed
- Authentication-results: sourceware.org; auth=none
This is the 4th patch in the series. It doesn't change the analysis in
any way shape or form. It just arranges to pass around the range data
to the points where we're going to need it.
Bootstrapped and regression tested on x86_64-linux-gnu.
Jeff
commit e2b702e7bcb00c2197776691735ff8a599dce4e1
Author: Jeff Law <law@torsion.usersys.redhat.com>
Date: Mon Feb 19 17:53:40 2018 -0500
Push vr-values to where it needs to be
* gimple-ssa-sprintf.c (get_int_range): Accept vr_values parameter
pass it to children as needed.
(struct directive::fmtresult): Similarly.
(struct directive::set_width): Similarly.
(struct directive::set_precision): Similarly.
(format_integer, format_directive, parse_directive): Similarly.
(format_none): Accept unnamed vr_values parameter.
(format_percent, format_floating, format_character): Similarly.
(format_string, format_plain): Similarly.
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 4b2de6d..54c9132 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -771,7 +771,8 @@ fmtresult::type_max_digits (tree type, int base)
}
static bool
-get_int_range (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool, HOST_WIDE_INT);
+get_int_range (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool, HOST_WIDE_INT,
+ class vr_values *vr_values);
/* Description of a format directive. A directive is either a plain
string or a conversion specification that starts with '%'. */
@@ -806,7 +807,7 @@ struct directive
/* Format conversion function that given a directive and an argument
returns the formatting result. */
- fmtresult (*fmtfunc) (const directive &, tree);
+ fmtresult (*fmtfunc) (const directive &, tree, vr_values *);
/* Return True when a the format flag CHR has been used. */
bool get_flag (char chr) const
@@ -843,9 +844,9 @@ struct directive
or 0, whichever is greater. For a non-constant ARG in some range
set width to its range adjusting each bound to -1 if it's less.
For an indeterminate ARG set width to [0, INT_MAX]. */
- void set_width (tree arg)
+ void set_width (tree arg, vr_values *vr_values)
{
- get_int_range (arg, width, width + 1, true, 0);
+ get_int_range (arg, width, width + 1, true, 0, vr_values);
}
/* Set both bounds of the precision range to VAL. */
@@ -859,9 +860,9 @@ struct directive
or -1 whichever is greater. For a non-constant ARG in some range
set precision to its range adjusting each bound to -1 if it's less.
For an indeterminate ARG set precision to [-1, INT_MAX]. */
- void set_precision (tree arg)
+ void set_precision (tree arg, vr_values *vr_values)
{
- get_int_range (arg, prec, prec + 1, false, -1);
+ get_int_range (arg, prec, prec + 1, false, -1, vr_values);
}
/* Return true if both width and precision are known to be
@@ -1042,7 +1043,7 @@ struct sprintf_dom_walker::call_info
/* Return the result of formatting a no-op directive (such as '%n'). */
static fmtresult
-format_none (const directive &, tree)
+format_none (const directive &, tree, vr_values *)
{
fmtresult res (0);
return res;
@@ -1051,7 +1052,7 @@ format_none (const directive &, tree)
/* Return the result of formatting the '%%' directive. */
static fmtresult
-format_percent (const directive &, tree)
+format_percent (const directive &, tree, vr_values *)
{
fmtresult res (1);
return res;
@@ -1108,7 +1109,8 @@ build_intmax_type_nodes (tree *pintmax, tree *puintmax)
static bool
get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
- bool absolute, HOST_WIDE_INT negbound)
+ bool absolute, HOST_WIDE_INT negbound,
+ class vr_values *vr_values)
{
/* The type of the result. */
const_tree type = integer_type_node;
@@ -1179,7 +1181,8 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
/* Handle an argument with an unknown range as if none had been
provided. */
if (unknown)
- return get_int_range (NULL_TREE, pmin, pmax, absolute, negbound);
+ return get_int_range (NULL_TREE, pmin, pmax, absolute,
+ negbound, vr_values);
}
/* Adjust each bound as specified by ABSOLUTE and NEGBOUND. */
@@ -1264,7 +1267,7 @@ adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax)
used when the directive argument or its value isn't known. */
static fmtresult
-format_integer (const directive &dir, tree arg)
+format_integer (const directive &dir, tree arg, vr_values *vr_values)
{
tree intmax_type_node;
tree uintmax_type_node;
@@ -1482,7 +1485,7 @@ format_integer (const directive &dir, tree arg)
if (code == INTEGER_CST)
{
arg = gimple_assign_rhs1 (def);
- return format_integer (dir, arg);
+ return format_integer (dir, arg, vr_values);
}
if (code == NOP_EXPR)
@@ -1527,16 +1530,16 @@ format_integer (const directive &dir, tree arg)
/* For unsigned conversions/directives or signed when
the minimum is positive, use the minimum and maximum to compute
the shortest and longest output, respectively. */
- res.range.min = format_integer (dir, argmin).range.min;
- res.range.max = format_integer (dir, argmax).range.max;
+ res.range.min = format_integer (dir, argmin, vr_values).range.min;
+ res.range.max = format_integer (dir, argmax, vr_values).range.max;
}
else if (tree_int_cst_sgn (argmax) < 0)
{
/* For signed conversions/directives if maximum is negative,
use the minimum as the longest output and maximum as the
shortest output. */
- res.range.min = format_integer (dir, argmax).range.min;
- res.range.max = format_integer (dir, argmin).range.max;
+ res.range.min = format_integer (dir, argmax, vr_values).range.min;
+ res.range.max = format_integer (dir, argmin, vr_values).range.max;
}
else
{
@@ -1544,9 +1547,12 @@ format_integer (const directive &dir, tree arg)
as the shortest output and for the longest output compute the
length of the output of both minimum and maximum and pick the
longer. */
- unsigned HOST_WIDE_INT max1 = format_integer (dir, argmin).range.max;
- unsigned HOST_WIDE_INT max2 = format_integer (dir, argmax).range.max;
- res.range.min = format_integer (dir, integer_zero_node).range.min;
+ unsigned HOST_WIDE_INT max1
+ = format_integer (dir, argmin, vr_values).range.max;
+ unsigned HOST_WIDE_INT max2
+ = format_integer (dir, argmax, vr_values).range.max;
+ res.range.min
+ = format_integer (dir, integer_zero_node, vr_values).range.min;
res.range.max = MAX (max1, max2);
}
@@ -1887,7 +1893,7 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2])
ARG. */
static fmtresult
-format_floating (const directive &dir, tree arg)
+format_floating (const directive &dir, tree arg, vr_values *)
{
HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] };
tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll
@@ -2127,7 +2133,7 @@ get_string_length (tree str)
vsprinf). */
static fmtresult
-format_character (const directive &dir, tree arg)
+format_character (const directive &dir, tree arg, vr_values *vr_values)
{
fmtresult res;
@@ -2139,7 +2145,7 @@ format_character (const directive &dir, tree arg)
res.range.min = 0;
HOST_WIDE_INT min, max;
- if (get_int_range (arg, &min, &max, false, 0))
+ if (get_int_range (arg, &min, &max, false, 0, vr_values))
{
if (min == 0 && max == 0)
{
@@ -2192,7 +2198,7 @@ format_character (const directive &dir, tree arg)
vsprinf). */
static fmtresult
-format_string (const directive &dir, tree arg)
+format_string (const directive &dir, tree arg, vr_values *)
{
fmtresult res;
@@ -2353,7 +2359,7 @@ format_string (const directive &dir, tree arg)
/* Format plain string (part of the format string itself). */
static fmtresult
-format_plain (const directive &dir, tree)
+format_plain (const directive &dir, tree, vr_values *)
{
fmtresult res (dir.len);
return res;
@@ -2734,7 +2740,8 @@ maybe_warn (substring_loc &dirloc, location_t argloc,
static bool
format_directive (const sprintf_dom_walker::call_info &info,
- format_result *res, const directive &dir)
+ format_result *res, const directive &dir,
+ class vr_values *vr_values)
{
/* Offset of the beginning of the directive from the beginning
of the format string. */
@@ -2759,7 +2766,7 @@ format_directive (const sprintf_dom_walker::call_info &info,
return false;
/* Compute the range of lengths of the formatted output. */
- fmtresult fmtres = dir.fmtfunc (dir, dir.arg);
+ fmtresult fmtres = dir.fmtfunc (dir, dir.arg, vr_values);
/* Record whether the output of all directives is known to be
bounded by some maximum, implying that their arguments are
@@ -3025,7 +3032,8 @@ format_directive (const sprintf_dom_walker::call_info &info,
static size_t
parse_directive (sprintf_dom_walker::call_info &info,
directive &dir, format_result *res,
- const char *str, unsigned *argno)
+ const char *str, unsigned *argno,
+ vr_values *vr_values)
{
const char *pcnt = strchr (str, target_percent);
dir.beg = str;
@@ -3343,7 +3351,7 @@ parse_directive (sprintf_dom_walker::call_info &info,
if (star_width)
{
if (INTEGRAL_TYPE_P (TREE_TYPE (star_width)))
- dir.set_width (star_width);
+ dir.set_width (star_width, vr_values);
else
{
/* Width specified by a va_list takes on the range [0, -INT_MIN]
@@ -3376,7 +3384,7 @@ parse_directive (sprintf_dom_walker::call_info &info,
if (star_precision)
{
if (INTEGRAL_TYPE_P (TREE_TYPE (star_precision)))
- dir.set_precision (star_precision);
+ dir.set_precision (star_precision, vr_values);
else
{
/* Precision specified by a va_list takes on the range [-1, INT_MAX]
@@ -3498,10 +3506,12 @@ sprintf_dom_walker::compute_format_length (call_info &info,
directive dir = directive ();
dir.dirno = dirno;
- size_t n = parse_directive (info, dir, res, pf, &argno);
+ size_t n = parse_directive (info, dir, res, pf, &argno,
+ evrp_range_analyzer.get_vr_values ());
/* Return failure if the format function fails. */
- if (!format_directive (info, res, dir))
+ if (!format_directive (info, res, dir,
+ evrp_range_analyzer.get_vr_values ()))
return false;
/* Return success the directive is zero bytes long and it's