GCC Middle and Back End API Reference
value-range.h
Go to the documentation of this file.
1/* Support routines for value ranges.
2 Copyright (C) 2019-2025 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew Macleod <amacleod@redhat.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#ifndef GCC_VALUE_RANGE_H
23#define GCC_VALUE_RANGE_H
24
25class irange;
26
27// Types of value ranges.
29{
30 /* Empty range. */
32 /* Range spans the entire domain. */
34 /* Range is [MIN, MAX]. */
36 /* Range is ~[MIN, MAX]. */
38 /* Range is a NAN. */
40 /* Range is a nice guy. */
42};
43
44// Discriminator between different vrange types.
45
47{
48 // Range holds an integer or pointer.
50 // Pointer range.
52 // Floating point range.
54 // Range holds an unsupported type.
56};
57
58// Abstract class for ranges of any of the supported types.
59//
60// To query what types ranger and the entire ecosystem can support,
61// use value_range::supports_type_p(tree type). This is a static
62// method available independently of any vrange object.
63//
64// To query what a given vrange variant can support, use:
65// irange::supports_p ()
66// frange::supports_p ()
67// etc
68//
69// To query what a range object can support, use:
70// void foo (vrange &v, irange &i, frange &f)
71// {
72// if (v.supports_type_p (type)) ...
73// if (i.supports_type_p (type)) ...
74// if (f.supports_type_p (type)) ...
75// }
76
77class vrange
78{
79 template <typename T> friend bool is_a (vrange &);
80 friend class value_range;
81 friend void streamer_write_vrange (struct output_block *, const vrange &);
82 friend class range_op_handler;
83public:
84 virtual void accept (const class vrange_visitor &v) const = 0;
85 virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
86 virtual tree type () const = 0;
87 virtual bool supports_type_p (const_tree type) const = 0;
88 virtual void set_varying (tree type) = 0;
89 virtual void set_undefined () = 0;
90 virtual bool union_ (const vrange &) = 0;
91 virtual bool intersect (const vrange &) = 0;
92 virtual bool singleton_p (tree *result = NULL) const = 0;
93 virtual bool contains_p (tree cst) const = 0;
94 virtual bool zero_p () const = 0;
95 virtual bool nonzero_p () const = 0;
96 virtual void set_nonzero (tree type) = 0;
97 virtual void set_zero (tree type) = 0;
98 virtual void set_nonnegative (tree type) = 0;
99 virtual bool fits_p (const vrange &r) const = 0;
100 virtual ~vrange () { }
101 virtual tree lbound () const = 0;
102 virtual tree ubound () const = 0;
103 virtual void update_bitmask (const class irange_bitmask &);
104 virtual irange_bitmask get_bitmask () const;
105 wide_int get_nonzero_bits () const;
106 void set_nonzero_bits (const wide_int &bits);
107
108 bool varying_p () const;
109 bool undefined_p () const;
110 vrange& operator= (const vrange &);
111 bool operator== (const vrange &) const;
112 bool operator!= (const vrange &r) const { return !(*this == r); }
113 void dump (FILE *) const;
114protected:
116 ENUM_BITFIELD(value_range_kind) m_kind : 8;
118};
119
120namespace inchash
121{
122 extern void add_vrange (const vrange &, hash &, unsigned flags = 0);
123}
124
125// A pair of values representing the known bits in a range. Zero bits
126// in MASK cover constant values. Set bits in MASK cover unknown
127// values. VALUE are the known bits.
128//
129// Set bits in MASK (no meaningful information) must have their
130// corresponding bits in VALUE cleared, as this speeds up union and
131// intersect.
132
134{
135public:
136 irange_bitmask () { /* uninitialized */ }
137 irange_bitmask (unsigned prec) { set_unknown (prec); }
138 irange_bitmask (const wide_int &value, const wide_int &mask);
139 irange_bitmask (tree type, const wide_int &min, const wide_int &max);
140
141 wide_int value () const { return m_value; }
142 wide_int mask () const { return m_mask; }
143 void set_unknown (unsigned prec);
144 bool unknown_p () const;
145 unsigned get_precision () const;
146 void union_ (const irange_bitmask &src);
147 void intersect (const irange_bitmask &src);
148 bool operator== (const irange_bitmask &src) const;
149 bool operator!= (const irange_bitmask &src) const { return !(*this == src); }
150 void verify_mask () const;
151 void dump (FILE *) const;
152
153 bool member_p (const wide_int &val) const;
154
155 // Convenience functions for nonzero bitmask compatibility.
156 wide_int get_nonzero_bits () const;
157 void set_nonzero_bits (const wide_int &bits);
158private:
161};
162
163inline void
165{
166 m_value = wi::zero (prec);
167 m_mask = wi::minus_one (prec);
168 if (flag_checking)
169 verify_mask ();
170}
171
172// Return TRUE if THIS does not have any meaningful information.
173
174inline bool
176{
177 return m_mask == -1;
178}
179
180inline
182{
183 m_value = value;
184 m_mask = mask;
185 if (flag_checking)
186 verify_mask ();
187}
188
189inline unsigned
191{
192 return m_mask.get_precision ();
193}
194
195// The following two functions are meant for backwards compatability
196// with the nonzero bitmask. A cleared bit means the value must be 0.
197// A set bit means we have no information for the bit.
198
199// Return the nonzero bits.
200inline wide_int
202{
203 return m_value | m_mask;
204}
205
206// Set the bitmask to the nonzero bits in BITS.
207inline void
209{
210 m_value = wi::zero (bits.get_precision ());
211 m_mask = bits;
212 if (flag_checking)
213 verify_mask ();
214}
215
216// Return TRUE if val could be a valid value with this bitmask.
217
218inline bool
220{
221 if (unknown_p ())
222 return true;
223 wide_int res = m_mask & val;
224 if (m_value != 0)
225 res |= ~m_mask & m_value;
226 return res == val;
227}
228
229inline bool
231{
232 bool unknown1 = unknown_p ();
233 bool unknown2 = src.unknown_p ();
234 if (unknown1 || unknown2)
235 return unknown1 == unknown2;
236 return m_value == src.m_value && m_mask == src.m_mask;
237}
238
239inline void
241{
242 m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
243 m_value = m_value & src.m_value;
244 if (flag_checking)
245 verify_mask ();
246}
247
248inline void
250{
251 // If we have two known bits that are incompatible, the resulting
252 // bit is undefined. It is unclear whether we should set the entire
253 // range to UNDEFINED, or just a subset of it. For now, set the
254 // entire bitmask to unknown (VARYING).
255 if (wi::bit_and (~(m_mask | src.m_mask),
256 m_value ^ src.m_value) != 0)
257 {
258 unsigned prec = m_mask.get_precision ();
259 m_mask = wi::minus_one (prec);
260 m_value = wi::zero (prec);
261 }
262 else
263 {
264 m_mask = m_mask & src.m_mask;
265 m_value = m_value | src.m_value;
266 }
267 if (flag_checking)
268 verify_mask ();
269}
270
271// An integer range without any storage.
272
273class irange : public vrange
274{
275 friend class irange_storage;
276 friend class vrange_printer;
277public:
278 // In-place setters.
279 void set (tree type, const wide_int &, const wide_int &,
281 virtual void set_nonzero (tree type) override;
282 virtual void set_zero (tree type) override;
283 virtual void set_nonnegative (tree type) override;
284 virtual void set_varying (tree type) override;
285 virtual void set_undefined () override;
286
287 // Range types.
289 virtual bool supports_type_p (const_tree type) const override;
290 virtual tree type () const override;
291
292 // Iteration over sub-ranges.
293 unsigned num_pairs () const;
294 wide_int lower_bound (unsigned = 0) const;
295 wide_int upper_bound (unsigned) const;
297 virtual tree lbound () const override;
298 virtual tree ubound () const override;
299
300 // Predicates.
301 virtual bool zero_p () const override;
302 virtual bool nonzero_p () const override;
303 virtual bool singleton_p (tree *result = NULL) const override;
304 bool singleton_p (wide_int &) const;
305 bool contains_p (const wide_int &) const;
306 bool nonnegative_p () const;
307 bool nonpositive_p () const;
308
309 // In-place operators.
310 virtual bool union_ (const vrange &) override;
311 virtual bool intersect (const vrange &) override;
312 void invert ();
313
314 // Operator overloads.
315 irange& operator= (const irange &);
316 bool operator== (const irange &) const;
317 bool operator!= (const irange &r) const { return !(*this == r); }
318
319 // Misc methods.
320 virtual bool fits_p (const vrange &r) const override;
321 virtual void accept (const vrange_visitor &v) const override;
322
323 virtual void update_bitmask (const class irange_bitmask &) override;
324 virtual irange_bitmask get_bitmask () const override;
325
326protected:
327 void maybe_resize (int needed);
328 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
329 virtual bool contains_p (tree cst) const override;
330 irange (wide_int *, unsigned nranges, bool resizable);
331
332 // In-place operators.
333 bool irange_contains_p (const irange &) const;
334 bool irange_single_pair_union (const irange &r);
335
337
338 void verify_range ();
339
340 // Hard limit on max ranges allowed.
341 static const int HARD_MAX_RANGES = 255;
342private:
343 bool varying_compatible_p () const;
344 bool intersect_bitmask (const irange &r);
345 bool union_bitmask (const irange &r);
347
348 bool intersect (const wide_int& lb, const wide_int& ub);
349 bool union_append (const irange &r);
350 unsigned char m_num_ranges;
352 unsigned char m_max_ranges;
355protected:
357};
358
359// Here we describe an irange with N pairs of ranges. The storage for
360// the pairs is embedded in the class as an array.
361//
362// If RESIZABLE is true, the storage will be resized on the heap when
363// the number of ranges needed goes past N up to a max of
364// HARD_MAX_RANGES. This new storage is freed upon destruction.
365
366template<unsigned N, bool RESIZABLE = false>
367class int_range final : public irange
368{
369public:
371 int_range (tree type, const wide_int &, const wide_int &,
375 int_range (const irange &);
376 ~int_range () final override;
377 int_range& operator= (const int_range &);
378protected:
380private:
382};
383
384class prange final : public vrange
385{
386 friend class prange_storage;
387 friend class vrange_printer;
388public:
389 prange ();
390 prange (const prange &);
391 prange (tree type);
392 prange (tree type, const wide_int &, const wide_int &,
394 static bool supports_p (const_tree type);
395 virtual bool supports_type_p (const_tree type) const final override;
396 virtual void accept (const vrange_visitor &v) const final override;
397 virtual void set_undefined () final override;
398 virtual void set_varying (tree type) final override;
399 virtual void set_nonzero (tree type) final override;
400 virtual void set_zero (tree type) final override;
401 virtual void set_nonnegative (tree type) final override;
402 virtual bool contains_p (tree cst) const final override;
403 virtual bool fits_p (const vrange &v) const final override;
404 virtual bool singleton_p (tree *result = NULL) const final override;
405 virtual bool zero_p () const final override;
406 virtual bool nonzero_p () const final override;
407 virtual void set (tree, tree, value_range_kind = VR_RANGE) final override;
408 virtual tree type () const final override;
409 virtual bool union_ (const vrange &v) final override;
410 virtual bool intersect (const vrange &v) final override;
411 virtual tree lbound () const final override;
412 virtual tree ubound () const final override;
413
414 prange& operator= (const prange &);
415 bool operator== (const prange &) const;
416 void set (tree type, const wide_int &, const wide_int &,
418 void invert ();
419 bool contains_p (const wide_int &) const;
420 wide_int lower_bound () const;
421 wide_int upper_bound () const;
422 void verify_range () const;
423 irange_bitmask get_bitmask () const final override;
424 void update_bitmask (const irange_bitmask &) final override;
425protected:
426 bool varying_compatible_p () const;
427
432};
433
434// Unsupported temporaries may be created by ranger before it's known
435// they're unsupported, or by vr_values::get_value_range.
436
438{
439public:
442 {
443 set_undefined ();
444 }
450 void set (tree min, tree, value_range_kind = VR_RANGE) final override;
451 tree type () const final override;
452 bool supports_type_p (const_tree) const final override;
453 void set_varying (tree) final override;
454 void set_undefined () final override;
455 void accept (const vrange_visitor &v) const final override;
456 bool union_ (const vrange &r) final override;
457 bool intersect (const vrange &r) final override;
458 bool singleton_p (tree * = NULL) const final override;
459 bool contains_p (tree) const final override;
460 bool zero_p () const final override;
461 bool nonzero_p () const final override;
462 void set_nonzero (tree type) final override;
463 void set_zero (tree type) final override;
464 void set_nonnegative (tree type) final override;
465 bool fits_p (const vrange &) const final override;
466 unsupported_range& operator= (const unsupported_range &r);
467 tree lbound () const final override;
468 tree ubound () const final override;
469};
470
471// The NAN state as an opaque object.
472
474{
475public:
476 nan_state (bool);
477 nan_state (bool pos_nan, bool neg_nan);
478 bool neg_p () const;
479 bool pos_p () const;
480private:
483};
484
485// Set NAN state to +-NAN if NAN_P is true. Otherwise set NAN state
486// to false.
487
488inline
490{
491 m_pos_nan = nan_p;
492 m_neg_nan = nan_p;
493}
494
495// Constructor initializing the object to +NAN if POS_NAN is set, -NAN
496// if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
497// NEG_NAN are clear, and the object cannot be a NAN.
498
499inline
500nan_state::nan_state (bool pos_nan, bool neg_nan)
501{
502 m_pos_nan = pos_nan;
503 m_neg_nan = neg_nan;
504}
505
506// Return if +NAN is possible.
507
508inline bool
510{
511 return m_pos_nan;
512}
513
514// Return if -NAN is possible.
515
516inline bool
518{
519 return m_neg_nan;
520}
521
522// A floating point range.
523//
524// The representation is a type with a couple of endpoints, unioned
525// with the set of { -NAN, +Nan }.
526
527class frange final : public vrange
528{
529 friend class frange_storage;
530 friend class vrange_printer;
531public:
532 frange ();
533 frange (const frange &);
535 frange (tree type);
536 frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
539 {
540 // ?? Decimal floats can have multiple representations for the
541 // same number. Supporting them may be as simple as just
542 // disabling them in singleton_p. No clue.
544 }
545 virtual tree type () const override;
546 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
548 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
550 void set_nan (tree type);
551 void set_nan (tree type, bool sign);
552 void set_nan (tree type, const nan_state &);
553 virtual void set_varying (tree type) override;
554 virtual void set_undefined () override;
555 virtual bool union_ (const vrange &) override;
556 virtual bool intersect (const vrange &) override;
557 bool contains_p (const REAL_VALUE_TYPE &) const;
558 virtual bool singleton_p (tree *result = NULL) const override;
559 bool singleton_p (REAL_VALUE_TYPE &r) const;
560 virtual bool supports_type_p (const_tree type) const override;
561 virtual void accept (const vrange_visitor &v) const override;
562 virtual bool zero_p () const override;
563 virtual bool nonzero_p () const override;
564 virtual void set_nonzero (tree type) override;
565 virtual void set_zero (tree type) override;
566 virtual void set_nonnegative (tree type) override;
567 virtual bool fits_p (const vrange &) const override;
568 frange& operator= (const frange &);
569 bool operator== (const frange &) const;
570 bool operator!= (const frange &r) const { return !(*this == r); }
571 const REAL_VALUE_TYPE &lower_bound () const;
572 const REAL_VALUE_TYPE &upper_bound () const;
573 virtual tree lbound () const override;
574 virtual tree ubound () const override;
575 nan_state get_nan_state () const;
576 void update_nan ();
577 void update_nan (bool sign);
578 void update_nan (tree) = delete; // Disallow silent conversion to bool.
579 void update_nan (const nan_state &);
580 void clear_nan ();
582
583 // fpclassify like API
584 bool known_isfinite () const;
585 bool known_isnan () const;
586 bool known_isinf () const;
587 bool maybe_isnan () const;
588 bool maybe_isnan (bool sign) const;
589 bool maybe_isinf () const;
590 bool signbit_p (bool &signbit) const;
591 bool nan_signbit_p (bool &signbit) const;
592 bool known_isnormal () const;
593 bool known_isdenormal_or_zero () const;
594
595protected:
596 virtual bool contains_p (tree cst) const override;
597 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
598
599private:
601 void verify_range ();
602 bool normalize_kind ();
603 bool union_nans (const frange &);
604 bool intersect_nans (const frange &);
605 bool combine_zeros (const frange &, bool union_p);
606
612};
613
614inline const REAL_VALUE_TYPE &
616{
618 return m_min;
619}
620
621inline const REAL_VALUE_TYPE &
623{
625 return m_max;
626}
627
628// Return the NAN state.
629
630inline nan_state
632{
633 return nan_state (m_pos_nan, m_neg_nan);
634}
635
636// is_a<> and as_a<> implementation for vrange.
637
638// Anything we haven't specialized is a hard fail.
639template <typename T>
640inline bool
642{
644 return false;
645}
646
647template <typename T>
648inline bool
649is_a (const vrange &v)
650{
651 // Reuse is_a <vrange> to implement the const version.
652 const T &derived = static_cast<const T &> (v);
653 return is_a <T> (const_cast<T &> (derived));
654}
655
656template <typename T>
657inline T &
659{
661 return static_cast <T &> (v);
662}
663
664template <typename T>
665inline const T &
666as_a (const vrange &v)
667{
669 return static_cast <const T &> (v);
670}
671
672// Specializations for the different range types.
673
674template <>
675inline bool
677{
678 return v.m_discriminator == VR_IRANGE;
679}
680
681template <>
682inline bool
684{
685 return v.m_discriminator == VR_PRANGE;
686}
687
688template <>
689inline bool
691{
692 return v.m_discriminator == VR_FRANGE;
693}
694
695template <>
696inline bool
698{
699 return v.m_discriminator == VR_UNKNOWN;
700}
701
702// For resizable ranges, resize the range up to HARD_MAX_RANGES if the
703// NEEDED pairs is greater than the current capacity of the range.
704
705inline void
707{
709 return;
710
711 if (needed > m_max_ranges)
712 {
714 wide_int *newmem = new wide_int[m_max_ranges * 2];
715 unsigned n = num_pairs () * 2;
716 for (unsigned i = 0; i < n; ++i)
717 newmem[i] = m_base[i];
718 m_base = newmem;
719 }
720}
721
722template<unsigned N, bool RESIZABLE>
723inline
725{
726 if (RESIZABLE && m_base != m_ranges)
727 delete[] m_base;
728}
729
730// This is an "infinite" precision irange for use in temporary
731// calculations. It starts with a sensible default covering 99% of
732// uses, and goes up to HARD_MAX_RANGES when needed. Any allocated
733// storage is freed upon destruction.
734typedef int_range<3, /*RESIZABLE=*/true> int_range_max;
735
737{
738public:
739 virtual void visit (const irange &) const { }
740 virtual void visit (const prange &) const { }
741 virtual void visit (const frange &) const { }
742 virtual void visit (const unsupported_range &) const { }
743};
744
745// This is an "infinite" precision range object for use in temporary
746// calculations for any of the handled types. The object can be
747// transparently used as a vrange.
748//
749// Using any of the various constructors initializes the object
750// appropriately, but the default constructor is uninitialized and
751// must be initialized either with set_type() or by assigning into it.
752//
753// Assigning between incompatible types is allowed. For example if a
754// temporary holds an irange, you can assign an frange into it, and
755// all the right things will happen. However, before passing this
756// object to a function accepting a vrange, the correct type must be
757// set. If it isn't, you can do so with set_type().
758
760{
761public:
762 value_range ();
763 value_range (const vrange &r);
766 value_range (const value_range &);
767 ~value_range ();
768 void set_type (tree type);
769 vrange& operator= (const vrange &);
771 bool operator== (const value_range &r) const;
772 bool operator!= (const value_range &r) const;
773 operator vrange &();
774 operator const vrange &() const;
775 void dump (FILE *) const;
776 static bool supports_type_p (const_tree type);
777
778 tree type () { return m_vrange->type (); }
779 bool varying_p () const { return m_vrange->varying_p (); }
780 bool undefined_p () const { return m_vrange->undefined_p (); }
781 void set_varying (tree type) { init (type); m_vrange->set_varying (type); }
782 void set_undefined () { m_vrange->set_undefined (); }
783 bool union_ (const vrange &r) { return m_vrange->union_ (r); }
784 bool intersect (const vrange &r) { return m_vrange->intersect (r); }
785 bool contains_p (tree cst) const { return m_vrange->contains_p (cst); }
786 bool singleton_p (tree *result = NULL) const
787 { return m_vrange->singleton_p (result); }
788 void set_zero (tree type) { init (type); return m_vrange->set_zero (type); }
790 { init (type); return m_vrange->set_nonzero (type); }
791 bool nonzero_p () const { return m_vrange->nonzero_p (); }
792 bool zero_p () const { return m_vrange->zero_p (); }
793 tree lbound () const { return m_vrange->lbound (); }
794 tree ubound () const { return m_vrange->ubound (); }
795 irange_bitmask get_bitmask () const { return m_vrange->get_bitmask (); }
796 void update_bitmask (const class irange_bitmask &bm)
797 { return m_vrange->update_bitmask (bm); }
798 void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
799private:
800 void init (tree type);
801 void init (const vrange &);
802
812};
813
814// The default constructor is uninitialized and must be initialized
815// with either set_type() or with an assignment into it.
816
817inline
819 : m_buffer ()
820{
821 m_vrange = NULL;
822}
823
824// Copy constructor.
825
826inline
828{
829 init (*r.m_vrange);
830}
831
832// Copy constructor from a vrange.
833
834inline
836{
837 init (r);
838}
839
840// Construct an UNDEFINED range that can hold ranges of TYPE. If TYPE
841// is not supported, default to unsupported_range.
842
843inline
848
849// Construct a range that can hold a range of [MIN, MAX], where MIN
850// and MAX are trees.
851
852inline
854{
855 init (TREE_TYPE (min));
856 m_vrange->set (min, max, kind);
857}
858
859inline
861{
862 if (m_vrange)
863 m_vrange->~vrange ();
864}
865
866// Initialize object to an UNDEFINED range that can hold ranges of
867// TYPE. Clean-up memory if there was a previous object.
868
869inline void
871{
872 if (m_vrange)
873 m_vrange->~vrange ();
874 init (type);
875}
876
877// Initialize object to an UNDEFINED range that can hold ranges of
878// TYPE.
879
880inline void
882{
884
886 m_vrange = new (&m_buffer.ints) int_range_max ();
887 else if (prange::supports_p (type))
888 m_vrange = new (&m_buffer.pointers) prange ();
889 else if (frange::supports_p (type))
890 m_vrange = new (&m_buffer.floats) frange ();
891 else
892 m_vrange = new (&m_buffer.unsupported) unsupported_range ();
893}
894
895// Initialize object with a copy of R.
896
897inline void
899{
900 if (is_a <irange> (r))
902 else if (is_a <prange> (r))
903 m_vrange = new (&m_buffer.pointers) prange (as_a <prange> (r));
904 else if (is_a <frange> (r))
905 m_vrange = new (&m_buffer.floats) frange (as_a <frange> (r));
906 else
907 m_vrange = new (&m_buffer.unsupported)
909}
910
911// Assignment operator. Copying incompatible types is allowed. That
912// is, assigning an frange to an object holding an irange does the
913// right thing.
914
915inline vrange &
917{
918 if (m_vrange)
919 m_vrange->~vrange ();
920 init (r);
921 return *m_vrange;
922}
923
924inline value_range &
926{
927 // No need to call the m_vrange destructor here, as we will do so in
928 // the assignment below.
929 *this = *r.m_vrange;
930 return *this;
931}
932
933inline bool
935{
936 return *m_vrange == *r.m_vrange;
937}
938
939inline bool
941{
942 return *m_vrange != *r.m_vrange;
943}
944
945inline
946value_range::operator vrange &()
947{
948 return *m_vrange;
949}
950
951inline
952value_range::operator const vrange &() const
953{
954 return *m_vrange;
955}
956
957// Return TRUE if TYPE is supported by the vrange infrastructure.
958
959inline bool
966
967extern value_range_kind get_legacy_range (const vrange &, tree &min, tree &max);
968extern void dump_value_range (FILE *, const vrange *);
972
973// Number of sub-ranges in a range.
974
975inline unsigned
977{
978 return m_num_ranges;
979}
980
981inline tree
983{
985 return m_type;
986}
987
988inline bool
990{
991 if (m_num_ranges != 1)
992 return false;
993
994 const wide_int &l = m_base[0];
995 const wide_int &u = m_base[1];
996 tree t = m_type;
997
998 if (m_kind == VR_VARYING)
999 return true;
1000
1001 unsigned prec = TYPE_PRECISION (t);
1002 signop sign = TYPE_SIGN (t);
1003 if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
1004 return (l == wi::min_value (prec, sign)
1005 && u == wi::max_value (prec, sign)
1006 && m_bitmask.unknown_p ());
1007 return true;
1008}
1009
1010inline bool
1012{
1013 return m_kind == VR_VARYING;
1014}
1015
1016inline bool
1018{
1019 return m_kind == VR_UNDEFINED;
1020}
1021
1022inline bool
1024{
1025 return (m_kind == VR_RANGE && m_num_ranges == 1
1026 && lower_bound (0) == 0
1027 && upper_bound (0) == 0);
1028}
1029
1030inline bool
1032{
1033 if (undefined_p ())
1034 return false;
1035
1036 wide_int zero = wi::zero (TYPE_PRECISION (type ()));
1037 return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
1038}
1039
1040inline bool
1045
1046inline bool
1048{
1049 return contains_p (wi::to_wide (cst));
1050}
1051
1052inline bool
1054{
1055 if (vr.undefined_p ())
1056 return false;
1057
1058 if (vr.varying_p ())
1059 return true;
1060
1061 return vr.contains_p (build_zero_cst (vr.type ()));
1062}
1063
1064// Constructors for irange
1065
1066inline
1067irange::irange (wide_int *base, unsigned nranges, bool resizable)
1068 : vrange (VR_IRANGE),
1069 m_resizable (resizable),
1070 m_max_ranges (nranges)
1071{
1072 m_base = base;
1073 set_undefined ();
1074}
1075
1076// Constructors for int_range<>.
1077
1078template<unsigned N, bool RESIZABLE>
1079inline
1081 : irange (m_ranges, N, RESIZABLE)
1082{
1083}
1084
1085template<unsigned N, bool RESIZABLE>
1087 : irange (m_ranges, N, RESIZABLE)
1088{
1089 irange::operator= (other);
1090}
1091
1092template<unsigned N, bool RESIZABLE>
1094 : irange (m_ranges, N, RESIZABLE)
1095{
1096 irange::set (min, max, kind);
1097}
1098
1099template<unsigned N, bool RESIZABLE>
1105
1106template<unsigned N, bool RESIZABLE>
1108 value_range_kind kind)
1109 : irange (m_ranges, N, RESIZABLE)
1110{
1111 set (type, wmin, wmax, kind);
1112}
1113
1114template<unsigned N, bool RESIZABLE>
1116 : irange (m_ranges, N, RESIZABLE)
1117{
1118 irange::operator= (other);
1119}
1120
1121template<unsigned N, bool RESIZABLE>
1124{
1125 irange::operator= (src);
1126 return *this;
1127}
1128
1129inline void
1135
1136inline void
1138{
1140 m_num_ranges = 1;
1141 m_bitmask.set_unknown (TYPE_PRECISION (type));
1142
1144 {
1145 m_type = type;
1146 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
1147 // min_value and max_value.
1150 }
1151 else
1153}
1154
1155// Return the lower bound of a sub-range. PAIR is the sub-range in
1156// question.
1157
1158inline wide_int
1160{
1163 return m_base[pair * 2];
1164}
1165
1166// Return the upper bound of a sub-range. PAIR is the sub-range in
1167// question.
1168
1169inline wide_int
1171{
1174 return m_base[pair * 2 + 1];
1175}
1176
1177// Return the highest bound of a range.
1178
1179inline wide_int
1181{
1182 unsigned pairs = num_pairs ();
1183 gcc_checking_assert (pairs > 0);
1184 return upper_bound (pairs - 1);
1185}
1186
1187// Set value range VR to a nonzero range of type TYPE.
1188
1189inline void
1191{
1192 unsigned prec = TYPE_PRECISION (type);
1193
1194 if (TYPE_UNSIGNED (type))
1195 {
1196 m_type = type;
1197 m_kind = VR_RANGE;
1198 m_base[0] = wi::one (prec);
1199 m_base[1] = wi::minus_one (prec);
1200 m_bitmask.set_unknown (prec);
1201 m_num_ranges = 1;
1202
1203 if (flag_checking)
1204 verify_range ();
1205 }
1206 else
1207 {
1208 wide_int zero = wi::zero (prec);
1209 set (type, zero, zero, VR_ANTI_RANGE);
1210 }
1211}
1212
1213// Set value range VR to a ZERO range of type TYPE.
1214
1215inline void
1217{
1219 set (type, zero, zero);
1220}
1221
1222// Normalize a range to VARYING or UNDEFINED if possible.
1223
1224inline void
1226{
1227 if (m_num_ranges == 0)
1228 set_undefined ();
1229 else if (varying_compatible_p ())
1230 {
1231 if (m_kind == VR_RANGE)
1233 else if (m_kind == VR_ANTI_RANGE)
1234 set_undefined ();
1235 }
1236 if (flag_checking)
1237 verify_range ();
1238}
1239
1240inline bool
1242{
1243 if (r.undefined_p ())
1244 return false;
1245
1246 wide_int zero = wi::zero (TYPE_PRECISION (r.type ()));
1247 return r.contains_p (zero);
1248}
1249
1250inline wide_int
1256
1257inline wide_int
1263
1264inline
1266 : vrange (VR_PRANGE)
1267{
1268 set_undefined ();
1269}
1270
1271inline
1273 : vrange (VR_PRANGE)
1274{
1275 *this = r;
1276}
1277
1278inline
1280 : vrange (VR_PRANGE)
1281{
1282 set_varying (type);
1283}
1284
1285inline
1287 value_range_kind kind)
1288 : vrange (VR_PRANGE)
1289{
1290 set (type, lb, ub, kind);
1291}
1292
1293inline bool
1298
1299inline bool
1301{
1302 return POINTER_TYPE_P (type);
1303}
1304
1305inline void
1310
1311inline void
1313{
1315 m_type = type;
1318 m_bitmask.set_unknown (TYPE_PRECISION (type));
1319
1320 if (flag_checking)
1321 verify_range ();
1322}
1323
1324inline void
1326{
1327 m_kind = VR_RANGE;
1328 m_type = type;
1331 m_bitmask.set_unknown (TYPE_PRECISION (type));
1332
1333 if (flag_checking)
1334 verify_range ();
1335}
1336
1337inline void
1339{
1340 m_kind = VR_RANGE;
1341 m_type = type;
1343 m_min = m_max = zero;
1344 m_bitmask = irange_bitmask (zero, zero);
1345
1346 if (flag_checking)
1347 verify_range ();
1348}
1349
1350inline bool
1352{
1353 return contains_p (wi::to_wide (cst));
1354}
1355
1356inline bool
1358{
1359 return m_kind == VR_RANGE && m_min == 0 && m_max == 0;
1360}
1361
1362inline bool
1364{
1365 return m_kind == VR_RANGE && m_min == 1 && m_max == -1;
1366}
1367
1368inline tree
1370{
1372 return m_type;
1373}
1374
1375inline wide_int
1377{
1379 return m_min;
1380}
1381
1382inline wide_int
1384{
1386 return m_max;
1387}
1388
1389inline bool
1391{
1392 return (!undefined_p ()
1393 && m_min == 0 && m_max == -1 && get_bitmask ().unknown_p ());
1394}
1395
1396inline irange_bitmask
1398{
1399 return m_bitmask;
1400}
1401
1402inline bool
1403prange::fits_p (const vrange &) const
1404{
1405 return true;
1406}
1407
1408
1409inline
1411 : vrange (VR_FRANGE)
1412{
1413 set_undefined ();
1414}
1415
1416inline
1418 : vrange (VR_FRANGE)
1419{
1420 *this = src;
1421}
1422
1423inline
1425 : vrange (VR_FRANGE)
1426{
1427 set_varying (type);
1428}
1429
1430// frange constructor from REAL_VALUE_TYPE endpoints.
1431
1432inline
1434 const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
1435 value_range_kind kind)
1436 : vrange (VR_FRANGE)
1437{
1438 set (type, min, max, kind);
1439}
1440
1441// frange constructor from trees.
1442
1443inline
1445 : vrange (VR_FRANGE)
1446{
1447 set (min, max, kind);
1448}
1449
1450inline tree
1452{
1454 return m_type;
1455}
1456
1457inline void
1459{
1461 m_type = type;
1464 if (HONOR_NANS (m_type))
1465 {
1466 m_pos_nan = true;
1467 m_neg_nan = true;
1468 }
1469 else
1470 {
1471 m_pos_nan = false;
1472 m_neg_nan = false;
1473 }
1474}
1475
1476inline void
1478{
1480 m_type = NULL;
1481 m_pos_nan = false;
1482 m_neg_nan = false;
1483 // m_min and m_min are uninitialized as they are REAL_VALUE_TYPE ??.
1484 if (flag_checking)
1485 verify_range ();
1486}
1487
1488// Set the NAN bits to NAN and adjust the range.
1489
1490inline void
1492{
1494 if (HONOR_NANS (m_type))
1495 {
1496 m_pos_nan = nan.pos_p ();
1497 m_neg_nan = nan.neg_p ();
1498 normalize_kind ();
1499 if (flag_checking)
1500 verify_range ();
1501 }
1502}
1503
1504// Set the NAN bit to +-NAN.
1505
1506inline void
1508{
1510 nan_state nan (true);
1511 update_nan (nan);
1512}
1513
1514// Like above, but set the sign of the NAN.
1515
1516inline void
1518{
1520 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1521 update_nan (nan);
1522}
1523
1524inline bool
1526{
1527 return contains_p (*TREE_REAL_CST_PTR (cst));
1528}
1529
1530// Clear the NAN bit and adjust the range.
1531
1532inline void
1534{
1536 m_pos_nan = false;
1537 m_neg_nan = false;
1538 normalize_kind ();
1539 if (flag_checking)
1540 verify_range ();
1541}
1542
1543// Set R to maximum representable value for TYPE.
1544
1545inline REAL_VALUE_TYPE
1547{
1549 char buf[128];
1551 buf, sizeof (buf), false);
1552 int res = real_from_string (&r, buf);
1553 gcc_checking_assert (!res);
1554 return r;
1555}
1556
1557// Return the minimum representable value for TYPE.
1558
1559inline REAL_VALUE_TYPE
1566
1567// Return the minimum value for TYPE.
1568
1569inline REAL_VALUE_TYPE
1571{
1572 if (HONOR_INFINITIES (type))
1573 return dconstninf;
1574 else
1576}
1577
1578// Return the maximum value for TYPE.
1579
1580inline REAL_VALUE_TYPE
1582{
1583 if (HONOR_INFINITIES (type))
1584 return dconstinf;
1585 else
1587}
1588
1589// Return TRUE if R is the minimum value for TYPE.
1590
1591inline bool
1593{
1595 return real_identical (&min, &r);
1596}
1597
1598// Return TRUE if R is the max value for TYPE.
1599
1600inline bool
1602{
1604 return real_identical (&max, &r);
1605}
1606
1607// Build a NAN with a state of NAN.
1608
1609inline void
1611{
1612 gcc_checking_assert (nan.pos_p () || nan.neg_p ());
1613 if (HONOR_NANS (type))
1614 {
1615 m_kind = VR_NAN;
1616 m_type = type;
1617 m_neg_nan = nan.neg_p ();
1618 m_pos_nan = nan.pos_p ();
1619 if (flag_checking)
1620 verify_range ();
1621 }
1622 else
1623 set_undefined ();
1624}
1625
1626// Build a signless NAN of type TYPE.
1627
1628inline void
1630{
1631 nan_state nan (true);
1632 set_nan (type, nan);
1633}
1634
1635// Build a NAN of type TYPE with SIGN.
1636
1637inline void
1639{
1640 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1641 set_nan (type, nan);
1642}
1643
1644// Return TRUE if range is known to be finite.
1645
1646inline bool
1648{
1649 if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
1650 return false;
1651 return (!maybe_isnan () && !real_isinf (&m_min) && !real_isinf (&m_max));
1652}
1653
1654// Return TRUE if range is known to be normal.
1655
1656inline bool
1658{
1659 if (!known_isfinite ())
1660 return false;
1661
1662 machine_mode mode = TYPE_MODE (type ());
1663 return (!real_isdenormal (&m_min, mode) && !real_isdenormal (&m_max, mode)
1664 && !real_iszero (&m_min) && !real_iszero (&m_max)
1665 && (!real_isneg (&m_min) || real_isneg (&m_max)));
1666}
1667
1668// Return TRUE if range is known to be denormal.
1669
1670inline bool
1672{
1673 if (!known_isfinite ())
1674 return false;
1675
1676 machine_mode mode = TYPE_MODE (type ());
1677 return ((real_isdenormal (&m_min, mode) || real_iszero (&m_min))
1678 && (real_isdenormal (&m_max, mode) || real_iszero (&m_max)));
1679}
1680
1681// Return TRUE if range may be infinite.
1682
1683inline bool
1685{
1686 if (undefined_p () || m_kind == VR_ANTI_RANGE || m_kind == VR_NAN)
1687 return false;
1688 if (varying_p ())
1689 return true;
1690 return real_isinf (&m_min) || real_isinf (&m_max);
1691}
1692
1693// Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
1694
1695inline bool
1697{
1698 return (m_kind == VR_RANGE
1699 && !maybe_isnan ()
1700 && real_identical (&m_min, &m_max)
1701 && real_isinf (&m_min));
1702}
1703
1704// Return TRUE if range is possibly a NAN.
1705
1706inline bool
1708{
1709 if (undefined_p ())
1710 return false;
1711 return m_pos_nan || m_neg_nan;
1712}
1713
1714// Return TRUE if range is possibly a NAN with SIGN.
1715
1716inline bool
1717frange::maybe_isnan (bool sign) const
1718{
1719 if (undefined_p ())
1720 return false;
1721 if (sign)
1722 return m_neg_nan;
1723 return m_pos_nan;
1724}
1725
1726// Return TRUE if range is a +NAN or -NAN.
1727
1728inline bool
1730{
1731 return m_kind == VR_NAN;
1732}
1733
1734// If the signbit for the range is known, set it in SIGNBIT and return
1735// TRUE.
1736
1737inline bool
1738frange::signbit_p (bool &signbit) const
1739{
1740 if (undefined_p ())
1741 return false;
1742
1743 // NAN with unknown sign.
1744 if (m_pos_nan && m_neg_nan)
1745 return false;
1746 // No NAN.
1747 if (!m_pos_nan && !m_neg_nan)
1748 {
1749 if (m_min.sign == m_max.sign)
1750 {
1751 signbit = m_min.sign;
1752 return true;
1753 }
1754 return false;
1755 }
1756 // NAN with known sign.
1757 bool nan_sign = m_neg_nan;
1758 if (known_isnan ()
1759 || (nan_sign == m_min.sign && nan_sign == m_max.sign))
1760 {
1761 signbit = nan_sign;
1762 return true;
1763 }
1764 return false;
1765}
1766
1767// If range has a NAN with a known sign, set it in SIGNBIT and return
1768// TRUE.
1769
1770inline bool
1771frange::nan_signbit_p (bool &signbit) const
1772{
1773 if (undefined_p ())
1774 return false;
1775
1776 if (m_pos_nan == m_neg_nan)
1777 return false;
1778
1779 signbit = m_neg_nan;
1780 return true;
1781}
1782
1783void frange_nextafter (enum machine_mode, REAL_VALUE_TYPE &,
1784 const REAL_VALUE_TYPE &);
1786 const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
1787 const REAL_VALUE_TYPE &);
1788
1789// Return true if TYPE1 and TYPE2 are compatible range types.
1790
1791inline bool
1793{
1794 // types_compatible_p requires conversion in both directions to be useless.
1795 // GIMPLE only requires a cast one way in order to be compatible.
1796 // Ranges really only need the sign and precision to be the same.
1797 return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
1798 && TYPE_SIGN (type1) == TYPE_SIGN (type2));
1799}
1800#endif // GCC_VALUE_RANGE_H
Definition value-range.h:528
tree m_type
Definition value-range.h:607
void update_nan(tree)=delete
void set(tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &, value_range_kind=VR_RANGE)
Definition value-range.cc:827
void update_nan()
Definition value-range.h:1507
void clear_nan()
Definition value-range.h:1533
REAL_VALUE_TYPE m_min
Definition value-range.h:608
bool known_isfinite() const
Definition value-range.h:1647
bool known_isdenormal_or_zero() const
Definition value-range.h:1671
REAL_VALUE_TYPE m_max
Definition value-range.h:609
bool intersect_nans(const frange &)
Definition value-range.cc:992
void verify_range()
Definition value-range.cc:1208
bool maybe_isinf() const
Definition value-range.h:1684
bool internal_singleton_p(REAL_VALUE_TYPE *=NULL) const
Definition value-range.cc:1153
bool m_neg_nan
Definition value-range.h:611
bool known_isnormal() const
Definition value-range.h:1657
bool nan_signbit_p(bool &signbit) const
Definition value-range.h:1771
virtual void set_varying(tree type) override
Definition value-range.h:1458
bool m_pos_nan
Definition value-range.h:610
bool known_isnan() const
Definition value-range.h:1729
void flush_denormals_to_zero()
Definition value-range.cc:728
bool union_nans(const frange &)
Definition value-range.cc:920
virtual void set_undefined() override
Definition value-range.h:1477
bool maybe_isnan() const
Definition value-range.h:1707
bool normalize_kind()
Definition value-range.cc:850
bool known_isinf() const
Definition value-range.h:1696
const REAL_VALUE_TYPE & upper_bound() const
Definition value-range.h:622
void set_nan(tree type)
Definition value-range.h:1629
friend class vrange_printer
Definition value-range.h:530
frange()
Definition value-range.h:1410
const REAL_VALUE_TYPE & lower_bound() const
Definition value-range.h:615
bool combine_zeros(const frange &, bool union_p)
Definition value-range.cc:888
friend class frange_storage
Definition value-range.h:529
bool signbit_p(bool &signbit) const
Definition value-range.h:1738
bool contains_p(const REAL_VALUE_TYPE &) const
Definition value-range.cc:1114
static bool supports_p(const_tree type)
Definition value-range.h:538
virtual tree type() const override
Definition value-range.h:1451
nan_state get_nan_state() const
Definition value-range.h:631
Definition inchash.h:38
Definition value-range.h:368
wide_int m_ranges[N *2]
Definition value-range.h:381
int_range()
Definition value-range.h:1080
int_range(tree type, const wide_int &, const wide_int &, value_range_kind=VR_RANGE)
Definition value-range.h:1107
int_range(tree type)
Definition value-range.h:1100
int_range(const irange &)
Definition value-range.h:1115
int_range(const int_range &)
Definition value-range.h:1086
int_range & operator=(const int_range &)
Definition value-range.h:1123
~int_range() final override
Definition value-range.h:724
Definition value-range.h:134
irange_bitmask(unsigned prec)
Definition value-range.h:137
void dump(FILE *) const
Definition value-range.cc:294
void verify_mask() const
Definition value-range.cc:2506
void set_nonzero_bits(const wide_int &bits)
Definition value-range.h:208
unsigned get_precision() const
Definition value-range.h:190
bool member_p(const wide_int &val) const
Definition value-range.h:219
void set_unknown(unsigned prec)
Definition value-range.h:164
bool unknown_p() const
Definition value-range.h:175
void union_(const irange_bitmask &src)
Definition value-range.h:240
bool operator==(const irange_bitmask &src) const
Definition value-range.h:230
wide_int get_nonzero_bits() const
Definition value-range.h:201
wide_int mask() const
Definition value-range.h:142
bool operator!=(const irange_bitmask &src) const
Definition value-range.h:149
irange_bitmask()
Definition value-range.h:136
wide_int m_mask
Definition value-range.h:160
void intersect(const irange_bitmask &src)
Definition value-range.h:249
wide_int m_value
Definition value-range.h:159
wide_int value() const
Definition value-range.h:141
Definition value-range.h:274
friend class irange_storage
Definition value-range.h:275
void invert()
Definition value-range.cc:2163
bool union_bitmask(const irange &r)
Definition value-range.cc:2465
virtual bool nonzero_p() const override
Definition value-range.h:1031
virtual bool zero_p() const override
Definition value-range.h:1023
bool m_resizable
Definition value-range.h:351
virtual bool supports_type_p(const_tree type) const override
Definition value-range.cc:399
virtual void set_nonzero(tree type) override
Definition value-range.h:1190
unsigned num_pairs() const
Definition value-range.h:976
unsigned char m_max_ranges
Definition value-range.h:352
virtual bool union_(const vrange &) override
Definition value-range.cc:1758
virtual void set_nonnegative(tree type) override
Definition value-range.cc:413
void maybe_resize(int needed)
Definition value-range.h:706
bool union_append(const irange &r)
Definition value-range.cc:1720
virtual void set_varying(tree type) override
Definition value-range.h:1137
virtual tree lbound() const override
Definition value-range.cc:2494
bool intersect_bitmask(const irange &r)
Definition value-range.cc:2433
tree m_type
Definition value-range.h:353
virtual bool contains_p(tree cst) const override
Definition value-range.h:1047
virtual bool intersect(const vrange &) override
Definition value-range.cc:1943
bool nonnegative_p() const
Definition value-range.cc:387
virtual irange_bitmask get_bitmask() const override
Definition value-range.cc:2379
wide_int * m_base
Definition value-range.h:356
static const int HARD_MAX_RANGES
Definition value-range.h:341
bool operator==(const irange &) const
Definition value-range.cc:1560
virtual bool fits_p(const vrange &r) const override
Definition value-range.cc:407
void set(tree type, const wide_int &, const wide_int &, value_range_kind=VR_RANGE)
Definition value-range.cc:1441
unsigned char m_num_ranges
Definition value-range.h:350
virtual void accept(const vrange_visitor &v) const override
Definition value-range.cc:59
bool irange_single_pair_union(const irange &r)
Definition value-range.cc:1653
virtual bool singleton_p(tree *result=NULL) const override
Definition value-range.cc:1597
static bool supports_p(const_tree type)
Definition value-range.h:1041
wide_int upper_bound() const
Definition value-range.h:1180
wide_int lower_bound(unsigned=0) const
Definition value-range.h:1159
irange_bitmask m_bitmask
Definition value-range.h:354
virtual void set_undefined() override
Definition value-range.h:1130
virtual tree ubound() const override
Definition value-range.cc:2500
bool nonpositive_p() const
Definition value-range.cc:393
irange & operator=(const irange &)
Definition value-range.cc:1320
void verify_range()
Definition value-range.cc:1518
friend class vrange_printer
Definition value-range.h:276
virtual void set_zero(tree type) override
Definition value-range.h:1216
virtual void update_bitmask(const class irange_bitmask &) override
Definition value-range.cc:2356
bool contains_p(const wide_int &) const
Definition value-range.cc:1626
bool set_range_from_bitmask()
Definition value-range.cc:2262
bool irange_contains_p(const irange &) const
Definition value-range.cc:1897
bool varying_compatible_p() const
Definition value-range.h:989
virtual tree type() const override
Definition value-range.h:982
void normalize_kind()
Definition value-range.h:1225
wide_int upper_bound(unsigned) const
Definition value-range.h:1170
bool operator!=(const irange &r) const
Definition value-range.h:317
irange(wide_int *, unsigned nranges, bool resizable)
Definition value-range.h:1067
Definition value-range.h:474
bool neg_p() const
Definition value-range.h:517
bool m_neg_nan
Definition value-range.h:482
bool pos_p() const
Definition value-range.h:509
bool m_pos_nan
Definition value-range.h:481
nan_state(bool)
Definition value-range.h:489
Definition value-range.h:385
virtual bool supports_type_p(const_tree type) const final override
Definition value-range.h:1300
wide_int m_min
Definition value-range.h:429
virtual bool intersect(const vrange &v) final override
Definition value-range.cc:558
virtual void set_nonnegative(tree type) final override
Definition value-range.cc:429
void invert()
Definition value-range.cc:636
prange()
Definition value-range.h:1265
virtual tree lbound() const final override
Definition value-range.cc:506
wide_int upper_bound() const
Definition value-range.h:1383
irange_bitmask get_bitmask() const final override
Definition value-range.h:1397
wide_int m_max
Definition value-range.h:430
virtual bool contains_p(tree cst) const final override
Definition value-range.h:1351
tree m_type
Definition value-range.h:428
bool varying_compatible_p() const
Definition value-range.h:1390
virtual void set_varying(tree type) final override
Definition value-range.h:1312
static bool supports_p(const_tree type)
Definition value-range.h:1294
virtual void set_zero(tree type) final override
Definition value-range.h:1338
wide_int lower_bound() const
Definition value-range.h:1376
virtual bool fits_p(const vrange &v) const final override
Definition value-range.h:1403
virtual bool zero_p() const final override
Definition value-range.h:1357
virtual void set_undefined() final override
Definition value-range.h:1306
void verify_range() const
Definition value-range.cc:668
void update_bitmask(const irange_bitmask &) final override
Definition value-range.cc:687
virtual void set_nonzero(tree type) final override
Definition value-range.h:1325
virtual bool nonzero_p() const final override
Definition value-range.h:1363
friend class vrange_printer
Definition value-range.h:387
friend class prange_storage
Definition value-range.h:386
virtual bool singleton_p(tree *result=NULL) const final override
Definition value-range.cc:494
virtual tree ubound() const final override
Definition value-range.cc:512
virtual tree type() const final override
Definition value-range.h:1369
virtual void set(tree, tree, value_range_kind=VR_RANGE) final override
Definition value-range.cc:437
virtual bool union_(const vrange &v) final override
Definition value-range.cc:518
irange_bitmask m_bitmask
Definition value-range.h:431
Definition value-range.h:438
unsupported_range & operator=(const unsupported_range &r)
Definition value-range.cc:223
unsupported_range(const unsupported_range &src)
Definition value-range.h:445
unsupported_range()
Definition value-range.h:440
Definition value-range.h:760
void set_zero(tree type)
Definition value-range.h:788
~value_range()
Definition value-range.h:860
bool undefined_p() const
Definition value-range.h:780
bool contains_p(tree cst) const
Definition value-range.h:785
static bool supports_type_p(const_tree type)
Definition value-range.h:960
void accept(const vrange_visitor &v) const
Definition value-range.h:798
bool nonzero_p() const
Definition value-range.h:791
bool varying_p() const
Definition value-range.h:779
vrange * m_vrange
Definition value-range.h:803
tree type()
Definition value-range.h:778
irange_bitmask get_bitmask() const
Definition value-range.h:795
tree ubound() const
Definition value-range.h:794
value_range()
Definition value-range.h:818
bool intersect(const vrange &r)
Definition value-range.h:784
void update_bitmask(const class irange_bitmask &bm)
Definition value-range.h:796
bool union_(const vrange &r)
Definition value-range.h:783
void set_nonzero(tree type)
Definition value-range.h:789
void set_type(tree type)
Definition value-range.h:870
void set_undefined()
Definition value-range.h:782
bool zero_p() const
Definition value-range.h:792
bool operator!=(const value_range &r) const
Definition value-range.h:940
bool singleton_p(tree *result=NULL) const
Definition value-range.h:786
tree lbound() const
Definition value-range.h:793
void set_varying(tree type)
Definition value-range.h:781
vrange & operator=(const vrange &)
Definition value-range.h:916
union value_range::buffer_type m_buffer
bool operator==(const value_range &r) const
Definition value-range.h:934
void init(tree type)
Definition value-range.h:881
Definition value-range.h:737
virtual void visit(const unsupported_range &) const
Definition value-range.h:742
virtual void visit(const irange &) const
Definition value-range.h:739
virtual void visit(const frange &) const
Definition value-range.h:741
virtual void visit(const prange &) const
Definition value-range.h:740
Definition value-range.h:78
friend class value_range
Definition value-range.h:80
virtual irange_bitmask get_bitmask() const
Definition value-range.cc:101
vrange(enum value_range_discriminator d)
Definition value-range.h:115
enum value_range_kind m_kind
Definition value-range.h:116
virtual bool singleton_p(tree *result=NULL) const =0
bool operator!=(const vrange &r) const
Definition value-range.h:112
virtual bool supports_type_p(const_tree type) const =0
virtual void set_zero(tree type)=0
virtual bool union_(const vrange &)=0
virtual ~vrange()
Definition value-range.h:100
virtual bool nonzero_p() const =0
friend class range_op_handler
Definition value-range.h:82
virtual bool zero_p() const =0
virtual void set(tree, tree, value_range_kind=VR_RANGE)=0
virtual void set_varying(tree type)=0
bool undefined_p() const
Definition value-range.h:1017
enum value_range_discriminator m_discriminator
Definition value-range.h:117
virtual void set_undefined()=0
virtual bool intersect(const vrange &)=0
virtual void set_nonzero(tree type)=0
virtual void update_bitmask(const class irange_bitmask &)
Definition value-range.cc:96
virtual tree ubound() const =0
friend bool is_a(vrange &)
Definition value-range.h:641
void set_nonzero_bits(const wide_int &bits)
Definition value-range.cc:2412
virtual void set_nonnegative(tree type)=0
virtual void accept(const class vrange_visitor &v) const =0
virtual bool contains_p(tree cst) const =0
vrange & operator=(const vrange &)
Definition value-range.cc:250
virtual tree lbound() const =0
virtual tree type() const =0
void dump(FILE *) const
Definition value-range.cc:283
friend void streamer_write_vrange(struct output_block *, const vrange &)
Definition data-streamer-out.cc:408
wide_int get_nonzero_bits() const
Definition value-range.cc:2422
virtual bool fits_p(const vrange &r) const =0
bool varying_p() const
Definition value-range.h:1011
bool operator==(const vrange &) const
Definition value-range.cc:269
unsigned int get_precision() const
Definition wide-int.h:1252
const union tree_node * const_tree
Definition coretypes.h:98
union tree_node * tree
Definition coretypes.h:97
bool operator==(const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
Definition diagnostic-spec.h:131
bool operator!=(const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
Definition diagnostic-spec.h:139
REAL_VALUE_TYPE dconstninf
Definition emit-rtl.cc:114
REAL_VALUE_TYPE dconstinf
Definition emit-rtl.cc:113
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2008
static type_p type(options_p *optsp, bool nested)
Definition gengtype-parse.cc:883
static struct token T
Definition gengtype-parse.cc:45
tree_code
Definition genmatch.cc:1002
#define N
Definition gensupport.cc:202
Definition fold-const.cc:4338
void add_vrange(const vrange &v, inchash::hash &hstate, unsigned int)
Definition value-range.cc:320
wide_int min_value(machine_mode, signop)
Definition rtl.h:2356
hwi_with_prec minus_one(unsigned int)
Definition wide-int.h:2011
hwi_with_prec zero(unsigned int)
Definition wide-int.h:2018
BINARY_FUNCTION bit_and(const T1 &, const T2 &)
wide_int max_value(machine_mode, signop)
Definition rtl.h:2364
tree_to_wide_ref to_wide(const_tree)
Definition tree.h:6473
hwi_with_prec one(unsigned int)
Definition wide-int.h:2025
poly_int< N, C > r
Definition poly-int.h:774
i
Definition poly-int.h:776
static bool maybe_isnan(const frange &op1, const frange &op2)
Definition range-op-float.cc:239
static bool zero_p(const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
Definition range-op-float.cc:2266
int real_from_string(REAL_VALUE_TYPE *r, const char *str)
Definition real.cc:2006
bool HONOR_NANS(machine_mode m)
Definition real.cc:5498
REAL_VALUE_TYPE real_value_negate(const REAL_VALUE_TYPE *op0)
Definition real.cc:1115
bool real_isneg(const REAL_VALUE_TYPE *r)
Definition real.cc:1280
bool real_isinf(const REAL_VALUE_TYPE *r)
Definition real.cc:1242
static bool real_isdenormal(const REAL_VALUE_TYPE *r)
Definition real.cc:120
bool real_identical(const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
Definition real.cc:1312
bool HONOR_INFINITIES(machine_mode m)
Definition real.cc:5539
bool real_iszero(const REAL_VALUE_TYPE *r)
Definition real.cc:1288
void get_max_float(const struct real_format *fmt, char *buf, size_t len, bool norm_max)
Definition real.cc:5436
#define REAL_MODE_FORMAT(MODE)
Definition real.h:183
#define REAL_VALUE_TYPE
Definition real.h:68
signop
Definition signop.h:28
@ UNSIGNED
Definition signop.h:30
Definition lto-streamer.h:709
Definition gengtype.h:218
Definition cse.cc:4127
Definition gengtype.h:252
#define NULL
Definition system.h:50
#define gcc_unreachable()
Definition system.h:841
#define gcc_checking_assert(EXPR)
Definition system.h:821
tree build_zero_cst(tree type)
Definition tree.cc:2722
#define DECIMAL_FLOAT_TYPE_P(TYPE)
Definition tree.h:680
#define TYPE_PRECISION(NODE)
Definition tree.h:2306
#define SCALAR_FLOAT_TYPE_P(TYPE)
Definition tree.h:648
#define TREE_REAL_CST_PTR(NODE)
Definition tree.h:1155
#define TYPE_UNSIGNED(NODE)
Definition tree.h:949
#define TYPE_MODE(NODE)
Definition tree.h:2315
#define TYPE_SIGN(NODE)
Definition tree.h:952
#define POINTER_TYPE_P(TYPE)
Definition tree.h:700
#define TYPE_P(NODE)
Definition tree.h:226
#define TREE_TYPE(NODE)
Definition tree.h:512
#define INTEGRAL_TYPE_P(TYPE)
Definition tree.h:613
#define error_mark_node
Definition tree.h:4477
unsupported_range unsupported
Definition value-range.h:807
buffer_type()
Definition value-range.h:809
prange pointers
Definition value-range.h:808
~buffer_type()
Definition value-range.h:810
frange floats
Definition value-range.h:806
int_range_max ints
Definition value-range.h:805
T & as_a(vrange &v)
Definition value-range.h:658
REAL_VALUE_TYPE frange_val_max(const_tree type)
Definition value-range.h:1581
bool range_includes_zero_p(const vrange &vr)
Definition value-range.h:1053
wide_int irange_val_max(const_tree type)
Definition value-range.h:1258
value_range_kind
Definition value-range.h:29
@ VR_ANTI_RANGE
Definition value-range.h:37
@ VR_RANGE
Definition value-range.h:35
@ VR_LAST
Definition value-range.h:41
@ VR_NAN
Definition value-range.h:39
@ VR_VARYING
Definition value-range.h:33
@ VR_UNDEFINED
Definition value-range.h:31
void dump_value_range(FILE *, const vrange *)
Definition value-range.cc:2513
bool is_a< prange >(vrange &v)
Definition value-range.h:683
bool is_a< unsupported_range >(vrange &v)
Definition value-range.h:697
value_range_discriminator
Definition value-range.h:47
@ VR_UNKNOWN
Definition value-range.h:55
@ VR_IRANGE
Definition value-range.h:49
@ VR_PRANGE
Definition value-range.h:51
@ VR_FRANGE
Definition value-range.h:53
REAL_VALUE_TYPE real_min_representable(const_tree type)
Definition value-range.h:1560
void frange_arithmetic(enum tree_code, tree, REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &)
Definition range-op-float.cc:331
int_range< 3, true > int_range_max
Definition value-range.h:734
value_range_kind get_legacy_range(const vrange &, tree &min, tree &max)
Definition value-range.cc:1423
bool is_a< frange >(vrange &v)
Definition value-range.h:690
void frange_nextafter(enum machine_mode, REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &)
Definition range-op-float.cc:298
REAL_VALUE_TYPE real_max_representable(const_tree type)
Definition value-range.h:1546
wide_int irange_val_min(const_tree type)
Definition value-range.h:1251
bool range_compatible_p(tree type1, tree type2)
Definition value-range.h:1792
bool frange_val_is_min(const REAL_VALUE_TYPE &r, const_tree type)
Definition value-range.h:1592
bool contains_zero_p(const irange &r)
Definition value-range.h:1241
bool frange_val_is_max(const REAL_VALUE_TYPE &r, const_tree type)
Definition value-range.h:1601
bool vrp_operand_equal_p(const_tree, const_tree)
Definition value-range.cc:2534
REAL_VALUE_TYPE frange_val_min(const_tree type)
Definition value-range.h:1570
bool is_a< irange >(vrange &v)
Definition value-range.h:676
generic_wide_int< wide_int_storage > wide_int
Definition wide-int.h:343