1 /* Support routines for value ranges.
2 Copyright (C) 2019-2022 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew Macleod <amacleod@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #ifndef GCC_VALUE_RANGE_H
23 #define GCC_VALUE_RANGE_H
27 // Types of value ranges.
32 /* Range spans the entire domain. */
34 /* Range is [MIN, MAX]. */
36 /* Range is ~[MIN, MAX]. */
40 /* Range is a nice guy. */
44 // Discriminator between different vrange types.
46 enum value_range_discriminator
48 // Range holds an integer or pointer.
50 // Floating point range.
52 // Range holds an unsupported type.
56 // Abstract class for ranges of any of the supported types.
58 // To query what types ranger and the entire ecosystem can support,
59 // use Value_Range::supports_type_p(tree type). This is a static
60 // method available independently of any vrange object.
62 // To query what a given vrange variant can support, use:
63 // irange::supports_p ()
64 // frange::supports_p ()
67 // To query what a range object can support, use:
68 // void foo (vrange &v, irange &i, frange &f)
70 // if (v.supports_type_p (type)) ...
71 // if (i.supports_type_p (type)) ...
72 // if (f.supports_type_p (type)) ...
77 template <typename T
> friend bool is_a (vrange
&);
78 friend class Value_Range
;
80 virtual void accept (const class vrange_visitor
&v
) const = 0;
81 virtual void set (tree
, tree
, value_range_kind
= VR_RANGE
);
82 virtual tree
type () const;
83 virtual bool supports_type_p (const_tree type
) const;
84 virtual void set_varying (tree type
);
85 virtual void set_undefined ();
86 virtual bool union_ (const vrange
&);
87 virtual bool intersect (const vrange
&);
88 virtual bool singleton_p (tree
*result
= NULL
) const;
89 virtual bool contains_p (tree cst
) const;
90 virtual bool zero_p () const;
91 virtual bool nonzero_p () const;
92 virtual void set_nonzero (tree type
);
93 virtual void set_zero (tree type
);
94 virtual void set_nonnegative (tree type
);
95 virtual bool fits_p (const vrange
&r
) const;
97 bool varying_p () const;
98 bool undefined_p () const;
99 vrange
& operator= (const vrange
&);
100 bool operator== (const vrange
&) const;
101 bool operator!= (const vrange
&r
) const { return !(*this == r
); }
102 void dump (FILE *) const;
104 enum value_range_kind
kind () const; // DEPRECATED
107 ENUM_BITFIELD(value_range_kind
) m_kind
: 8;
108 ENUM_BITFIELD(value_range_discriminator
) m_discriminator
: 4;
111 // An integer range without any storage.
113 class GTY((user
)) irange
: public vrange
115 friend class vrange_allocator
;
116 friend class irange_storage_slot
; // For legacy_mode_p checks.
119 virtual void set (tree
, tree
, value_range_kind
= VR_RANGE
) override
;
120 void set (tree type
, const wide_int_ref
&, const wide_int_ref
&,
121 value_range_kind
= VR_RANGE
);
122 virtual void set_nonzero (tree type
) override
;
123 virtual void set_zero (tree type
) override
;
124 virtual void set_nonnegative (tree type
) override
;
125 virtual void set_varying (tree type
) override
;
126 virtual void set_undefined () override
;
129 static bool supports_p (const_tree type
);
130 virtual bool supports_type_p (const_tree type
) const override
;
131 virtual tree
type () const override
;
133 // Iteration over sub-ranges.
134 unsigned num_pairs () const;
135 wide_int
lower_bound (unsigned = 0) const;
136 wide_int
upper_bound (unsigned) const;
137 wide_int
upper_bound () const;
140 virtual bool zero_p () const override
;
141 virtual bool nonzero_p () const override
;
142 virtual bool singleton_p (tree
*result
= NULL
) const override
;
143 virtual bool contains_p (tree cst
) const override
;
145 // In-place operators.
146 virtual bool union_ (const vrange
&) override
;
147 virtual bool intersect (const vrange
&) override
;
150 // Operator overloads.
151 irange
& operator= (const irange
&);
152 bool operator== (const irange
&) const;
153 bool operator!= (const irange
&r
) const { return !(*this == r
); }
156 virtual bool fits_p (const vrange
&r
) const override
;
157 virtual void accept (const vrange_visitor
&v
) const override
;
160 wide_int
get_nonzero_bits () const;
161 void set_nonzero_bits (const wide_int_ref
&bits
);
163 // Deprecated legacy public methods.
164 tree
min () const; // DEPRECATED
165 tree
max () const; // DEPRECATED
166 bool symbolic_p () const; // DEPRECATED
167 bool constant_p () const; // DEPRECATED
168 void normalize_symbolics (); // DEPRECATED
169 void normalize_addresses (); // DEPRECATED
170 bool may_contain_p (tree
) const; // DEPRECATED
171 bool legacy_verbose_union_ (const class irange
*); // DEPRECATED
172 bool legacy_verbose_intersect (const irange
*); // DEPRECATED
175 irange (tree
*, unsigned);
176 // potential promotion to public?
177 tree
tree_lower_bound (unsigned = 0) const;
178 tree
tree_upper_bound (unsigned) const;
179 tree
tree_upper_bound () const;
181 // In-place operators.
182 bool irange_union (const irange
&);
183 bool irange_intersect (const irange
&);
184 void irange_set (tree
, tree
);
185 void irange_set_anti_range (tree
, tree
);
186 bool irange_contains_p (const irange
&) const;
187 bool irange_single_pair_union (const irange
&r
);
189 void normalize_kind ();
191 bool legacy_mode_p () const;
192 bool legacy_equal_p (const irange
&) const;
193 void legacy_union (irange
*, const irange
*);
194 void legacy_intersect (irange
*, const irange
*);
195 void verify_range ();
196 wide_int
legacy_lower_bound (unsigned = 0) const;
197 wide_int
legacy_upper_bound (unsigned) const;
198 int value_inside_range (tree
) const;
199 bool maybe_anti_range () const;
200 void copy_to_legacy (const irange
&);
201 void copy_legacy_to_multi_range (const irange
&);
204 friend void gt_ggc_mx (irange
*);
205 friend void gt_pch_nx (irange
*);
206 friend void gt_pch_nx (irange
*, gt_pointer_operator
, void *);
208 void irange_set_1bit_anti_range (tree
, tree
);
209 bool varying_compatible_p () const;
210 bool intersect_nonzero_bits (const irange
&r
);
211 bool union_nonzero_bits (const irange
&r
);
212 wide_int
get_nonzero_bits_from_range () const;
213 bool set_range_from_nonzero_bits ();
215 bool intersect (const wide_int
& lb
, const wide_int
& ub
);
216 unsigned char m_num_ranges
;
217 unsigned char m_max_ranges
;
222 // Here we describe an irange with N pairs of ranges. The storage for
223 // the pairs is embedded in the class as an array.
226 class GTY((user
)) int_range
: public irange
230 int_range (tree
, tree
, value_range_kind
= VR_RANGE
);
231 int_range (tree type
, const wide_int
&, const wide_int
&,
232 value_range_kind
= VR_RANGE
);
233 int_range (tree type
);
234 int_range (const int_range
&);
235 int_range (const irange
&);
236 virtual ~int_range () = default;
237 int_range
& operator= (const int_range
&);
239 template <unsigned X
> friend void gt_ggc_mx (int_range
<X
> *);
240 template <unsigned X
> friend void gt_pch_nx (int_range
<X
> *);
241 template <unsigned X
> friend void gt_pch_nx (int_range
<X
> *,
242 gt_pointer_operator
, void *);
244 // ?? These stubs are for ipa-prop.cc which use a value_range in a
245 // hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
246 // instead of picking up the gt_ggc_mx (T *) version.
247 friend void gt_ggc_mx (int_range
<1> *&);
248 friend void gt_pch_nx (int_range
<1> *&);
253 // Unsupported temporaries may be created by ranger before it's known
254 // they're unsupported, or by vr_values::get_value_range.
256 class unsupported_range
: public vrange
261 m_discriminator
= VR_UNKNOWN
;
264 virtual void set_undefined () final override
266 m_kind
= VR_UNDEFINED
;
268 virtual void accept (const vrange_visitor
&v
) const override
;
271 // A floating point range.
273 // The representation is a type with a couple of endpoints, unioned
274 // with the set of { -NAN, +Nan }.
276 class frange
: public vrange
278 friend class frange_storage_slot
;
279 friend class vrange_printer
;
282 frange (const frange
&);
283 frange (tree
, tree
, value_range_kind
= VR_RANGE
);
285 frange (tree type
, const REAL_VALUE_TYPE
&min
, const REAL_VALUE_TYPE
&max
,
286 value_range_kind
= VR_RANGE
);
287 static bool supports_p (const_tree type
)
289 // ?? Decimal floats can have multiple representations for the
290 // same number. Supporting them may be as simple as just
291 // disabling them in singleton_p. No clue.
292 return SCALAR_FLOAT_TYPE_P (type
) && !DECIMAL_FLOAT_TYPE_P (type
);
294 virtual tree
type () const override
;
295 virtual void set (tree
, tree
, value_range_kind
= VR_RANGE
) override
;
296 void set (tree type
, const REAL_VALUE_TYPE
&, const REAL_VALUE_TYPE
&,
297 value_range_kind
= VR_RANGE
);
298 void set_nan (tree type
);
299 void set_nan (tree type
, bool sign
);
300 virtual void set_varying (tree type
) override
;
301 virtual void set_undefined () override
;
302 virtual bool union_ (const vrange
&) override
;
303 virtual bool intersect (const vrange
&) override
;
304 virtual bool contains_p (tree
) const override
;
305 virtual bool singleton_p (tree
*result
= NULL
) const override
;
306 virtual bool supports_type_p (const_tree type
) const override
;
307 virtual void accept (const vrange_visitor
&v
) const override
;
308 virtual bool zero_p () const override
;
309 virtual bool nonzero_p () const override
;
310 virtual void set_nonzero (tree type
) override
;
311 virtual void set_zero (tree type
) override
;
312 virtual void set_nonnegative (tree type
) override
;
313 frange
& operator= (const frange
&);
314 bool operator== (const frange
&) const;
315 bool operator!= (const frange
&r
) const { return !(*this == r
); }
316 const REAL_VALUE_TYPE
&lower_bound () const;
317 const REAL_VALUE_TYPE
&upper_bound () const;
319 void update_nan (bool sign
);
320 void update_nan (tree
) = delete; // Disallow silent conversion to bool.
323 // fpclassify like API
324 bool known_isfinite () const;
325 bool known_isnan () const;
326 bool known_isinf () const;
327 bool maybe_isnan () const;
328 bool maybe_isnan (bool sign
) const;
329 bool maybe_isinf () const;
330 bool signbit_p (bool &signbit
) const;
331 bool nan_signbit_p (bool &signbit
) const;
333 void verify_range ();
334 bool normalize_kind ();
335 bool union_nans (const frange
&);
336 bool intersect_nans (const frange
&);
337 bool combine_zeros (const frange
&, bool union_p
);
338 void flush_denormals_to_zero ();
341 REAL_VALUE_TYPE m_min
;
342 REAL_VALUE_TYPE m_max
;
347 inline const REAL_VALUE_TYPE
&
348 frange::lower_bound () const
350 gcc_checking_assert (!undefined_p () && !known_isnan ());
354 inline const REAL_VALUE_TYPE
&
355 frange::upper_bound () const
357 gcc_checking_assert (!undefined_p () && !known_isnan ());
361 // is_a<> and as_a<> implementation for vrange.
363 // Anything we haven't specialized is a hard fail.
364 template <typename T
>
372 template <typename T
>
374 is_a (const vrange
&v
)
376 // Reuse is_a <vrange> to implement the const version.
377 const T
&derived
= static_cast<const T
&> (v
);
378 return is_a
<T
> (const_cast<T
&> (derived
));
381 template <typename T
>
385 gcc_checking_assert (is_a
<T
> (v
));
386 return static_cast <T
&> (v
);
389 template <typename T
>
391 as_a (const vrange
&v
)
393 gcc_checking_assert (is_a
<T
> (v
));
394 return static_cast <const T
&> (v
);
397 // Specializations for the different range types.
401 is_a
<irange
> (vrange
&v
)
403 return v
.m_discriminator
== VR_IRANGE
;
408 is_a
<frange
> (vrange
&v
)
410 return v
.m_discriminator
== VR_FRANGE
;
416 virtual void visit (const irange
&) const { }
417 virtual void visit (const frange
&) const { }
418 virtual void visit (const unsupported_range
&) const { }
421 // This is a special int_range<1> with only one pair, plus
422 // VR_ANTI_RANGE magic to describe slightly more than can be described
423 // in one pair. It is described in the code as a "legacy range" (as
424 // opposed to multi-ranges which have multiple sub-ranges). It is
425 // provided for backward compatibility with code that has not been
426 // converted to multi-range irange's.
428 // There are copy operators to seamlessly copy to/fro multi-ranges.
429 typedef int_range
<1> value_range
;
431 // This is an "infinite" precision irange for use in temporary
433 typedef int_range
<255> int_range_max
;
435 // This is an "infinite" precision range object for use in temporary
436 // calculations for any of the handled types. The object can be
437 // transparently used as a vrange.
443 Value_Range (const vrange
&r
);
444 Value_Range (tree type
);
445 Value_Range (const Value_Range
&);
446 void set_type (tree type
);
447 vrange
& operator= (const vrange
&);
448 bool operator== (const Value_Range
&r
) const;
449 bool operator!= (const Value_Range
&r
) const;
451 operator const vrange
&() const;
452 void dump (FILE *) const;
453 static bool supports_type_p (const_tree type
);
455 // Convenience methods for vrange compatability.
456 void set (tree min
, tree max
, value_range_kind kind
= VR_RANGE
)
457 { return m_vrange
->set (min
, max
, kind
); }
458 tree
type () { return m_vrange
->type (); }
459 enum value_range_kind
kind () { return m_vrange
->kind (); }
460 bool varying_p () const { return m_vrange
->varying_p (); }
461 bool undefined_p () const { return m_vrange
->undefined_p (); }
462 void set_varying (tree type
) { m_vrange
->set_varying (type
); }
463 void set_undefined () { m_vrange
->set_undefined (); }
464 bool union_ (const vrange
&r
) { return m_vrange
->union_ (r
); }
465 bool intersect (const vrange
&r
) { return m_vrange
->intersect (r
); }
466 bool singleton_p (tree
*result
= NULL
) const
467 { return m_vrange
->singleton_p (result
); }
468 bool zero_p () const { return m_vrange
->zero_p (); }
469 wide_int
lower_bound () const; // For irange/prange compatability.
470 wide_int
upper_bound () const; // For irange/prange compatability.
471 void accept (const vrange_visitor
&v
) const { m_vrange
->accept (v
); }
473 void init (tree type
);
474 unsupported_range m_unsupported
;
476 int_range_max m_irange
;
481 Value_Range::Value_Range ()
483 m_vrange
= &m_unsupported
;
486 // Copy constructor from a vrange.
489 Value_Range::Value_Range (const vrange
&r
)
494 // Copy constructor from a TYPE. The range of the temporary is set to
498 Value_Range::Value_Range (tree type
)
504 Value_Range::Value_Range (const Value_Range
&r
)
506 m_vrange
= r
.m_vrange
;
509 // Initialize object so it is possible to store temporaries of TYPE
513 Value_Range::init (tree type
)
515 gcc_checking_assert (TYPE_P (type
));
517 if (irange::supports_p (type
))
518 m_vrange
= &m_irange
;
519 else if (frange::supports_p (type
))
520 m_vrange
= &m_frange
;
522 m_vrange
= &m_unsupported
;
525 // Set the temporary to allow storing temporaries of TYPE. The range
526 // of the temporary is set to UNDEFINED.
529 Value_Range::set_type (tree type
)
532 m_vrange
->set_undefined ();
535 // Assignment operator for temporaries. Copying incompatible types is
539 Value_Range::operator= (const vrange
&r
)
541 if (is_a
<irange
> (r
))
543 m_irange
= as_a
<irange
> (r
);
544 m_vrange
= &m_irange
;
546 else if (is_a
<frange
> (r
))
548 m_frange
= as_a
<frange
> (r
);
549 m_vrange
= &m_frange
;
558 Value_Range::operator== (const Value_Range
&r
) const
560 return *m_vrange
== *r
.m_vrange
;
564 Value_Range::operator!= (const Value_Range
&r
) const
566 return *m_vrange
!= *r
.m_vrange
;
570 Value_Range::operator vrange
&()
576 Value_Range::operator const vrange
&() const
581 // Return TRUE if TYPE is supported by the vrange infrastructure.
584 Value_Range::supports_type_p (const_tree type
)
586 return irange::supports_p (type
) || frange::supports_p (type
);
589 // Returns true for an old-school value_range as described above.
591 irange::legacy_mode_p () const
593 return m_max_ranges
== 1;
596 extern bool range_has_numeric_bounds_p (const irange
*);
597 extern bool ranges_from_anti_range (const value_range
*,
598 value_range
*, value_range
*);
599 extern void dump_value_range (FILE *, const vrange
*);
600 extern bool vrp_val_is_min (const_tree
);
601 extern bool vrp_val_is_max (const_tree
);
602 extern bool vrp_operand_equal_p (const_tree
, const_tree
);
603 inline REAL_VALUE_TYPE
frange_val_min (const_tree type
);
604 inline REAL_VALUE_TYPE
frange_val_max (const_tree type
);
606 inline value_range_kind
607 vrange::kind () const
612 // Number of sub-ranges in a range.
615 irange::num_pairs () const
617 if (m_kind
== VR_ANTI_RANGE
)
618 return constant_p () ? 2 : 1;
624 irange::type () const
626 gcc_checking_assert (m_num_ranges
> 0);
627 return TREE_TYPE (m_base
[0]);
630 // Return the lower bound of a sub-range expressed as a tree. PAIR is
631 // the sub-range in question.
634 irange::tree_lower_bound (unsigned pair
) const
636 return m_base
[pair
* 2];
639 // Return the upper bound of a sub-range expressed as a tree. PAIR is
640 // the sub-range in question.
643 irange::tree_upper_bound (unsigned pair
) const
645 return m_base
[pair
* 2 + 1];
648 // Return the highest bound of a range expressed as a tree.
651 irange::tree_upper_bound () const
653 gcc_checking_assert (m_num_ranges
);
654 return tree_upper_bound (m_num_ranges
- 1);
660 return tree_lower_bound (0);
667 return tree_upper_bound ();
673 irange::varying_compatible_p () const
675 if (m_num_ranges
!= 1)
680 tree t
= TREE_TYPE (l
);
682 if (m_kind
== VR_VARYING
&& t
== error_mark_node
)
685 unsigned prec
= TYPE_PRECISION (t
);
686 signop sign
= TYPE_SIGN (t
);
687 if (INTEGRAL_TYPE_P (t
))
688 return (wi::to_wide (l
) == wi::min_value (prec
, sign
)
689 && wi::to_wide (u
) == wi::max_value (prec
, sign
)
690 && (!m_nonzero_mask
|| wi::to_wide (m_nonzero_mask
) == -1));
691 if (POINTER_TYPE_P (t
))
692 return (wi::to_wide (l
) == 0
693 && wi::to_wide (u
) == wi::max_value (prec
, sign
)
694 && (!m_nonzero_mask
|| wi::to_wide (m_nonzero_mask
) == -1));
699 irange::set (tree type
, const wide_int_ref
&min
, const wide_int_ref
&max
,
700 value_range_kind kind
)
702 set (wide_int_to_tree (type
, min
), wide_int_to_tree (type
, max
), kind
);
706 vrange::varying_p () const
708 return m_kind
== VR_VARYING
;
712 vrange::undefined_p () const
714 return m_kind
== VR_UNDEFINED
;
718 irange::zero_p () const
720 return (m_kind
== VR_RANGE
&& m_num_ranges
== 1
721 && integer_zerop (tree_lower_bound (0))
722 && integer_zerop (tree_upper_bound (0)));
726 irange::nonzero_p () const
731 tree zero
= build_zero_cst (type ());
732 return *this == int_range
<1> (zero
, zero
, VR_ANTI_RANGE
);
736 irange::supports_p (const_tree type
)
738 return INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
);
742 range_includes_zero_p (const irange
*vr
)
744 if (vr
->undefined_p ())
747 if (vr
->varying_p ())
750 return vr
->may_contain_p (build_zero_cst (vr
->type ()));
754 gt_ggc_mx (irange
*x
)
756 for (unsigned i
= 0; i
< x
->m_num_ranges
; ++i
)
758 gt_ggc_mx (x
->m_base
[i
* 2]);
759 gt_ggc_mx (x
->m_base
[i
* 2 + 1]);
761 if (x
->m_nonzero_mask
)
762 gt_ggc_mx (x
->m_nonzero_mask
);
766 gt_pch_nx (irange
*x
)
768 for (unsigned i
= 0; i
< x
->m_num_ranges
; ++i
)
770 gt_pch_nx (x
->m_base
[i
* 2]);
771 gt_pch_nx (x
->m_base
[i
* 2 + 1]);
773 if (x
->m_nonzero_mask
)
774 gt_pch_nx (x
->m_nonzero_mask
);
778 gt_pch_nx (irange
*x
, gt_pointer_operator op
, void *cookie
)
780 for (unsigned i
= 0; i
< x
->m_num_ranges
; ++i
)
782 op (&x
->m_base
[i
* 2], NULL
, cookie
);
783 op (&x
->m_base
[i
* 2 + 1], NULL
, cookie
);
785 if (x
->m_nonzero_mask
)
786 op (&x
->m_nonzero_mask
, NULL
, cookie
);
791 gt_ggc_mx (int_range
<N
> *x
)
793 gt_ggc_mx ((irange
*) x
);
798 gt_pch_nx (int_range
<N
> *x
)
800 gt_pch_nx ((irange
*) x
);
805 gt_pch_nx (int_range
<N
> *x
, gt_pointer_operator op
, void *cookie
)
807 gt_pch_nx ((irange
*) x
, op
, cookie
);
810 // Constructors for irange
813 irange::irange (tree
*base
, unsigned nranges
)
815 m_discriminator
= VR_IRANGE
;
817 m_max_ranges
= nranges
;
821 // Constructors for int_range<>.
825 int_range
<N
>::int_range ()
826 : irange (m_ranges
, N
)
831 int_range
<N
>::int_range (const int_range
&other
)
832 : irange (m_ranges
, N
)
834 irange::operator= (other
);
838 int_range
<N
>::int_range (tree min
, tree max
, value_range_kind kind
)
839 : irange (m_ranges
, N
)
841 irange::set (min
, max
, kind
);
845 int_range
<N
>::int_range (tree type
)
846 : irange (m_ranges
, N
)
852 int_range
<N
>::int_range (tree type
, const wide_int
&wmin
, const wide_int
&wmax
,
853 value_range_kind kind
)
854 : irange (m_ranges
, N
)
856 tree min
= wide_int_to_tree (type
, wmin
);
857 tree max
= wide_int_to_tree (type
, wmax
);
858 set (min
, max
, kind
);
862 int_range
<N
>::int_range (const irange
&other
)
863 : irange (m_ranges
, N
)
865 irange::operator= (other
);
870 int_range
<N
>::operator= (const int_range
&src
)
872 irange::operator= (src
);
877 irange::set_undefined ()
879 m_kind
= VR_UNDEFINED
;
881 m_nonzero_mask
= NULL
;
885 irange::set_varying (tree type
)
889 m_nonzero_mask
= NULL
;
891 if (INTEGRAL_TYPE_P (type
))
893 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
894 // min_value and max_value.
895 wide_int min
= wi::min_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
896 wide_int max
= wi::max_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
897 if (wi::eq_p (max
, wi::to_wide (TYPE_MAX_VALUE (type
)))
898 && wi::eq_p (min
, wi::to_wide (TYPE_MIN_VALUE (type
))))
900 m_base
[0] = TYPE_MIN_VALUE (type
);
901 m_base
[1] = TYPE_MAX_VALUE (type
);
905 m_base
[0] = wide_int_to_tree (type
, min
);
906 m_base
[1] = wide_int_to_tree (type
, max
);
909 else if (POINTER_TYPE_P (type
))
911 m_base
[0] = build_int_cst (type
, 0);
912 m_base
[1] = build_int_cst (type
, -1);
915 m_base
[0] = m_base
[1] = error_mark_node
;
918 // Return the lower bound of a sub-range. PAIR is the sub-range in
922 irange::lower_bound (unsigned pair
) const
924 if (legacy_mode_p ())
925 return legacy_lower_bound (pair
);
926 gcc_checking_assert (m_num_ranges
> 0);
927 gcc_checking_assert (pair
+ 1 <= num_pairs ());
928 return wi::to_wide (tree_lower_bound (pair
));
931 // Return the upper bound of a sub-range. PAIR is the sub-range in
935 irange::upper_bound (unsigned pair
) const
937 if (legacy_mode_p ())
938 return legacy_upper_bound (pair
);
939 gcc_checking_assert (m_num_ranges
> 0);
940 gcc_checking_assert (pair
+ 1 <= num_pairs ());
941 return wi::to_wide (tree_upper_bound (pair
));
944 // Return the highest bound of a range.
947 irange::upper_bound () const
949 unsigned pairs
= num_pairs ();
950 gcc_checking_assert (pairs
> 0);
951 return upper_bound (pairs
- 1);
955 irange::union_ (const vrange
&r
)
957 dump_flags_t m_flags
= dump_flags
;
958 dump_flags
&= ~TDF_DETAILS
;
959 bool ret
= irange::legacy_verbose_union_ (&as_a
<irange
> (r
));
960 dump_flags
= m_flags
;
965 irange::intersect (const vrange
&r
)
967 dump_flags_t m_flags
= dump_flags
;
968 dump_flags
&= ~TDF_DETAILS
;
969 bool ret
= irange::legacy_verbose_intersect (&as_a
<irange
> (r
));
970 dump_flags
= m_flags
;
974 // Set value range VR to a nonzero range of type TYPE.
977 irange::set_nonzero (tree type
)
979 tree zero
= build_int_cst (type
, 0);
980 if (legacy_mode_p ())
981 set (zero
, zero
, VR_ANTI_RANGE
);
983 irange_set_anti_range (zero
, zero
);
986 // Set value range VR to a ZERO range of type TYPE.
989 irange::set_zero (tree type
)
991 tree z
= build_int_cst (type
, 0);
992 if (legacy_mode_p ())
998 // Normalize a range to VARYING or UNDEFINED if possible.
1001 irange::normalize_kind ()
1003 if (m_num_ranges
== 0)
1005 else if (varying_compatible_p ())
1007 if (m_kind
== VR_RANGE
)
1008 m_kind
= VR_VARYING
;
1009 else if (m_kind
== VR_ANTI_RANGE
)
1014 // Return the maximum value for TYPE.
1017 vrp_val_max (const_tree type
)
1019 if (INTEGRAL_TYPE_P (type
))
1020 return TYPE_MAX_VALUE (type
);
1021 if (POINTER_TYPE_P (type
))
1023 wide_int max
= wi::max_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
1024 return wide_int_to_tree (const_cast<tree
> (type
), max
);
1026 if (frange::supports_p (type
))
1028 REAL_VALUE_TYPE r
= frange_val_max (type
);
1029 return build_real (const_cast <tree
> (type
), r
);
1034 // Return the minimum value for TYPE.
1037 vrp_val_min (const_tree type
)
1039 if (INTEGRAL_TYPE_P (type
))
1040 return TYPE_MIN_VALUE (type
);
1041 if (POINTER_TYPE_P (type
))
1042 return build_zero_cst (const_cast<tree
> (type
));
1043 if (frange::supports_p (type
))
1045 REAL_VALUE_TYPE r
= frange_val_min (type
);
1046 return build_real (const_cast <tree
> (type
), r
);
1054 m_discriminator
= VR_FRANGE
;
1059 frange::frange (const frange
&src
)
1061 m_discriminator
= VR_FRANGE
;
1066 frange::frange (tree type
)
1068 m_discriminator
= VR_FRANGE
;
1072 // frange constructor from REAL_VALUE_TYPE endpoints.
1075 frange::frange (tree type
,
1076 const REAL_VALUE_TYPE
&min
, const REAL_VALUE_TYPE
&max
,
1077 value_range_kind kind
)
1079 m_discriminator
= VR_FRANGE
;
1080 set (type
, min
, max
, kind
);
1083 // frange constructor from trees.
1086 frange::frange (tree min
, tree max
, value_range_kind kind
)
1088 m_discriminator
= VR_FRANGE
;
1089 set (min
, max
, kind
);
1093 frange::type () const
1095 gcc_checking_assert (!undefined_p ());
1100 frange::set_varying (tree type
)
1102 m_kind
= VR_VARYING
;
1104 m_min
= frange_val_min (type
);
1105 m_max
= frange_val_max (type
);
1106 if (HONOR_NANS (m_type
))
1119 frange::set_undefined ()
1121 m_kind
= VR_UNDEFINED
;
1125 // m_min and m_min are unitialized as they are REAL_VALUE_TYPE ??.
1130 // Set the NAN bit and adjust the range.
1133 frange::update_nan ()
1135 gcc_checking_assert (!undefined_p ());
1136 if (HONOR_NANS (m_type
))
1146 // Like above, but set the sign of the NAN.
1149 frange::update_nan (bool sign
)
1151 gcc_checking_assert (!undefined_p ());
1152 if (HONOR_NANS (m_type
))
1162 // Clear the NAN bit and adjust the range.
1165 frange::clear_nan ()
1167 gcc_checking_assert (!undefined_p ());
1175 // Set R to maximum representable value for TYPE.
1177 inline REAL_VALUE_TYPE
1178 real_max_representable (const_tree type
)
1182 get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type
)),
1183 buf
, sizeof (buf
), false);
1184 int res
= real_from_string (&r
, buf
);
1185 gcc_checking_assert (!res
);
1189 // Return the minimum representable value for TYPE.
1191 inline REAL_VALUE_TYPE
1192 real_min_representable (const_tree type
)
1194 REAL_VALUE_TYPE r
= real_max_representable (type
);
1195 r
= real_value_negate (&r
);
1199 // Return the minimum value for TYPE.
1201 inline REAL_VALUE_TYPE
1202 frange_val_min (const_tree type
)
1204 if (HONOR_INFINITIES (type
))
1207 return real_min_representable (type
);
1210 // Return the maximum value for TYPE.
1212 inline REAL_VALUE_TYPE
1213 frange_val_max (const_tree type
)
1215 if (HONOR_INFINITIES (type
))
1218 return real_max_representable (type
);
1221 // Return TRUE if R is the minimum value for TYPE.
1224 frange_val_is_min (const REAL_VALUE_TYPE
&r
, const_tree type
)
1226 REAL_VALUE_TYPE min
= frange_val_min (type
);
1227 return real_identical (&min
, &r
);
1230 // Return TRUE if R is the max value for TYPE.
1233 frange_val_is_max (const REAL_VALUE_TYPE
&r
, const_tree type
)
1235 REAL_VALUE_TYPE max
= frange_val_max (type
);
1236 return real_identical (&max
, &r
);
1239 // Build a signless NAN of type TYPE.
1242 frange::set_nan (tree type
)
1244 if (HONOR_NANS (type
))
1257 // Build a NAN of type TYPE with SIGN.
1260 frange::set_nan (tree type
, bool sign
)
1262 if (HONOR_NANS (type
))
1275 // Return TRUE if range is known to be finite.
1278 frange::known_isfinite () const
1280 if (undefined_p () || varying_p () || m_kind
== VR_ANTI_RANGE
)
1282 return (!maybe_isnan () && !real_isinf (&m_min
) && !real_isinf (&m_max
));
1285 // Return TRUE if range may be infinite.
1288 frange::maybe_isinf () const
1290 if (undefined_p () || m_kind
== VR_ANTI_RANGE
|| m_kind
== VR_NAN
)
1294 return real_isinf (&m_min
) || real_isinf (&m_max
);
1297 // Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
1300 frange::known_isinf () const
1302 return (m_kind
== VR_RANGE
1303 && real_identical (&m_min
, &m_max
)
1304 && real_isinf (&m_min
));
1307 // Return TRUE if range is possibly a NAN.
1310 frange::maybe_isnan () const
1314 return m_pos_nan
|| m_neg_nan
;
1317 // Return TRUE if range is possibly a NAN with SIGN.
1320 frange::maybe_isnan (bool sign
) const
1329 // Return TRUE if range is a +NAN or -NAN.
1332 frange::known_isnan () const
1334 return m_kind
== VR_NAN
;
1337 // If the signbit for the range is known, set it in SIGNBIT and return
1341 frange::signbit_p (bool &signbit
) const
1346 // NAN with unknown sign.
1347 if (m_pos_nan
&& m_neg_nan
)
1350 if (!m_pos_nan
&& !m_neg_nan
)
1352 if (m_min
.sign
== m_max
.sign
)
1354 signbit
= m_min
.sign
;
1359 // NAN with known sign.
1360 bool nan_sign
= m_neg_nan
;
1362 || (nan_sign
== m_min
.sign
&& nan_sign
== m_max
.sign
))
1370 // If range has a NAN with a known sign, set it in SIGNBIT and return
1374 frange::nan_signbit_p (bool &signbit
) const
1379 if (m_pos_nan
== m_neg_nan
)
1382 signbit
= m_neg_nan
;
1386 #endif // GCC_VALUE_RANGE_H