Convert vrange dumping facilities to pretty_printer.

We need to dump global ranges from the gimple pretty printer code, but
all the vrange dumping facilities work with FILE handles.  This patch
converts all the dumping methods to work with pretty printers, and
provides a wrapper so the FILE * methods continue to work for
debugging.  I also cleaned up the code a bit.

Tested on x86-64 Linux.

gcc/ChangeLog:

	* Makefile.in (OBJS): Add value-range-pretty-print.o.
	* pretty-print.h (pp_vrange): New.
	* value-range.cc (vrange::dump): Call pp version.
	(unsupported_range::dump): Move to its own file.
	(dump_bound_with_infinite_markers): Same.
	(irange::dump): Same.
	(irange::dump_bitmasks): Same.
	(vrange::debug): Remove.
	* value-range.h: Remove virtual designation for dump methods.
	Remove dump_bitmasks method.
	* value-range-pretty-print.cc: New file.
	* value-range-pretty-print.h: New file.
This commit is contained in:
Aldy Hernandez
2022-07-14 19:04:09 +02:00
parent 91a7f30662
commit 64864aa9e6
6 changed files with 172 additions and 105 deletions
+1
View File
@@ -1711,6 +1711,7 @@ OBJS = \
value-query.o \
value-range.o \
value-range-equiv.o \
value-range-pretty-print.o \
value-range-storage.o \
value-relation.o \
value-prof.o \
+7
View File
@@ -340,6 +340,13 @@ pp_get_prefix (const pretty_printer *pp) { return pp->prefix; }
pp_string (PP, pp_buffer (PP)->digit_buffer); \
} \
while (0)
#define pp_vrange(PP, R) \
do \
{ \
vrange_printer vrange_pp (PP); \
(R)->accept (vrange_pp); \
} \
while (0)
#define pp_double(PP, F) pp_scalar (PP, "%f", F)
#define pp_pointer(PP, P) pp_scalar (PP, "%p", P)
+111
View File
@@ -0,0 +1,111 @@
/* Pretty print support for value ranges.
Copyright (C) 2019-2022 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "tree-pretty-print.h"
#include "fold-const.h"
#include "gimple-range.h"
#include "value-range-pretty-print.h"
void
vrange_printer::visit (const unsupported_range &r) const
{
pp_string (pp, "[unsupported_range] ");
if (r.undefined_p ())
{
pp_string (pp, "UNDEFINED");
return;
}
if (r.varying_p ())
{
pp_string (pp, "VARYING");
return;
}
gcc_unreachable ();
}
void
vrange_printer::visit (const irange &r) const
{
pp_string (pp, "[irange] ");
if (r.undefined_p ())
{
pp_string (pp, "UNDEFINED");
return;
}
dump_generic_node (pp, r.type (), 0, TDF_NONE, false);
pp_character (pp, ' ');
if (r.varying_p ())
{
pp_string (pp, "VARYING");
return;
}
for (unsigned i = 0; i < r.num_pairs (); ++i)
{
tree lb = wide_int_to_tree (r.type (), r.lower_bound (i));
tree ub = wide_int_to_tree (r.type (), r.upper_bound (i));
pp_character (pp, '[');
print_irange_bound (lb);
pp_string (pp, ", ");
print_irange_bound (ub);
pp_character (pp, ']');
}
print_irange_bitmasks (r);
}
void
vrange_printer::print_irange_bound (tree bound) const
{
tree type = TREE_TYPE (bound);
wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
if (INTEGRAL_TYPE_P (type)
&& !TYPE_UNSIGNED (type)
&& TREE_CODE (bound) == INTEGER_CST
&& wi::to_wide (bound) == type_min
&& TYPE_PRECISION (type) != 1)
pp_string (pp, "-INF");
else if (TREE_CODE (bound) == INTEGER_CST
&& wi::to_wide (bound) == type_max
&& TYPE_PRECISION (type) != 1)
pp_string (pp, "+INF");
else
dump_generic_node (pp, bound, 0, TDF_NONE, false);
}
void
vrange_printer::print_irange_bitmasks (const irange &r) const
{
wide_int nz = r.get_nonzero_bits ();
if (nz == -1)
return;
pp_string (pp, " NONZERO ");
char buf[WIDE_INT_PRINT_BUFFER_SIZE];
print_hex (nz, buf);
pp_string (pp, buf);
}
+37
View File
@@ -0,0 +1,37 @@
/* Pretty print support for value ranges.
Copyright (C) 2022 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_VALUE_RANGE_PRETTY_H
#define GCC_VALUE_RANGE_PRETTY_H
class vrange_printer : public vrange_visitor
{
public:
vrange_printer (pretty_printer *pp_) : pp (pp_) { }
void visit (const unsupported_range &) const override;
void visit (const irange &) const override;
private:
void print_irange_bound (tree bound) const;
void print_irange_bitmasks (const irange &) const;
pretty_printer *pp;
};
#endif // GCC_VALUE_RANGE_PRETTY_H
+14 -99
View File
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "ssa.h"
#include "tree-pretty-print.h"
#include "value-range-pretty-print.h"
#include "fold-const.h"
#include "gimple-range.h"
@@ -212,6 +213,19 @@ vrange::operator== (const vrange &src) const
gcc_unreachable ();
}
// Wrapper for vrange_printer to dump a range to a file.
void
vrange::dump (FILE *file) const
{
pretty_printer buffer;
pp_needs_newline (&buffer) = true;
buffer.buffer->stream = file;
vrange_printer vrange_pp (&buffer);
this->accept (vrange_pp);
pp_flush (&buffer);
}
bool
irange::supports_type_p (tree type) const
{
@@ -238,23 +252,6 @@ unsupported_range::unsupported_range ()
set_undefined ();
}
void
unsupported_range::dump (FILE *file) const
{
fprintf (file, "[unsupported_range] ");
if (undefined_p ())
{
fprintf (file, "UNDEFINED");
return;
}
if (varying_p ())
{
fprintf (file, "VARYING");
return;
}
gcc_unreachable ();
}
// Here we copy between any two irange's. The ranges can be legacy or
// multi-ranges, and copying between any combination works correctly.
@@ -2461,88 +2458,6 @@ irange::union_nonzero_bits (const irange &r)
return false;
}
static void
dump_bound_with_infinite_markers (FILE *file, tree bound)
{
tree type = TREE_TYPE (bound);
wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
if (INTEGRAL_TYPE_P (type)
&& !TYPE_UNSIGNED (type)
&& TREE_CODE (bound) == INTEGER_CST
&& wi::to_wide (bound) == type_min
&& TYPE_PRECISION (type) != 1)
fprintf (file, "-INF");
else if (TREE_CODE (bound) == INTEGER_CST
&& wi::to_wide (bound) == type_max
&& TYPE_PRECISION (type) != 1)
fprintf (file, "+INF");
else
print_generic_expr (file, bound);
}
void
irange::dump (FILE *file) const
{
fprintf (file, "[irange] ");
if (undefined_p ())
{
fprintf (file, "UNDEFINED");
return;
}
print_generic_expr (file, type ());
fprintf (file, " ");
if (varying_p ())
{
fprintf (file, "VARYING");
dump_bitmasks (file);
return;
}
if (legacy_mode_p ())
{
fprintf (file, "%s[", (m_kind == VR_ANTI_RANGE) ? "~" : "");
dump_bound_with_infinite_markers (file, min ());
fprintf (file, ", ");
dump_bound_with_infinite_markers (file, max ());
fprintf (file, "]");
dump_bitmasks (file);
return;
}
for (unsigned i = 0; i < m_num_ranges; ++i)
{
tree lb = m_base[i * 2];
tree ub = m_base[i * 2 + 1];
fprintf (file, "[");
dump_bound_with_infinite_markers (file, lb);
fprintf (file, ", ");
dump_bound_with_infinite_markers (file, ub);
fprintf (file, "]");
}
dump_bitmasks (file);
}
void
irange::dump_bitmasks (FILE *file) const
{
if (m_nonzero_mask)
{
wide_int nz = get_nonzero_bits ();
if (nz != -1)
{
fprintf (file, " NONZERO ");
print_hex (nz, file);
}
}
}
void
vrange::debug () const
{
dump (stderr);
fprintf (stderr, "\n");
}
void
dump_value_range (FILE *file, const vrange *vr)
{
+2 -6
View File
@@ -79,7 +79,6 @@ public:
virtual bool supports_type_p (tree type) const;
virtual void set_varying (tree type);
virtual void set_undefined ();
virtual void dump (FILE * = stderr) const = 0;
virtual bool union_ (const vrange &);
virtual bool intersect (const vrange &);
virtual bool singleton_p (tree *result = NULL) const;
@@ -96,9 +95,9 @@ public:
vrange& operator= (const vrange &);
bool operator== (const vrange &) const;
bool operator!= (const vrange &r) const { return !(*this == r); }
void dump (FILE *) const;
enum value_range_kind kind () const; // DEPRECATED
void debug () const;
protected:
ENUM_BITFIELD(value_range_kind) m_kind : 8;
@@ -149,7 +148,6 @@ public:
// Misc methods.
virtual bool fits_p (const vrange &r) const override;
virtual void dump (FILE * = stderr) const override;
virtual void accept (const vrange_visitor &v) const override;
// Nonzero masks.
@@ -206,7 +204,6 @@ private:
void set_nonzero_bits (tree mask);
bool intersect_nonzero_bits (const irange &r);
bool union_nonzero_bits (const irange &r);
void dump_bitmasks (FILE *) const;
bool intersect (const wide_int& lb, const wide_int& ub);
unsigned char m_num_ranges;
@@ -252,7 +249,6 @@ class unsupported_range : public vrange
{
public:
unsupported_range ();
virtual void dump (FILE *) const override;
virtual void accept (const vrange_visitor &v) const override;
};
@@ -339,7 +335,7 @@ public:
bool operator!= (const Value_Range &r) const;
operator vrange &();
operator const vrange &() const;
void dump (FILE *out = stderr) const;
void dump (FILE *) const;
static bool supports_type_p (tree type);
// Convenience methods for vrange compatability.