This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: cleanups and unification of value_range dumping code




On 11/8/18 9:39 AM, Richard Biener wrote:
On Thu, Nov 8, 2018 at 2:32 PM Aldy Hernandez <aldyh@redhat.com> wrote:

[Richard, you're right.  An overloaded debug() is better than
this->dump().  Anyone who thinks different is wrong.  End of discussion.]

There's no reason to have multiple ways of dumping a value range.  And
I'm not even talking about ipa-prop.* which decided that they should
implement their own version of value_ranges basically to annoy me.
Attached is a patch to remedy this.

I have made three small user-visible changes to the dumping code--
cause, well... you know me... I can't leave things alone.

1. It *REALLY* irks me that bools are dumped with -INF/+INF.  Everyone
knows that bools should be 0/1.  It's in the Bible.  Look it up.

2. Analogous to #1, what's up with signed 1-bit fields?  Who understands
[0, +INF] as [0, 0]?  No one; that's right.  (It's still beyond me the
necessity of signed bit fields in the standard period, but I'll pick my
battles.)

3. I find it quite convenient to display the tree type along with the
range as:

         [1, 1] int EQUIVALENCES { me, myself, I }

the type inbetween the range and equivalences?  seriously?  If so then
_please_ dump the type before the range:

   int [1, 1] EQUIV { ... }

Done in attached patch.


Finally.. As mentioned, I've implement an overloaded debug() because
it's *so* nice to use gdb and an alias of:

         define dd
           call debug($arg0)
         end

...and have stuff just work.

I do realize that we still have dump() lying around.  At some point, we
should start dropping external access to the dump methods for objects
that are never dumped by the compiler (but by the user at debug time).

+DEBUG_FUNCTION void
+debug (const value_range *vr)
+{
+  dump_value_range (stderr, vr);
+}
+
+DEBUG_FUNCTION void
+debug (const value_range vr)

^^^ missing a & (const reference?)

+{
+  dump_value_range (stderr, &vr);
+}

Fixed.


also

@@ -2122,21 +2122,11 @@ dump_ssaname_info (pretty_printer *buffer,
tree node, int spc)
    if (!POINTER_TYPE_P (TREE_TYPE (node))
        && SSA_NAME_RANGE_INFO (node))
      {
-      wide_int min, max, nonzero_bits;
-      value_range_kind range_type = get_range_info (node, &min, &max);
+      value_range vr;

-      if (range_type == VR_VARYING)
-       pp_printf (buffer, "# RANGE VR_VARYING");
-      else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
-       {
-         pp_printf (buffer, "# RANGE ");
-         pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
-         pp_wide_int (buffer, min, TYPE_SIGN (TREE_TYPE (node)));
-         pp_printf (buffer, ", ");
-         pp_wide_int (buffer, max, TYPE_SIGN (TREE_TYPE (node)));
-         pp_printf (buffer, "]");
-       }
-      nonzero_bits = get_nonzero_bits (node);
+      get_range_info (node, vr);

this is again allocating INTEGER_CSTs for no good reason.  dumping really
shuld avoid possibly messing with the GC state.

Hmmmm, I'd really hate to have two distinct places that dump value ranges. Is this really a problem? Cause the times I've run into GC problems I'd had to resort to printf() anyhow...

And while we're on the subject of multiple implementations, I'm thinking of rewriting ipa-prop to actually use value_range's, not this:

struct GTY(()) ipa_vr
{
  /* The data fields below are valid only if known is true.  */
  bool known;
  enum value_range_kind type;
  wide_int min;
  wide_int max;
};

so perhaps:

struct { bool known; value_range vr; }

Remember that trees are cached, whereas wide_int's are not, and folks (not me :)) like to complain that wide_int's take a lot of space.

Would you be viscerally opposed to implementing ipa_vr with value_range's? I really hate having to deal with yet another value_range variant.

Aldy
            * gimple-pretty-print.c (dump_ssaname_info): Use value_range
            dumper to dump range information.
            * tree-vrp.c (value_range::dump_range): New.
            (value_range::dump): Add variant for dumping to pretty_printer.
            Adjust FILE * version accordingly.
            (debug_value_range): Rename to debug.
    
            Remove unused prototypes: dump_value_range, debug_value_range,
            dump_all_value_ranges, dump_vr_equiv, debug_vr_equiv.
            * tree-vrp.h (value_range::dump): Add new variant that takes
            pretty_printer.
            (value_range::dump_range): New.

diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 7dfec9120ab..73af30ba92f 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -2122,21 +2122,11 @@ dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
   if (!POINTER_TYPE_P (TREE_TYPE (node))
       && SSA_NAME_RANGE_INFO (node))
     {
-      wide_int min, max, nonzero_bits;
-      value_range_kind range_type = get_range_info (node, &min, &max);
+      value_range vr;
 
-      if (range_type == VR_VARYING)
-	pp_printf (buffer, "# RANGE VR_VARYING");
-      else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
-	{
-	  pp_printf (buffer, "# RANGE ");
-	  pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
-	  pp_wide_int (buffer, min, TYPE_SIGN (TREE_TYPE (node)));
-	  pp_printf (buffer, ", ");
-	  pp_wide_int (buffer, max, TYPE_SIGN (TREE_TYPE (node)));
-	  pp_printf (buffer, "]");
-	}
-      nonzero_bits = get_nonzero_bits (node);
+      get_range_info (node, vr);
+      vr.dump (buffer);
+      wide_int nonzero_bits = get_nonzero_bits (node);
       if (nonzero_bits != -1)
 	{
 	  pp_string (buffer, " NONZERO ");
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c
index 5a2dbf0108a..66d74e9b5e9 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c
@@ -18,5 +18,5 @@ int foo (int i, int j)
   return j;
 }
 
-/* { dg-final { scan-tree-dump "res_.: \\\[1, 1\\\]" "vrp1" } } */
+/* { dg-final { scan-tree-dump "res_.: int \\\[1, 1\\\]" "vrp1" } } */
 /* { dg-final { scan-tree-dump-not "Threaded" "vrp1" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 3ccf2e491d6..b13f7205570 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -310,57 +310,70 @@ value_range::type () const
   return TREE_TYPE (min ());
 }
 
-/* Dump value range to FILE.  */
+void
+value_range::dump_range (pretty_printer *buffer) const
+{
+  tree ttype = type ();
+  dump_generic_node (buffer, ttype, 0, TDF_SLIM, false);
+  pp_character (buffer, ' ');
+  pp_printf (buffer, "%s[", (m_kind == VR_ANTI_RANGE) ? "~" : "");
+  if (INTEGRAL_TYPE_P (ttype)
+      && !TYPE_UNSIGNED (ttype)
+      && vrp_val_is_min (min ())
+      && TYPE_PRECISION (ttype) != 1)
+    pp_printf (buffer, "-INF");
+  else
+    dump_generic_node (buffer, min (), 0, TDF_SLIM, false);
+
+  pp_printf (buffer, ", ");
+
+  if (INTEGRAL_TYPE_P (ttype)
+      && vrp_val_is_max (max ())
+      && TYPE_PRECISION (ttype) != 1)
+    pp_printf (buffer, "+INF");
+  else
+    dump_generic_node (buffer, max (), 0, TDF_SLIM, false);
+  pp_string (buffer, "] ");
+}
 
 void
-value_range::dump (FILE *file) const
+value_range::dump (pretty_printer *buffer) const
 {
   if (undefined_p ())
-    fprintf (file, "UNDEFINED");
+    pp_string (buffer, "UNDEFINED");
   else if (m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
     {
-      tree type = TREE_TYPE (min ());
-
-      fprintf (file, "%s[", (m_kind == VR_ANTI_RANGE) ? "~" : "");
-
-      if (INTEGRAL_TYPE_P (type)
-	  && !TYPE_UNSIGNED (type)
-	  && vrp_val_is_min (min ()))
-	fprintf (file, "-INF");
-      else
-	print_generic_expr (file, min ());
-
-      fprintf (file, ", ");
-
-      if (INTEGRAL_TYPE_P (type)
-	  && vrp_val_is_max (max ()))
-	fprintf (file, "+INF");
-      else
-	print_generic_expr (file, max ());
-
-      fprintf (file, "]");
-
+      dump_range (buffer);
       if (m_equiv)
 	{
 	  bitmap_iterator bi;
 	  unsigned i, c = 0;
 
-	  fprintf (file, "  EQUIVALENCES: { ");
+	  pp_printf (buffer, " EQUIVALENCES: { ");
 
 	  EXECUTE_IF_SET_IN_BITMAP (m_equiv, 0, i, bi)
 	    {
-	      print_generic_expr (file, ssa_name (i));
-	      fprintf (file, " ");
+	      dump_generic_node (buffer, ssa_name (i), 0, TDF_SLIM, false);
+	      pp_string (buffer, " ");
 	      c++;
 	    }
 
-	  fprintf (file, "} (%u elements)", c);
+	  pp_printf (buffer, "} (%u elements)", c);
 	}
     }
   else if (varying_p ())
-    fprintf (file, "VARYING");
+    pp_string (buffer, "VARYING");
+  else
+    pp_string (buffer, "INVALID RANGE");
+}
+
+void
+dump_value_range (FILE *file, const value_range *vr)
+{
+  if (!vr)
+    fprintf (file, "[]");
   else
-    fprintf (file, "INVALID RANGE");
+    vr->dump (file);
 }
 
 void
@@ -370,6 +383,28 @@ value_range::dump () const
   fprintf (stderr, "\n");
 }
 
+void
+value_range::dump (FILE *file) const
+{
+ pretty_printer buffer;
+ pp_needs_newline (&buffer) = true;
+ buffer.buffer->stream = file;
+ dump (&buffer);
+ pp_flush (&buffer);
+}
+
+DEBUG_FUNCTION void
+debug (const value_range *vr)
+{
+  dump_value_range (stderr, vr);
+}
+
+DEBUG_FUNCTION void
+debug (const value_range &vr)
+{
+  dump_value_range (stderr, &vr);
+}
+
 /* Return true if the SSA name NAME is live on the edge E.  */
 
 static bool
@@ -2102,32 +2137,6 @@ extract_range_from_unary_expr (value_range *vr,
   return;
 }
 
-/* Debugging dumps.  */
-
-void dump_value_range (FILE *, const value_range *);
-void debug_value_range (const value_range *);
-void dump_all_value_ranges (FILE *);
-void dump_vr_equiv (FILE *, bitmap);
-void debug_vr_equiv (bitmap);
-
-void
-dump_value_range (FILE *file, const value_range *vr)
-{
-  if (!vr)
-    fprintf (file, "[]");
-  else
-    vr->dump (file);
-}
-
-/* Dump value range VR to stderr.  */
-
-DEBUG_FUNCTION void
-debug_value_range (const value_range *vr)
-{
-  vr->dump ();
-}
-
-
 /* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
    create a new SSA name N and return the assertion assignment
    'N = ASSERT_EXPR <V, V OP W>'.  */
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index c251329a195..934097523dd 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -71,6 +71,7 @@ class GTY((for_user)) value_range
   void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap);
   void dump (FILE *) const;
   void dump () const;
+  void dump (pretty_printer *buffer) const;
 
   enum value_range_kind kind () const;
   tree min () const;
@@ -82,6 +83,7 @@ class GTY((for_user)) value_range
   bool equal_p (const value_range &, bool ignore_equivs) const;
   void intersect_helper (value_range *, const value_range *);
   void union_helper (value_range *, const value_range *);
+  void dump_range (pretty_printer *) const;
 
   enum value_range_kind m_kind;
  public:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]