c++: top level bind when rewriting coroutines [PR106188]
[official-gcc.git] / gcc / value-range.h
blob645dc76c33a833aae7c667c9702e03054bce6e20
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)
11 any later version.
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
25 class irange;
27 // Types of value ranges.
28 enum value_range_kind
30 /* Empty range. */
31 VR_UNDEFINED,
32 /* Range spans the entire domain. */
33 VR_VARYING,
34 /* Range is [MIN, MAX]. */
35 VR_RANGE,
36 /* Range is ~[MIN, MAX]. */
37 VR_ANTI_RANGE,
38 /* Range is a nice guy. */
39 VR_LAST
42 // Discriminator between different vrange types.
44 enum value_range_discriminator
46 // Range holds an integer or pointer.
47 VR_IRANGE,
48 // Floating point range.
49 VR_FRANGE,
50 // Range holds an unsupported type.
51 VR_UNKNOWN
54 // Abstract class for ranges of any of the supported types.
56 // To query what types ranger and the entire ecosystem can support,
57 // use Value_Range::supports_type_p(tree type). This is a static
58 // method available independently of any vrange object.
60 // To query what a given vrange variant can support, use:
61 // irange::supports_p ()
62 // frange::supports_p ()
63 // etc
65 // To query what a range object can support, use:
66 // void foo (vrange &v, irange &i, frange &f)
67 // {
68 // if (v.supports_type_p (type)) ...
69 // if (i.supports_type_p (type)) ...
70 // if (f.supports_type_p (type)) ...
71 // }
73 class vrange
75 template <typename T> friend bool is_a (vrange &);
76 friend class Value_Range;
77 public:
78 virtual void accept (const class vrange_visitor &v) const = 0;
79 virtual void set (tree, tree, value_range_kind = VR_RANGE);
80 virtual tree type () const;
81 virtual bool supports_type_p (const_tree type) const;
82 virtual void set_varying (tree type);
83 virtual void set_undefined ();
84 virtual bool union_ (const vrange &);
85 virtual bool intersect (const vrange &);
86 virtual bool singleton_p (tree *result = NULL) const;
87 virtual bool contains_p (tree cst) const;
88 virtual bool zero_p () const;
89 virtual bool nonzero_p () const;
90 virtual void set_nonzero (tree type);
91 virtual void set_zero (tree type);
92 virtual void set_nonnegative (tree type);
93 virtual bool fits_p (const vrange &r) const;
95 bool varying_p () const;
96 bool undefined_p () const;
97 vrange& operator= (const vrange &);
98 bool operator== (const vrange &) const;
99 bool operator!= (const vrange &r) const { return !(*this == r); }
100 void dump (FILE *) const;
102 enum value_range_kind kind () const; // DEPRECATED
104 protected:
105 ENUM_BITFIELD(value_range_kind) m_kind : 8;
106 ENUM_BITFIELD(value_range_discriminator) m_discriminator : 4;
109 // An integer range without any storage.
111 class GTY((user)) irange : public vrange
113 friend class vrange_allocator;
114 friend class irange_storage_slot; // For legacy_mode_p checks.
115 public:
116 // In-place setters.
117 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
118 virtual void set_nonzero (tree type) override;
119 virtual void set_zero (tree type) override;
120 virtual void set_nonnegative (tree type) override;
121 virtual void set_varying (tree type) override;
122 virtual void set_undefined () override;
124 // Range types.
125 static bool supports_p (const_tree type);
126 virtual bool supports_type_p (const_tree type) const override;
127 virtual tree type () const override;
129 // Iteration over sub-ranges.
130 unsigned num_pairs () const;
131 wide_int lower_bound (unsigned = 0) const;
132 wide_int upper_bound (unsigned) const;
133 wide_int upper_bound () const;
135 // Predicates.
136 virtual bool zero_p () const override;
137 virtual bool nonzero_p () const override;
138 virtual bool singleton_p (tree *result = NULL) const override;
139 virtual bool contains_p (tree cst) const override;
141 // In-place operators.
142 virtual bool union_ (const vrange &) override;
143 virtual bool intersect (const vrange &) override;
144 void invert ();
146 // Operator overloads.
147 irange& operator= (const irange &);
148 bool operator== (const irange &) const;
149 bool operator!= (const irange &r) const { return !(*this == r); }
151 // Misc methods.
152 virtual bool fits_p (const vrange &r) const override;
153 virtual void accept (const vrange_visitor &v) const override;
155 // Nonzero masks.
156 wide_int get_nonzero_bits () const;
157 void set_nonzero_bits (const wide_int_ref &bits);
159 // Deprecated legacy public methods.
160 tree min () const; // DEPRECATED
161 tree max () const; // DEPRECATED
162 bool symbolic_p () const; // DEPRECATED
163 bool constant_p () const; // DEPRECATED
164 void normalize_symbolics (); // DEPRECATED
165 void normalize_addresses (); // DEPRECATED
166 bool may_contain_p (tree) const; // DEPRECATED
167 bool legacy_verbose_union_ (const class irange *); // DEPRECATED
168 bool legacy_verbose_intersect (const irange *); // DEPRECATED
170 protected:
171 irange (tree *, unsigned);
172 // potential promotion to public?
173 tree tree_lower_bound (unsigned = 0) const;
174 tree tree_upper_bound (unsigned) const;
175 tree tree_upper_bound () const;
177 // In-place operators.
178 bool irange_union (const irange &);
179 bool irange_intersect (const irange &);
180 void irange_set (tree, tree);
181 void irange_set_anti_range (tree, tree);
182 bool irange_contains_p (const irange &) const;
183 bool irange_single_pair_union (const irange &r);
185 void normalize_kind ();
187 bool legacy_mode_p () const;
188 bool legacy_equal_p (const irange &) const;
189 void legacy_union (irange *, const irange *);
190 void legacy_intersect (irange *, const irange *);
191 void verify_range ();
192 wide_int legacy_lower_bound (unsigned = 0) const;
193 wide_int legacy_upper_bound (unsigned) const;
194 int value_inside_range (tree) const;
195 bool maybe_anti_range () const;
196 void copy_to_legacy (const irange &);
197 void copy_legacy_to_multi_range (const irange &);
199 private:
200 friend void gt_ggc_mx (irange *);
201 friend void gt_pch_nx (irange *);
202 friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
204 void irange_set_1bit_anti_range (tree, tree);
205 bool varying_compatible_p () const;
206 void set_nonzero_bits (tree mask);
207 bool intersect_nonzero_bits (const irange &r);
208 bool union_nonzero_bits (const irange &r);
210 bool intersect (const wide_int& lb, const wide_int& ub);
211 unsigned char m_num_ranges;
212 unsigned char m_max_ranges;
213 tree m_nonzero_mask;
214 tree *m_base;
217 // Here we describe an irange with N pairs of ranges. The storage for
218 // the pairs is embedded in the class as an array.
220 template<unsigned N>
221 class GTY((user)) int_range : public irange
223 public:
224 int_range ();
225 int_range (tree, tree, value_range_kind = VR_RANGE);
226 int_range (tree type, const wide_int &, const wide_int &,
227 value_range_kind = VR_RANGE);
228 int_range (tree type);
229 int_range (const int_range &);
230 int_range (const irange &);
231 virtual ~int_range () = default;
232 int_range& operator= (const int_range &);
233 private:
234 template <unsigned X> friend void gt_ggc_mx (int_range<X> *);
235 template <unsigned X> friend void gt_pch_nx (int_range<X> *);
236 template <unsigned X> friend void gt_pch_nx (int_range<X> *,
237 gt_pointer_operator, void *);
239 // ?? These stubs are for ipa-prop.cc which use a value_range in a
240 // hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
241 // instead of picking up the gt_ggc_mx (T *) version.
242 friend void gt_ggc_mx (int_range<1> *&);
243 friend void gt_pch_nx (int_range<1> *&);
245 tree m_ranges[N*2];
248 // Unsupported temporaries may be created by ranger before it's known
249 // they're unsupported, or by vr_values::get_value_range.
251 class unsupported_range : public vrange
253 public:
254 unsupported_range ()
256 m_discriminator = VR_UNKNOWN;
257 set_undefined ();
259 virtual void set_undefined () final override
261 m_kind = VR_UNDEFINED;
263 virtual void accept (const vrange_visitor &v) const override;
266 // Floating point property to represent possible values of a NAN, INF, etc.
268 class fp_prop
270 public:
271 enum kind {
272 UNDEFINED = 0x0, // Prop is impossible.
273 YES = 0x1, // Prop is definitely set.
274 NO = 0x2, // Prop is definitely not set.
275 VARYING = (YES | NO) // Prop may hold.
277 fp_prop (kind f) : m_kind (f) { }
278 bool varying_p () const { return m_kind == VARYING; }
279 bool undefined_p () const { return m_kind == UNDEFINED; }
280 bool yes_p () const { return m_kind == YES; }
281 bool no_p () const { return m_kind == NO; }
282 private:
283 unsigned char m_kind : 2;
286 // Accessors for individual FP properties.
288 #define FP_PROP_ACCESSOR(NAME) \
289 void NAME##_set_varying () { u.bits.NAME = fp_prop::VARYING; } \
290 void NAME##_set_yes () { u.bits.NAME = fp_prop::YES; } \
291 void NAME##_set_no () { u.bits.NAME = fp_prop::NO; } \
292 bool NAME##_varying_p () const { return u.bits.NAME == fp_prop::VARYING; } \
293 bool NAME##_undefined_p () const { return u.bits.NAME == fp_prop::UNDEFINED; } \
294 bool NAME##_yes_p () const { return u.bits.NAME == fp_prop::YES; } \
295 bool NAME##_no_p () const { return u.bits.NAME == fp_prop::NO; } \
296 fp_prop get_##NAME () const \
297 { return fp_prop ((fp_prop::kind) u.bits.NAME); } \
298 void set_##NAME (fp_prop::kind f) { u.bits.NAME = f; }
300 // Aggregate of all the FP properties in an frange packed into one
301 // structure to save space. Using explicit fp_prop's in the frange,
302 // would take one byte per property because of padding. Instead, we
303 // can save all properties into one byte.
305 class frange_props
307 public:
308 frange_props () { set_varying (); }
309 void set_varying () { u.bytes = 0xff; }
310 void set_undefined () { u.bytes = 0; }
311 bool varying_p () { return u.bytes == 0xff; }
312 bool undefined_p () { return u.bytes == 0; }
313 bool union_ (const frange_props &other);
314 bool intersect (const frange_props &other);
315 bool operator== (const frange_props &other) const;
316 FP_PROP_ACCESSOR(nan)
317 FP_PROP_ACCESSOR(signbit)
318 private:
319 union {
320 struct {
321 unsigned char nan : 2;
322 unsigned char signbit : 2;
323 } bits;
324 unsigned char bytes;
325 } u;
328 // A floating point range.
330 class frange : public vrange
332 friend class frange_storage_slot;
333 public:
334 frange ();
335 frange (const frange &);
336 frange (tree, tree, value_range_kind = VR_RANGE);
337 frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
338 value_range_kind = VR_RANGE);
339 static bool supports_p (const_tree type)
341 // ?? Decimal floats can have multiple representations for the
342 // same number. Supporting them may be as simple as just
343 // disabling them in singleton_p. No clue.
344 return SCALAR_FLOAT_TYPE_P (type) && !DECIMAL_FLOAT_TYPE_P (type);
346 virtual tree type () const override;
347 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
348 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
349 value_range_kind = VR_RANGE);
350 virtual void set_varying (tree type) override;
351 virtual void set_undefined () override;
352 virtual bool union_ (const vrange &) override;
353 virtual bool intersect (const vrange &) override;
354 virtual bool contains_p (tree) const override;
355 virtual bool singleton_p (tree *result = NULL) const override;
356 virtual bool supports_type_p (const_tree type) const override;
357 virtual void accept (const vrange_visitor &v) const override;
358 virtual bool zero_p () const override;
359 virtual bool nonzero_p () const override;
360 virtual void set_nonzero (tree type) override;
361 virtual void set_zero (tree type) override;
362 virtual void set_nonnegative (tree type) override;
363 frange& operator= (const frange &);
364 bool operator== (const frange &) const;
365 bool operator!= (const frange &r) const { return !(*this == r); }
366 const REAL_VALUE_TYPE &lower_bound () const;
367 const REAL_VALUE_TYPE &upper_bound () const;
369 // Accessors for FP properties.
370 fp_prop get_nan () const { return m_props.get_nan (); }
371 void set_nan (fp_prop::kind f);
372 fp_prop get_signbit () const { return m_props.get_signbit (); }
373 void set_signbit (fp_prop::kind);
374 private:
375 void verify_range ();
376 bool normalize_kind ();
378 frange_props m_props;
379 tree m_type;
380 REAL_VALUE_TYPE m_min;
381 REAL_VALUE_TYPE m_max;
384 inline const REAL_VALUE_TYPE &
385 frange::lower_bound () const
387 gcc_checking_assert (!undefined_p ());
388 return m_min;
391 inline const REAL_VALUE_TYPE &
392 frange::upper_bound () const
394 gcc_checking_assert (!undefined_p ());
395 return m_max;
398 // is_a<> and as_a<> implementation for vrange.
400 // Anything we haven't specialized is a hard fail.
401 template <typename T>
402 inline bool
403 is_a (vrange &)
405 gcc_unreachable ();
406 return false;
409 template <typename T>
410 inline bool
411 is_a (const vrange &v)
413 // Reuse is_a <vrange> to implement the const version.
414 const T &derived = static_cast<const T &> (v);
415 return is_a <T> (const_cast<T &> (derived));
418 template <typename T>
419 inline T &
420 as_a (vrange &v)
422 gcc_checking_assert (is_a <T> (v));
423 return static_cast <T &> (v);
426 template <typename T>
427 inline const T &
428 as_a (const vrange &v)
430 gcc_checking_assert (is_a <T> (v));
431 return static_cast <const T &> (v);
434 // Specializations for the different range types.
436 template <>
437 inline bool
438 is_a <irange> (vrange &v)
440 return v.m_discriminator == VR_IRANGE;
443 template <>
444 inline bool
445 is_a <frange> (vrange &v)
447 return v.m_discriminator == VR_FRANGE;
450 class vrange_visitor
452 public:
453 virtual void visit (const irange &) const { }
454 virtual void visit (const frange &) const { }
455 virtual void visit (const unsupported_range &) const { }
458 // This is a special int_range<1> with only one pair, plus
459 // VR_ANTI_RANGE magic to describe slightly more than can be described
460 // in one pair. It is described in the code as a "legacy range" (as
461 // opposed to multi-ranges which have multiple sub-ranges). It is
462 // provided for backward compatibility with code that has not been
463 // converted to multi-range irange's.
465 // There are copy operators to seamlessly copy to/fro multi-ranges.
466 typedef int_range<1> value_range;
468 // This is an "infinite" precision irange for use in temporary
469 // calculations.
470 typedef int_range<255> int_range_max;
472 // This is an "infinite" precision range object for use in temporary
473 // calculations for any of the handled types. The object can be
474 // transparently used as a vrange.
476 class Value_Range
478 public:
479 Value_Range ();
480 Value_Range (const vrange &r);
481 Value_Range (tree type);
482 Value_Range (const Value_Range &);
483 void set_type (tree type);
484 vrange& operator= (const vrange &);
485 bool operator== (const Value_Range &r) const;
486 bool operator!= (const Value_Range &r) const;
487 operator vrange &();
488 operator const vrange &() const;
489 void dump (FILE *) const;
490 static bool supports_type_p (const_tree type);
492 // Convenience methods for vrange compatability.
493 void set (tree min, tree max, value_range_kind kind = VR_RANGE)
494 { return m_vrange->set (min, max, kind); }
495 tree type () { return m_vrange->type (); }
496 enum value_range_kind kind () { return m_vrange->kind (); }
497 bool varying_p () const { return m_vrange->varying_p (); }
498 bool undefined_p () const { return m_vrange->undefined_p (); }
499 void set_varying (tree type) { m_vrange->set_varying (type); }
500 void set_undefined () { m_vrange->set_undefined (); }
501 bool union_ (const vrange &r) { return m_vrange->union_ (r); }
502 bool intersect (const vrange &r) { return m_vrange->intersect (r); }
503 bool singleton_p (tree *result = NULL) const
504 { return m_vrange->singleton_p (result); }
505 bool zero_p () const { return m_vrange->zero_p (); }
506 wide_int lower_bound () const; // For irange/prange compatability.
507 wide_int upper_bound () const; // For irange/prange compatability.
508 void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
509 private:
510 void init (tree type);
511 unsupported_range m_unsupported;
512 vrange *m_vrange;
513 int_range_max m_irange;
514 frange m_frange;
517 inline
518 Value_Range::Value_Range ()
520 m_vrange = &m_unsupported;
523 // Copy constructor from a vrange.
525 inline
526 Value_Range::Value_Range (const vrange &r)
528 *this = r;
531 // Copy constructor from a TYPE. The range of the temporary is set to
532 // UNDEFINED.
534 inline
535 Value_Range::Value_Range (tree type)
537 init (type);
540 inline
541 Value_Range::Value_Range (const Value_Range &r)
543 m_vrange = r.m_vrange;
546 // Initialize object so it is possible to store temporaries of TYPE
547 // into it.
549 inline void
550 Value_Range::init (tree type)
552 gcc_checking_assert (TYPE_P (type));
554 if (irange::supports_p (type))
555 m_vrange = &m_irange;
556 else if (frange::supports_p (type))
557 m_vrange = &m_frange;
558 else
559 m_vrange = &m_unsupported;
562 // Set the temporary to allow storing temporaries of TYPE. The range
563 // of the temporary is set to UNDEFINED.
565 inline void
566 Value_Range::set_type (tree type)
568 init (type);
569 m_vrange->set_undefined ();
572 // Assignment operator for temporaries. Copying incompatible types is
573 // allowed.
575 inline vrange &
576 Value_Range::operator= (const vrange &r)
578 if (is_a <irange> (r))
580 m_irange = as_a <irange> (r);
581 m_vrange = &m_irange;
583 else if (is_a <frange> (r))
585 m_frange = as_a <frange> (r);
586 m_vrange = &m_frange;
588 else
589 gcc_unreachable ();
591 return *m_vrange;
594 inline bool
595 Value_Range::operator== (const Value_Range &r) const
597 return *m_vrange == *r.m_vrange;
600 inline bool
601 Value_Range::operator!= (const Value_Range &r) const
603 return *m_vrange != *r.m_vrange;
606 inline
607 Value_Range::operator vrange &()
609 return *m_vrange;
612 inline
613 Value_Range::operator const vrange &() const
615 return *m_vrange;
618 // Return TRUE if TYPE is supported by the vrange infrastructure.
620 inline bool
621 Value_Range::supports_type_p (const_tree type)
623 return irange::supports_p (type) || frange::supports_p (type);
626 // Returns true for an old-school value_range as described above.
627 inline bool
628 irange::legacy_mode_p () const
630 return m_max_ranges == 1;
633 extern bool range_has_numeric_bounds_p (const irange *);
634 extern bool ranges_from_anti_range (const value_range *,
635 value_range *, value_range *);
636 extern void dump_value_range (FILE *, const vrange *);
637 extern bool vrp_val_is_min (const_tree);
638 extern bool vrp_val_is_max (const_tree);
639 extern bool vrp_operand_equal_p (const_tree, const_tree);
641 inline value_range_kind
642 vrange::kind () const
644 return m_kind;
647 // Number of sub-ranges in a range.
649 inline unsigned
650 irange::num_pairs () const
652 if (m_kind == VR_ANTI_RANGE)
653 return constant_p () ? 2 : 1;
654 else
655 return m_num_ranges;
658 inline tree
659 irange::type () const
661 gcc_checking_assert (m_num_ranges > 0);
662 return TREE_TYPE (m_base[0]);
665 // Return the lower bound of a sub-range expressed as a tree. PAIR is
666 // the sub-range in question.
668 inline tree
669 irange::tree_lower_bound (unsigned pair) const
671 return m_base[pair * 2];
674 // Return the upper bound of a sub-range expressed as a tree. PAIR is
675 // the sub-range in question.
677 inline tree
678 irange::tree_upper_bound (unsigned pair) const
680 return m_base[pair * 2 + 1];
683 // Return the highest bound of a range expressed as a tree.
685 inline tree
686 irange::tree_upper_bound () const
688 gcc_checking_assert (m_num_ranges);
689 return tree_upper_bound (m_num_ranges - 1);
692 inline tree
693 irange::min () const
695 return tree_lower_bound (0);
698 inline tree
699 irange::max () const
701 if (m_num_ranges)
702 return tree_upper_bound ();
703 else
704 return NULL;
707 inline bool
708 irange::varying_compatible_p () const
710 if (m_num_ranges != 1)
711 return false;
713 tree l = m_base[0];
714 tree u = m_base[1];
715 tree t = TREE_TYPE (l);
717 if (m_kind == VR_VARYING && t == error_mark_node)
718 return true;
720 unsigned prec = TYPE_PRECISION (t);
721 signop sign = TYPE_SIGN (t);
722 if (INTEGRAL_TYPE_P (t))
723 return (wi::to_wide (l) == wi::min_value (prec, sign)
724 && wi::to_wide (u) == wi::max_value (prec, sign)
725 && !m_nonzero_mask);
726 if (POINTER_TYPE_P (t))
727 return (wi::to_wide (l) == 0
728 && wi::to_wide (u) == wi::max_value (prec, sign));
729 return true;
732 inline bool
733 vrange::varying_p () const
735 return m_kind == VR_VARYING;
738 inline bool
739 vrange::undefined_p () const
741 return m_kind == VR_UNDEFINED;
744 inline bool
745 irange::zero_p () const
747 return (m_kind == VR_RANGE && m_num_ranges == 1
748 && integer_zerop (tree_lower_bound (0))
749 && integer_zerop (tree_upper_bound (0)));
752 inline bool
753 irange::nonzero_p () const
755 if (undefined_p ())
756 return false;
758 tree zero = build_zero_cst (type ());
759 return *this == int_range<1> (zero, zero, VR_ANTI_RANGE);
762 inline bool
763 irange::supports_p (const_tree type)
765 return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
768 inline bool
769 range_includes_zero_p (const irange *vr)
771 if (vr->undefined_p ())
772 return false;
774 if (vr->varying_p ())
775 return true;
777 return vr->may_contain_p (build_zero_cst (vr->type ()));
780 inline void
781 gt_ggc_mx (irange *x)
783 for (unsigned i = 0; i < x->m_num_ranges; ++i)
785 gt_ggc_mx (x->m_base[i * 2]);
786 gt_ggc_mx (x->m_base[i * 2 + 1]);
788 if (x->m_nonzero_mask)
789 gt_ggc_mx (x->m_nonzero_mask);
792 inline void
793 gt_pch_nx (irange *x)
795 for (unsigned i = 0; i < x->m_num_ranges; ++i)
797 gt_pch_nx (x->m_base[i * 2]);
798 gt_pch_nx (x->m_base[i * 2 + 1]);
800 if (x->m_nonzero_mask)
801 gt_pch_nx (x->m_nonzero_mask);
804 inline void
805 gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie)
807 for (unsigned i = 0; i < x->m_num_ranges; ++i)
809 op (&x->m_base[i * 2], NULL, cookie);
810 op (&x->m_base[i * 2 + 1], NULL, cookie);
812 if (x->m_nonzero_mask)
813 op (&x->m_nonzero_mask, NULL, cookie);
816 template<unsigned N>
817 inline void
818 gt_ggc_mx (int_range<N> *x)
820 gt_ggc_mx ((irange *) x);
823 template<unsigned N>
824 inline void
825 gt_pch_nx (int_range<N> *x)
827 gt_pch_nx ((irange *) x);
830 template<unsigned N>
831 inline void
832 gt_pch_nx (int_range<N> *x, gt_pointer_operator op, void *cookie)
834 gt_pch_nx ((irange *) x, op, cookie);
837 // Constructors for irange
839 inline
840 irange::irange (tree *base, unsigned nranges)
842 m_discriminator = VR_IRANGE;
843 m_base = base;
844 m_max_ranges = nranges;
845 set_undefined ();
848 // Constructors for int_range<>.
850 template<unsigned N>
851 inline
852 int_range<N>::int_range ()
853 : irange (m_ranges, N)
857 template<unsigned N>
858 int_range<N>::int_range (const int_range &other)
859 : irange (m_ranges, N)
861 irange::operator= (other);
864 template<unsigned N>
865 int_range<N>::int_range (tree min, tree max, value_range_kind kind)
866 : irange (m_ranges, N)
868 irange::set (min, max, kind);
871 template<unsigned N>
872 int_range<N>::int_range (tree type)
873 : irange (m_ranges, N)
875 set_varying (type);
878 template<unsigned N>
879 int_range<N>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
880 value_range_kind kind)
881 : irange (m_ranges, N)
883 tree min = wide_int_to_tree (type, wmin);
884 tree max = wide_int_to_tree (type, wmax);
885 set (min, max, kind);
888 template<unsigned N>
889 int_range<N>::int_range (const irange &other)
890 : irange (m_ranges, N)
892 irange::operator= (other);
895 template<unsigned N>
896 int_range<N>&
897 int_range<N>::operator= (const int_range &src)
899 irange::operator= (src);
900 return *this;
903 inline void
904 irange::set_undefined ()
906 m_kind = VR_UNDEFINED;
907 m_num_ranges = 0;
908 m_nonzero_mask = NULL;
911 inline void
912 irange::set_varying (tree type)
914 m_kind = VR_VARYING;
915 m_num_ranges = 1;
916 m_nonzero_mask = NULL;
918 if (INTEGRAL_TYPE_P (type))
920 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
921 // min_value and max_value.
922 wide_int min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
923 wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
924 if (wi::eq_p (max, wi::to_wide (TYPE_MAX_VALUE (type)))
925 && wi::eq_p (min, wi::to_wide (TYPE_MIN_VALUE (type))))
927 m_base[0] = TYPE_MIN_VALUE (type);
928 m_base[1] = TYPE_MAX_VALUE (type);
930 else
932 m_base[0] = wide_int_to_tree (type, min);
933 m_base[1] = wide_int_to_tree (type, max);
936 else if (POINTER_TYPE_P (type))
938 m_base[0] = build_int_cst (type, 0);
939 m_base[1] = build_int_cst (type, -1);
941 else
942 m_base[0] = m_base[1] = error_mark_node;
945 // Return the lower bound of a sub-range. PAIR is the sub-range in
946 // question.
948 inline wide_int
949 irange::lower_bound (unsigned pair) const
951 if (legacy_mode_p ())
952 return legacy_lower_bound (pair);
953 gcc_checking_assert (m_num_ranges > 0);
954 gcc_checking_assert (pair + 1 <= num_pairs ());
955 return wi::to_wide (tree_lower_bound (pair));
958 // Return the upper bound of a sub-range. PAIR is the sub-range in
959 // question.
961 inline wide_int
962 irange::upper_bound (unsigned pair) const
964 if (legacy_mode_p ())
965 return legacy_upper_bound (pair);
966 gcc_checking_assert (m_num_ranges > 0);
967 gcc_checking_assert (pair + 1 <= num_pairs ());
968 return wi::to_wide (tree_upper_bound (pair));
971 // Return the highest bound of a range.
973 inline wide_int
974 irange::upper_bound () const
976 unsigned pairs = num_pairs ();
977 gcc_checking_assert (pairs > 0);
978 return upper_bound (pairs - 1);
981 inline bool
982 irange::union_ (const vrange &r)
984 dump_flags_t m_flags = dump_flags;
985 dump_flags &= ~TDF_DETAILS;
986 bool ret = irange::legacy_verbose_union_ (&as_a <irange> (r));
987 dump_flags = m_flags;
988 return ret;
991 inline bool
992 irange::intersect (const vrange &r)
994 dump_flags_t m_flags = dump_flags;
995 dump_flags &= ~TDF_DETAILS;
996 bool ret = irange::legacy_verbose_intersect (&as_a <irange> (r));
997 dump_flags = m_flags;
998 return ret;
1001 // Set value range VR to a nonzero range of type TYPE.
1003 inline void
1004 irange::set_nonzero (tree type)
1006 tree zero = build_int_cst (type, 0);
1007 if (legacy_mode_p ())
1008 set (zero, zero, VR_ANTI_RANGE);
1009 else
1010 irange_set_anti_range (zero, zero);
1013 // Set value range VR to a ZERO range of type TYPE.
1015 inline void
1016 irange::set_zero (tree type)
1018 tree z = build_int_cst (type, 0);
1019 if (legacy_mode_p ())
1020 set (z, z);
1021 else
1022 irange_set (z, z);
1025 // Normalize a range to VARYING or UNDEFINED if possible.
1027 inline void
1028 irange::normalize_kind ()
1030 if (m_num_ranges == 0)
1031 set_undefined ();
1032 else if (varying_compatible_p ())
1034 if (m_kind == VR_RANGE)
1035 m_kind = VR_VARYING;
1036 else if (m_kind == VR_ANTI_RANGE)
1037 set_undefined ();
1038 else
1039 gcc_unreachable ();
1043 // Return the maximum value for TYPE.
1045 inline tree
1046 vrp_val_max (const_tree type)
1048 if (INTEGRAL_TYPE_P (type))
1049 return TYPE_MAX_VALUE (type);
1050 if (POINTER_TYPE_P (type))
1052 wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1053 return wide_int_to_tree (const_cast<tree> (type), max);
1055 if (frange::supports_p (type))
1056 return build_real (const_cast <tree> (type), dconstinf);
1057 return NULL_TREE;
1060 // Return the minimum value for TYPE.
1062 inline tree
1063 vrp_val_min (const_tree type)
1065 if (INTEGRAL_TYPE_P (type))
1066 return TYPE_MIN_VALUE (type);
1067 if (POINTER_TYPE_P (type))
1068 return build_zero_cst (const_cast<tree> (type));
1069 if (frange::supports_p (type))
1070 return build_real (const_cast <tree> (type), dconstninf);
1071 return NULL_TREE;
1074 // Supporting methods for frange.
1076 inline bool
1077 frange_props::operator== (const frange_props &other) const
1079 return u.bytes == other.u.bytes;
1082 inline bool
1083 frange_props::union_ (const frange_props &other)
1085 unsigned char saved = u.bytes;
1086 u.bytes |= other.u.bytes;
1087 return u.bytes != saved;
1090 inline bool
1091 frange_props::intersect (const frange_props &other)
1093 unsigned char saved = u.bytes;
1094 u.bytes &= other.u.bytes;
1095 return u.bytes != saved;
1098 inline
1099 frange::frange ()
1101 m_discriminator = VR_FRANGE;
1102 set_undefined ();
1105 inline
1106 frange::frange (const frange &src)
1108 m_discriminator = VR_FRANGE;
1109 *this = src;
1112 // frange constructor from REAL_VALUE_TYPE endpoints.
1114 inline
1115 frange::frange (tree type,
1116 const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
1117 value_range_kind kind)
1119 m_discriminator = VR_FRANGE;
1120 set (type, min, max, kind);
1123 // frange constructor from trees.
1125 inline
1126 frange::frange (tree min, tree max, value_range_kind kind)
1128 m_discriminator = VR_FRANGE;
1129 set (min, max, kind);
1132 inline tree
1133 frange::type () const
1135 return m_type;
1138 inline void
1139 frange::set_varying (tree type)
1141 m_kind = VR_VARYING;
1142 m_type = type;
1143 m_min = dconstninf;
1144 m_max = dconstinf;
1145 m_props.set_varying ();
1148 inline void
1149 frange::set_undefined ()
1151 m_kind = VR_UNDEFINED;
1152 m_type = NULL;
1153 m_props.set_undefined ();
1154 memset (&m_min, 0, sizeof (m_min));
1155 memset (&m_max, 0, sizeof (m_max));
1158 // Set R to maximum representable value for TYPE.
1160 inline void
1161 real_max_representable (REAL_VALUE_TYPE *r, tree type)
1163 char buf[128];
1164 get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type)),
1165 buf, sizeof (buf), false);
1166 int res = real_from_string (r, buf);
1167 gcc_checking_assert (!res);
1170 // Set R to minimum representable value for TYPE.
1172 inline void
1173 real_min_representable (REAL_VALUE_TYPE *r, tree type)
1175 real_max_representable (r, type);
1176 *r = real_value_negate (r);
1179 // Build a NAN of type TYPE.
1181 inline frange
1182 frange_nan (tree type)
1184 REAL_VALUE_TYPE r;
1186 gcc_assert (real_nan (&r, "", 1, TYPE_MODE (type)));
1187 return frange (type, r, r);
1190 #endif // GCC_VALUE_RANGE_H