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 \
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)
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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
#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"
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
{
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.
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)
{
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;
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;
// 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.
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;
{
public:
unsupported_range ();
- virtual void dump (FILE *) const override;
virtual void accept (const vrange_visitor &v) const override;
};
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.