diff mbox series

[committed,PR,tree-optimization/82123] 04/06 Make vr_values available where needed

Message ID 3b0a6217-de44-636d-3745-441e3a95d473@redhat.com
State New
Headers show
Series [committed,PR,tree-optimization/82123] 04/06 Make vr_values available where needed | expand

Commit Message

Jeff Law Feb. 20, 2018, 6:56 p.m. UTC
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 mbox series

Patch

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