1 /* Pretty print support for value ranges.
2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "tree-pretty-print.h"
29 #include "fold-const.h"
30 #include "gimple-range.h"
31 #include "value-range-pretty-print.h"
34 print_int_bound (pretty_printer
*pp
, const wide_int
&bound
, tree type
)
36 wide_int type_min
= wi::min_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
37 wide_int type_max
= wi::max_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
39 if (INTEGRAL_TYPE_P (type
)
40 && !TYPE_UNSIGNED (type
)
42 && TYPE_PRECISION (type
) != 1)
43 pp_string (pp
, "-INF");
44 else if (bound
== type_max
&& TYPE_PRECISION (type
) != 1)
45 pp_string (pp
, "+INF");
47 pp_wide_int (pp
, bound
, TYPE_SIGN (type
));
51 print_irange_bitmasks (pretty_printer
*pp
, const irange_bitmask
&bm
)
56 pp_string (pp
, " MASK ");
57 char buf
[WIDE_INT_PRINT_BUFFER_SIZE
], *p
;
58 unsigned len_mask
, len_val
;
59 if (print_hex_buf_size (bm
.mask (), &len_mask
)
60 | print_hex_buf_size (bm
.value (), &len_val
))
61 p
= XALLOCAVEC (char, MAX (len_mask
, len_val
));
64 print_hex (bm
.mask (), p
);
66 pp_string (pp
, " VALUE ");
67 print_hex (bm
.value (), p
);
72 vrange_printer::visit (const unsupported_range
&r
) const
74 pp_string (pp
, "[unsupported_range] ");
77 pp_string (pp
, "UNDEFINED");
82 pp_string (pp
, "VARYING");
89 vrange_printer::visit (const irange
&r
) const
91 pp_string (pp
, "[irange] ");
94 pp_string (pp
, "UNDEFINED");
97 dump_generic_node (pp
, r
.type (), 0, TDF_NONE
| TDF_NOUID
, false);
98 pp_character (pp
, ' ');
101 pp_string (pp
, "VARYING");
104 for (unsigned i
= 0; i
< r
.num_pairs (); ++i
)
106 pp_character (pp
, '[');
107 print_int_bound (pp
, r
.lower_bound (i
), r
.type ());
108 pp_string (pp
, ", ");
109 print_int_bound (pp
, r
.upper_bound (i
), r
.type ());
110 pp_character (pp
, ']');
112 print_irange_bitmasks (pp
, r
.m_bitmask
);
116 vrange_printer::visit (const prange
&r
) const
118 pp_string (pp
, "[prange] ");
119 if (r
.undefined_p ())
121 pp_string (pp
, "UNDEFINED");
124 dump_generic_node (pp
, r
.type (), 0, TDF_NONE
| TDF_NOUID
, false);
125 pp_character (pp
, ' ');
128 pp_string (pp
, "VARYING");
132 pp_character (pp
, '[');
133 print_int_bound (pp
, r
.lower_bound (), r
.type ());
134 pp_string (pp
, ", ");
135 print_int_bound (pp
, r
.upper_bound (), r
.type ());
136 pp_character (pp
, ']');
137 print_irange_bitmasks (pp
, r
.m_bitmask
);
141 vrange_printer::print_real_value (tree type
, const REAL_VALUE_TYPE
&r
) const
144 real_to_decimal_for_mode (s
, &r
, sizeof (s
), 0, 1, TYPE_MODE (type
));
146 if (!DECIMAL_FLOAT_TYPE_P (type
)
147 // real_to_hexadecimal prints infinities and NAN as text. No
148 // need to print them twice.
152 real_to_hexadecimal (s
, &r
, sizeof (s
), 0, 1);
153 pp_printf (pp
, " (%s)", s
);
160 vrange_printer::visit (const frange
&r
) const
162 pp_string (pp
, "[frange] ");
163 if (r
.undefined_p ())
165 pp_string (pp
, "UNDEFINED");
168 tree type
= r
.type ();
169 dump_generic_node (pp
, type
, 0, TDF_NONE
, false);
173 pp_string (pp
, "VARYING");
174 print_frange_nan (r
);
177 pp_character (pp
, '[');
178 bool has_endpoints
= !r
.known_isnan ();
181 print_real_value (type
, r
.lower_bound ());
182 pp_string (pp
, ", ");
183 print_real_value (type
, r
.upper_bound ());
185 pp_character (pp
, ']');
186 print_frange_nan (r
);
189 // Print the NAN info for an frange.
192 vrange_printer::print_frange_nan (const frange
&r
) const
194 if (r
.maybe_isnan ())
196 if (r
.m_pos_nan
&& r
.m_neg_nan
)
198 pp_string (pp
, " +-NAN");
201 bool nan_sign
= r
.m_neg_nan
;
203 pp_string (pp
, " -NAN");
205 pp_string (pp
, " +NAN");