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-2026 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 representing subsets of values for various
59// supported types, such as the possible values of a variable.
60//
61// There are subclasses for each of integer, floating point, and pointer
62// types, each with their own strategies for efficiently representing
63// subsets of values.
64//
65// For efficiency, we can't precisely represent any arbitrary subset
66// of values of a type (which could require 2^N bits for a type of size N)
67// Hence operations on the subclasses may introduce imprecision
68// due to over-approximating the possible subsets.
69//
70// To query what types ranger and the entire ecosystem can support,
71// use value_range::supports_type_p(tree type). This is a static
72// method available independently of any vrange object.
73//
74// To query what a given vrange variant can support, use:
75// irange::supports_p ()
76// frange::supports_p ()
77// etc
78//
79// To query what a range object can support, use:
80// void foo (vrange &v, irange &i, frange &f)
81// {
82// if (v.supports_type_p (type)) ...
83// if (i.supports_type_p (type)) ...
84// if (f.supports_type_p (type)) ...
85// }
86
87class vrange
88{
89 template <typename T> friend bool is_a (vrange &);
90 friend class value_range;
91 friend void streamer_write_vrange (struct output_block *, const vrange &);
92 friend class range_op_handler;
93public:
94 virtual void accept (const class vrange_visitor &v) const = 0;
95 virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
96 virtual tree type () const = 0;
97 virtual bool supports_type_p (const_tree type) const = 0;
98 virtual void set_varying (tree type) = 0;
99 virtual void set_undefined () = 0;
100 virtual bool union_ (const vrange &) = 0;
101 virtual bool intersect (const vrange &) = 0;
102 virtual bool singleton_p (tree *result = NULL) const = 0;
103 virtual bool contains_p (tree cst) const = 0;
104 virtual bool zero_p () const = 0;
105 // True if val == 0 may hold for some value in the range; for a float
106 // range that means +0.0 or -0.0.
107 virtual bool contains_zero_p () const = 0;
108 virtual void set_nonzero (tree type) = 0;
109 virtual void set_zero (tree type) = 0;
110 virtual void set_nonnegative (tree type) = 0;
111 virtual bool fits_p (const vrange &r) const = 0;
112 virtual ~vrange () { }
113 virtual tree lbound () const = 0;
114 virtual tree ubound () const = 0;
115 virtual void update_bitmask (const class irange_bitmask &);
116 virtual irange_bitmask get_bitmask () const;
117 wide_int get_nonzero_bits () const;
118 void set_nonzero_bits (const wide_int &bits);
119
120 bool varying_p () const;
121 bool undefined_p () const;
122 vrange& operator= (const vrange &);
123 bool operator== (const vrange &) const;
124 bool operator!= (const vrange &r) const { return !(*this == r); }
125 void dump (FILE *) const;
126 virtual void verify_range () const { }
127protected:
131};
132
133namespace inchash
134{
135 extern void add_vrange (const vrange &, hash &, unsigned flags = 0);
136}
137
138// A pair of values representing the known bits of a value. Zero bits
139// in MASK cover constant values. Set bits in MASK cover unknown
140// values. VALUE are the known bits for the bits where MASK is zero,
141// and must be zero for the unknown bits where MASK is set (needed as an
142// optimization of union and intersect)
143// For example:
144// VALUE: [..., 0, 1, 0]
145// MASK: [..., 1, 0, 0]
146// ^ ^ ^
147// | | known bit: {0}
148// | known bit: {1}
149// unknown bit: {0, 1}
150
152{
153public:
154 irange_bitmask () { /* uninitialized */ }
155 irange_bitmask (unsigned prec) { set_unknown (prec); }
156 irange_bitmask (const wide_int &value, const wide_int &mask);
157 irange_bitmask (tree type, const wide_int &min, const wide_int &max);
158
159 wide_int value () const { return m_value; }
160 wide_int mask () const { return m_mask; }
161 void set_unknown (unsigned prec);
162 bool unknown_p () const;
163 unsigned get_precision () const;
164 void union_ (const irange_bitmask &src);
165 bool intersect (const irange_bitmask &src);
166 bool operator== (const irange_bitmask &src) const;
167 bool operator!= (const irange_bitmask &src) const { return !(*this == src); }
168 void verify_mask () const;
169 void dump (FILE *) const;
170 bool range_from_mask (irange &r, tree type) const;
171
172 bool member_p (const wide_int &val) const;
173
174 // Convenience functions for nonzero bitmask compatibility.
175 wide_int get_nonzero_bits () const;
176 void set_nonzero_bits (const wide_int &bits);
177private:
180};
181
182inline void
184{
185 m_value = wi::zero (prec);
186 m_mask = wi::minus_one (prec);
187 if (flag_checking)
188 verify_mask ();
189}
190
191// Return TRUE if THIS does not have any meaningful information.
192
193inline bool
195{
196 return m_mask == -1;
197}
198
199inline
201{
202 m_value = value;
203 m_mask = mask;
204 if (flag_checking)
205 verify_mask ();
206}
207
208inline unsigned
210{
211 return m_mask.get_precision ();
212}
213
214// The following two functions are meant for backwards compatibility
215// with the nonzero bitmask. A cleared bit means the value must be 0.
216// A set bit means we have no information for the bit.
217
218// Return the nonzero bits.
219inline wide_int
221{
222 return m_value | m_mask;
223}
224
225// Set the bitmask to the nonzero bits in BITS.
226inline void
228{
229 m_value = wi::zero (bits.get_precision ());
230 m_mask = bits;
231 if (flag_checking)
232 verify_mask ();
233}
234
235// Return TRUE if val could be a valid value with this bitmask.
236
237inline bool
239{
240 if (unknown_p ())
241 return true;
242 wide_int res = m_mask & val;
243 if (m_value != 0)
244 res |= ~m_mask & m_value;
245 return res == val;
246}
247
248inline bool
250{
251 bool unknown1 = unknown_p ();
252 bool unknown2 = src.unknown_p ();
253 if (unknown1 || unknown2)
254 return unknown1 == unknown2;
255 return m_value == src.m_value && m_mask == src.m_mask;
256}
257
258inline void
260{
261 m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
262 m_value = m_value & src.m_value;
263 if (flag_checking)
264 verify_mask ();
265}
266
267// Return FALSE if the bitmask intersection is undefined.
268
269inline bool
271{
272 // If we have two known bits that are incompatible, the resulting
273 // bit and therefore entire range is undefined. Return FALSE.
274 if (wi::bit_and (~(m_mask | src.m_mask),
275 m_value ^ src.m_value) != 0)
276 return false;
277 else
278 {
279 m_mask = m_mask & src.m_mask;
280 m_value = m_value | src.m_value;
281 }
282 if (flag_checking)
283 verify_mask ();
284 return true;
285}
286
287// A subset of possible values for an integer type, leaving
288// allocation of storage to subclasses.
289
290class irange : public vrange
291{
292 friend class irange_storage;
293 friend class vrange_printer;
294public:
295 // In-place setters.
296 void set (tree type, const wide_int &, const wide_int &,
298 virtual void set_nonzero (tree type) override;
299 virtual void set_zero (tree type) override;
300 virtual void set_nonnegative (tree type) override;
301 virtual void set_varying (tree type) override;
302 virtual void set_undefined () override;
303
304 // Range types.
306 virtual bool supports_type_p (const_tree type) const override;
307 virtual tree type () const override;
308
309 // Iteration over sub-ranges.
310 unsigned num_pairs () const;
311 wide_int lower_bound (unsigned = 0) const;
312 wide_int upper_bound (unsigned) const;
314 virtual tree lbound () const override;
315 virtual tree ubound () const override;
316
317 // Predicates.
318 virtual bool zero_p () const override;
319 virtual bool contains_zero_p () const override;
320 virtual bool singleton_p (tree *result = NULL) const override;
321 bool singleton_p (wide_int &) const;
322 bool contains_p (const wide_int &) const;
323 bool nonnegative_p () const;
324 bool nonpositive_p () const;
325
326 // In-place operators.
327 virtual bool union_ (const vrange &) override;
328 virtual bool intersect (const vrange &) override;
329 bool invert ();
330
331 // Operator overloads.
332 irange& operator= (const irange &);
333 bool operator== (const irange &) const;
334 bool operator!= (const irange &r) const { return !(*this == r); }
335
336 // Misc methods.
337 virtual bool fits_p (const vrange &r) const override;
338 virtual void accept (const vrange_visitor &v) const override;
339
340 virtual void update_bitmask (const class irange_bitmask &) override;
341 virtual irange_bitmask get_bitmask () const override;
342
343 virtual void verify_range () const override;
344protected:
345 void maybe_resize (int needed);
346 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
347 virtual bool contains_p (tree cst) const override;
348 irange (wide_int *, unsigned nranges, bool resizable);
349
350 // In-place operators.
351 bool irange_contains_p (const irange &) const;
352 bool irange_single_pair_union (const irange &r);
353
355
356
357 // Hard limit on max ranges allowed.
358 static const int HARD_MAX_RANGES = 255;
359private:
360 bool varying_compatible_p () const;
361 bool intersect_bitmask (const irange &r);
362 bool union_bitmask (const irange &r);
364 bool snap_subranges ();
365 bool snap (const wide_int &, const wide_int &, wide_int &, wide_int &,
366 bool &);
367
368 bool intersect (const wide_int& lb, const wide_int& ub);
369 bool union_append (const irange &r);
370 unsigned char m_num_ranges;
372 unsigned char m_max_ranges;
375protected:
377};
378
379// Here we describe an irange with N pairs of ranges. The storage for
380// the pairs is embedded in the class as an array.
381//
382// If RESIZABLE is true, the storage will be resized on the heap when
383// the number of ranges needed goes past N up to a max of
384// HARD_MAX_RANGES. This new storage is freed upon destruction.
385
386template<unsigned N, bool RESIZABLE = false>
387class int_range final : public irange
388{
389public:
391 int_range (tree type, const wide_int &, const wide_int &,
395 int_range (const irange &);
396 ~int_range () final override;
397 int_range& operator= (const int_range &);
398protected:
400private:
402};
403
404class prange final : public vrange
405{
406 friend class prange_storage;
407 friend class vrange_printer;
408public:
409 prange ();
410 prange (const prange &);
411 prange (tree type);
412 prange (tree type, const wide_int &, const wide_int &,
414 static bool supports_p (const_tree type);
415 virtual bool supports_type_p (const_tree type) const final override;
416 virtual void accept (const vrange_visitor &v) const final override;
417 virtual void set_undefined () final override;
418 virtual void set_varying (tree type) final override;
419 virtual void set_nonzero (tree type) final override;
420 virtual void set_zero (tree type) final override;
421 virtual void set_nonnegative (tree type) final override;
422 virtual bool contains_p (tree cst) const final override;
423 virtual bool fits_p (const vrange &v) const final override;
424 virtual bool singleton_p (tree *result = NULL) const final override;
425 virtual bool zero_p () const final override;
426 virtual bool contains_zero_p () const final override;
427 virtual void set (tree, tree, value_range_kind = VR_RANGE) final override;
428 virtual tree type () const final override;
429 virtual bool union_ (const vrange &v) final override;
430 virtual bool intersect (const vrange &v) final override;
431 virtual tree lbound () const final override;
432 virtual tree ubound () const final override;
433
434 prange& operator= (const prange &);
435 bool operator== (const prange &) const;
436 void set (tree type, const wide_int &, const wide_int &,
438 bool invert ();
439 bool contains_p (const wide_int &) const;
440 wide_int lower_bound () const;
441 wide_int upper_bound () const;
442 virtual void verify_range () const final override;
443 irange_bitmask get_bitmask () const final override;
444 void update_bitmask (const irange_bitmask &) final override;
445
446 // prange interface to points to information.
447 // It can point_to or point_away from an object. This represents both
448 // sides of a conditional. ie:
449 // if (p == &foo)
450 // // p points to foo.
451 // else
452 // // p points away from foo.
453 // pt_invariant () and pt_invariant_away () - Return pt if this is invariant.
454 void set_pt (const prange &r);
455 void set_pt (tree ptr, bool points_to_p = true);
456
457 // unknown_p () is true if no object is pointed to.
458 void set_pt_unknown ();
459 bool pt_unknown_p () const;
460
461 // Invariant points-to are is_gimple_min_invariant_p ().
462 // Return expression or NULL_TREE for points-to or away
463 tree pt_invariant () const;
464 tree pt_invariant_away () const;
465
466 // Return true if THIS and R both point to the same object.
467 bool pt_invariant_p (const prange &r) const;
468 // Return true if THIS and R both point away from the same object.
469 bool pt_invariant_away_p (const prange &r) const;
470 // Return true if THIS and R refer to the same object, and one is inverted
471 // from the other, Ie, both to and away.
472 bool pt_inverted_p (const prange &r) const;
473
474 // Invert THIS if it points either to or away from an object.
475 bool pt_invert ();
476
477 // pt_base () - object/allocation the pointer refers into.
478 tree pt_base () const;
479 // pt_offset () - possible byte offset range from BASE.
480 void pt_offset (irange &) const;
481 // pt_size () - possible size range of the referenced object.
482 void pt_size (irange &) const;
483
484protected:
485 bool varying_compatible_p () const;
486
491
492 // A prange can point to an object, or NOT point to an object.
493 tree m_pt; // object points-to refers to.
494 bool m_points_to_p; // Does it point to it (TRUE), or not (FALSE).
495 // If P has the same points to fields as THIS.
496 bool pt_equal_p (const class prange &p) const;
497};
498
499// Unsupported temporaries may be created by ranger before it's known
500// they're unsupported, or by vr_values::get_value_range.
501
503{
504public:
507 {
508 set_undefined ();
509 }
515 void set (tree min, tree, value_range_kind = VR_RANGE) final override;
516 tree type () const final override;
517 bool supports_type_p (const_tree) const final override;
518 void set_varying (tree) final override;
519 void set_undefined () final override;
520 void accept (const vrange_visitor &v) const final override;
521 bool union_ (const vrange &r) final override;
522 bool intersect (const vrange &r) final override;
523 bool singleton_p (tree * = NULL) const final override;
524 bool contains_p (tree) const final override;
525 bool zero_p () const final override;
526 bool contains_zero_p () const final override;
527 void set_nonzero (tree type) final override;
528 void set_zero (tree type) final override;
529 void set_nonnegative (tree type) final override;
530 bool fits_p (const vrange &) const final override;
531 unsupported_range& operator= (const unsupported_range &r);
532 tree lbound () const final override;
533 tree ubound () const final override;
534};
535
536// The possible NAN state of a floating point value as an opaque object.
537// This represents one of the four subsets of { -NaN, +NaN },
538// i.e. one of {}, { -NaN }, { +NaN}, or { -NaN, +NaN }.
539
541{
542public:
543 nan_state (bool);
544 nan_state (bool pos_nan, bool neg_nan);
545 bool neg_p () const;
546 bool pos_p () const;
547private:
550};
551
552// Set NAN state to +-NAN if NAN_P is true. Otherwise set NAN state
553// to false.
554
555inline
557{
558 m_pos_nan = nan_p;
559 m_neg_nan = nan_p;
560}
561
562// Constructor initializing the object to +NAN if POS_NAN is set, -NAN
563// if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
564// NEG_NAN are clear, and the object cannot be a NAN.
565
566inline
567nan_state::nan_state (bool pos_nan, bool neg_nan)
568{
569 m_pos_nan = pos_nan;
570 m_neg_nan = neg_nan;
571}
572
573// Return if +NAN is possible.
574
575inline bool
577{
578 return m_pos_nan;
579}
580
581// Return if -NAN is possible.
582
583inline bool
585{
586 return m_neg_nan;
587}
588
589// A sub-range in an frange.
590
596
597// A subset of possible values for a floating point type.
598//
599// The representation is a handful of disjoint intervals, unioned with a
600// subset of { -NaN, +NaN }.
601
602class frange final : public vrange
603{
604 friend class frange_storage;
605 friend class vrange_printer;
606public:
607 frange ();
608 frange (const frange &);
610 frange (tree type);
611 frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
614 {
615 // ?? Decimal floats can have multiple representations for the
616 // same number. Supporting them may be as simple as just
617 // disabling them in singleton_p. No clue.
619 }
620 virtual tree type () const override;
621 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
623 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
625 void set_nan (tree type);
626 void set_nan (tree type, bool sign);
627 void set_nan (tree type, const nan_state &);
628 virtual void set_varying (tree type) override;
629 virtual void set_undefined () override;
630 virtual bool union_ (const vrange &) override;
631 virtual bool intersect (const vrange &) override;
632 bool contains_p (const REAL_VALUE_TYPE &) const;
633 virtual bool singleton_p (tree *result = NULL) const override;
634 bool singleton_p (REAL_VALUE_TYPE &r) const;
635 virtual bool supports_type_p (const_tree type) const override;
636 virtual void accept (const vrange_visitor &v) const override;
637 virtual bool zero_p () const override;
638 virtual bool contains_zero_p () const override;
639 virtual void set_nonzero (tree type) override;
640 virtual void set_zero (tree type) override;
641 virtual void set_nonnegative (tree type) override;
642 virtual bool fits_p (const vrange &) const override;
643 frange& operator= (const frange &);
644 bool operator== (const frange &) const;
645 bool operator!= (const frange &r) const { return !(*this == r); }
646 const REAL_VALUE_TYPE &lower_bound () const;
647 const REAL_VALUE_TYPE &upper_bound () const;
648 virtual tree lbound () const override;
649 virtual tree ubound () const override;
650 nan_state get_nan_state () const;
651 void update_nan ();
652 void update_nan (bool sign);
653 void update_nan (tree) = delete; // Disallow silent conversion to bool.
654 void update_nan (const nan_state &);
655 void clear_nan ();
657
658 // fpclassify like API
659 bool known_isfinite () const;
660 bool known_isnan () const;
661 bool known_isinf () const;
662 bool maybe_isnan () const;
663 bool maybe_isnan (bool sign) const;
664 bool maybe_isinf () const;
665 bool signbit_p (bool &signbit) const;
666 bool nan_signbit_p (bool &signbit) const;
667 bool known_isnormal () const;
668 bool known_isdenormal_or_zero () const;
669 virtual void verify_range () const override;
670
671 static const unsigned int MAX_PAIRS = 2;
672 unsigned num_pairs () const { return m_num_ranges; }
673 const REAL_VALUE_TYPE &lower_bound (unsigned pair) const;
674 const REAL_VALUE_TYPE &upper_bound (unsigned pair) const;
675
676 void widen (tree);
677protected:
678 virtual bool contains_p (tree cst) const override;
679 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
680
681private:
682 bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const;
683 bool normalize_kind ();
684 bool union_nans (const frange &);
685 bool intersect_nans (const frange &);
686 void set_pairs (frange_pair *, unsigned);
687 void canonicalize_zeros (frange_pair &);
688 void set_excluding (tree type, const REAL_VALUE_TYPE &,
689 const REAL_VALUE_TYPE &, const nan_state &);
690
693 unsigned char m_num_ranges;
696};
697
698inline const REAL_VALUE_TYPE &
700{
702 return m_pairs[0].min;
703}
704
705inline const REAL_VALUE_TYPE &
707{
709 return m_pairs[m_num_ranges - 1].max;
710}
711
712inline const REAL_VALUE_TYPE &
713frange::lower_bound (unsigned pair) const
714{
717 return m_pairs[pair].min;
718}
719
720inline const REAL_VALUE_TYPE &
721frange::upper_bound (unsigned pair) const
722{
725 return m_pairs[pair].max;
726}
727
728// Return the NAN state.
729
730inline nan_state
732{
733 return nan_state (m_pos_nan, m_neg_nan);
734}
735
736// is_a<> and as_a<> implementation for vrange.
737
738// Anything we haven't specialized is a hard fail.
739template <typename T>
740inline bool
742{
744 return false;
745}
746
747template <typename T>
748inline bool
749is_a (const vrange &v)
750{
751 // Reuse is_a <vrange> to implement the const version.
752 const T &derived = static_cast<const T &> (v);
753 return is_a <T> (const_cast<T &> (derived));
754}
755
756template <typename T>
757inline T &
759{
761 return static_cast <T &> (v);
762}
763
764template <typename T>
765inline const T &
766as_a (const vrange &v)
767{
769 return static_cast <const T &> (v);
770}
771
772// Specializations for the different range types.
773
774template <>
775inline bool
777{
778 return v.m_discriminator == VR_IRANGE;
779}
780
781template <>
782inline bool
784{
785 return v.m_discriminator == VR_PRANGE;
786}
787
788template <>
789inline bool
791{
792 return v.m_discriminator == VR_FRANGE;
793}
794
795template <>
796inline bool
798{
799 return v.m_discriminator == VR_UNKNOWN;
800}
801
802// For resizable ranges, resize the range up to HARD_MAX_RANGES if the
803// NEEDED pairs is greater than the current capacity of the range.
804
805inline void
807{
809 return;
810
811 if (needed > m_max_ranges)
812 {
814 wide_int *newmem = new wide_int[m_max_ranges * 2];
815 unsigned n = num_pairs () * 2;
816 for (unsigned i = 0; i < n; ++i)
817 newmem[i] = m_base[i];
818 m_base = newmem;
819 }
820}
821
822template<unsigned N, bool RESIZABLE>
823inline
825{
826 if (RESIZABLE && m_base != m_ranges)
827 delete[] m_base;
828}
829
830// This is an "infinite" precision irange for use in temporary
831// calculations. It starts with a sensible default covering 99% of
832// uses, and goes up to HARD_MAX_RANGES when needed. Any allocated
833// storage is freed upon destruction.
834typedef int_range<3, /*RESIZABLE=*/true> int_range_max;
835
837{
838public:
839 virtual void visit (const irange &) const { }
840 virtual void visit (const prange &) const { }
841 virtual void visit (const frange &) const { }
842 virtual void visit (const unsupported_range &) const { }
843};
844
845// This is an "infinite" precision range object for use in temporary
846// calculations for any of the handled types. The object can be
847// transparently used as a vrange.
848//
849// Using any of the various constructors initializes the object
850// appropriately, but the default constructor is uninitialized and
851// must be initialized either with set_range_class() or by assigning into it.
852//
853// Assigning between incompatible types is allowed. For example if a
854// temporary holds an irange, you can assign an frange into it, and
855// all the right things will happen. However, before passing this
856// object to a function accepting a vrange, the correct type must be
857// set. If it isn't, you can do so with set_range_class().
858
860{
861public:
862 value_range ();
863 value_range (const vrange &r);
866 value_range (const value_range &);
867 ~value_range ();
869 vrange& operator= (const vrange &);
871 bool operator== (const value_range &r) const;
872 bool operator!= (const value_range &r) const;
873 operator vrange &();
874 operator const vrange &() const;
875 void dump (FILE *) const;
876 void print (pretty_printer *) const;
877 static bool supports_type_p (const_tree type);
878
879 tree type () { return m_vrange->type (); }
880 bool varying_p () const { return m_vrange->varying_p (); }
881 bool undefined_p () const { return m_vrange->undefined_p (); }
882 void set_varying (tree type) { init (type); m_vrange->set_varying (type); }
883 void set_undefined () { m_vrange->set_undefined (); }
884 bool union_ (const vrange &r) { return m_vrange->union_ (r); }
885 bool intersect (const vrange &r) { return m_vrange->intersect (r); }
886 bool contains_p (tree cst) const { return m_vrange->contains_p (cst); }
887 bool singleton_p (tree *result = NULL) const
888 { return m_vrange->singleton_p (result); }
889 void set_zero (tree type) { init (type); return m_vrange->set_zero (type); }
891 { init (type); return m_vrange->set_nonzero (type); }
892 bool contains_zero_p () const { return m_vrange->contains_zero_p (); }
893 bool zero_p () const { return m_vrange->zero_p (); }
894 tree lbound () const { return m_vrange->lbound (); }
895 tree ubound () const { return m_vrange->ubound (); }
896 irange_bitmask get_bitmask () const { return m_vrange->get_bitmask (); }
897 void update_bitmask (const class irange_bitmask &bm)
898 { return m_vrange->update_bitmask (bm); }
899 void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
900 void verify_range () const { m_vrange->verify_range (); }
901private:
902 void init (tree type);
903 void init (const vrange &);
904
914};
915
916// The default constructor is uninitialized and must be initialized
917// with either set_range_class() or with an assignment into it.
918
919inline
921 : m_buffer ()
922{
923 m_vrange = NULL;
924}
925
926// Copy constructor.
927
928inline
930{
931 init (*r.m_vrange);
932}
933
934// Copy constructor from a vrange.
935
936inline
938{
939 init (r);
940}
941
942// Construct an UNDEFINED range that can hold ranges of TYPE. If TYPE
943// is not supported, default to unsupported_range.
944
945inline
950
951// Construct a range that can hold a range of [MIN, MAX], where MIN
952// and MAX are trees.
953
954inline
956{
957 init (TREE_TYPE (min));
958 m_vrange->set (min, max, kind);
959}
960
961inline
963{
964 if (m_vrange)
965 m_vrange->~vrange ();
966}
967
968// Initialize object to an UNDEFINED range that can hold ranges of
969// TYPE. Clean-up memory if there was a previous object.
970// Note that this does *not* set the type of the underlying vrange.
971
972inline void
974{
975 if (m_vrange)
976 m_vrange->~vrange ();
977 init (type);
978}
979
980// Initialize object to an UNDEFINED range that can hold ranges of
981// TYPE.
982// Note that this does *not* set the type of the underlying vrange.
983
984inline void
986{
988
990 m_vrange = new (&m_buffer.ints) int_range_max ();
991 else if (prange::supports_p (type))
992 m_vrange = new (&m_buffer.pointers) prange ();
993 else if (frange::supports_p (type))
994 m_vrange = new (&m_buffer.floats) frange ();
995 else
996 m_vrange = new (&m_buffer.unsupported) unsupported_range ();
997}
998
999// Initialize object with a copy of R.
1000
1001inline void
1003{
1004 if (is_a <irange> (r))
1005 m_vrange = new (&m_buffer.ints) int_range_max (as_a <irange> (r));
1006 else if (is_a <prange> (r))
1007 m_vrange = new (&m_buffer.pointers) prange (as_a <prange> (r));
1008 else if (is_a <frange> (r))
1009 m_vrange = new (&m_buffer.floats) frange (as_a <frange> (r));
1010 else
1011 m_vrange = new (&m_buffer.unsupported)
1013}
1014
1015// Assignment operator. Copying incompatible types is allowed. That
1016// is, assigning an frange to an object holding an irange does the
1017// right thing.
1018
1019inline vrange &
1021{
1022 if (m_vrange)
1023 m_vrange->~vrange ();
1024 init (r);
1025 return *m_vrange;
1026}
1027
1028inline value_range &
1030{
1031 // No need to call the m_vrange destructor here, as we will do so in
1032 // the assignment below.
1033 *this = *r.m_vrange;
1034 return *this;
1035}
1036
1037inline bool
1039{
1040 return *m_vrange == *r.m_vrange;
1041}
1042
1043inline bool
1045{
1046 return *m_vrange != *r.m_vrange;
1047}
1048
1049inline
1050value_range::operator vrange &()
1051{
1052 return *m_vrange;
1053}
1054
1055inline
1056value_range::operator const vrange &() const
1057{
1058 return *m_vrange;
1059}
1060
1061// Return TRUE if TYPE is supported by the vrange infrastructure.
1062
1063inline bool
1070
1071extern value_range_kind get_legacy_range (const vrange &, tree &min, tree &max);
1072extern void dump_value_range (FILE *, const vrange *);
1076
1077// Number of sub-ranges in a range.
1078
1079inline unsigned
1081{
1082 return m_num_ranges;
1083}
1084
1085inline tree
1087{
1089 return m_type;
1090}
1091
1092inline bool
1094{
1095 if (m_num_ranges != 1)
1096 return false;
1097
1098 const wide_int &l = m_base[0];
1099 const wide_int &u = m_base[1];
1100 tree t = m_type;
1101
1102 if (m_kind == VR_VARYING)
1103 return true;
1104
1105 unsigned prec = TYPE_PRECISION (t);
1106 signop sign = TYPE_SIGN (t);
1107 if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
1108 return (l == wi::min_value (prec, sign)
1109 && u == wi::max_value (prec, sign)
1110 && m_bitmask.unknown_p ());
1111 return true;
1112}
1113
1114inline bool
1116{
1117 return m_kind == VR_VARYING;
1118}
1119
1120inline bool
1122{
1123 return m_kind == VR_UNDEFINED;
1124}
1125
1126inline bool
1128{
1129 return (m_kind == VR_RANGE && m_num_ranges == 1
1130 && lower_bound (0) == 0
1131 && upper_bound (0) == 0);
1132}
1133
1134inline bool
1136{
1137 if (undefined_p ())
1138 return false;
1139
1140 wide_int zero = wi::zero (TYPE_PRECISION (type ()));
1141 return contains_p (zero);
1142}
1143
1144inline bool
1149
1150inline bool
1152{
1153 return contains_p (wi::to_wide (cst));
1154}
1155
1156inline bool
1158{
1159 if (vr.undefined_p ())
1160 return false;
1161
1162 if (vr.varying_p ())
1163 return true;
1164
1165 return vr.contains_p (build_zero_cst (vr.type ()));
1166}
1167
1168// Constructors for irange
1169
1170inline
1171irange::irange (wide_int *base, unsigned nranges, bool resizable)
1172 : vrange (VR_IRANGE),
1173 m_resizable (resizable),
1174 m_max_ranges (nranges)
1175{
1176 m_base = base;
1177 set_undefined ();
1178}
1179
1180// Constructors for int_range<>.
1181
1182template<unsigned N, bool RESIZABLE>
1183inline
1185 : irange (m_ranges, N, RESIZABLE)
1186{
1187}
1188
1189template<unsigned N, bool RESIZABLE>
1191 : irange (m_ranges, N, RESIZABLE)
1192{
1193 irange::operator= (other);
1194}
1195
1196template<unsigned N, bool RESIZABLE>
1198 : irange (m_ranges, N, RESIZABLE)
1199{
1200 irange::set (min, max, kind);
1201}
1202
1203template<unsigned N, bool RESIZABLE>
1209
1210template<unsigned N, bool RESIZABLE>
1212 value_range_kind kind)
1213 : irange (m_ranges, N, RESIZABLE)
1214{
1215 set (type, wmin, wmax, kind);
1216}
1217
1218template<unsigned N, bool RESIZABLE>
1220 : irange (m_ranges, N, RESIZABLE)
1221{
1222 irange::operator= (other);
1223}
1224
1225template<unsigned N, bool RESIZABLE>
1228{
1229 irange::operator= (src);
1230 return *this;
1231}
1232
1233inline void
1239
1240inline void
1242{
1244 m_num_ranges = 1;
1245 m_bitmask.set_unknown (TYPE_PRECISION (type));
1246
1248 {
1249 m_type = type;
1250 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
1251 // min_value and max_value.
1254 }
1255 else
1257}
1258
1259// Return the lower bound of a sub-range. PAIR is the sub-range in
1260// question.
1261
1262inline wide_int
1264{
1267 return m_base[pair * 2];
1268}
1269
1270// Return the upper bound of a sub-range. PAIR is the sub-range in
1271// question.
1272
1273inline wide_int
1275{
1278 return m_base[pair * 2 + 1];
1279}
1280
1281// Return the highest bound of a range.
1282
1283inline wide_int
1285{
1286 unsigned pairs = num_pairs ();
1287 gcc_checking_assert (pairs > 0);
1288 return upper_bound (pairs - 1);
1289}
1290
1291// Set value range VR to a nonzero range of type TYPE.
1292
1293inline void
1295{
1296 unsigned prec = TYPE_PRECISION (type);
1297
1298 if (TYPE_UNSIGNED (type))
1299 {
1300 m_type = type;
1301 m_kind = VR_RANGE;
1302 m_base[0] = wi::one (prec);
1303 m_base[1] = wi::minus_one (prec);
1304 m_bitmask.set_unknown (prec);
1305 m_num_ranges = 1;
1306
1307 if (flag_checking)
1308 verify_range ();
1309 }
1310 else
1311 {
1312 wide_int zero = wi::zero (prec);
1313 set (type, zero, zero, VR_ANTI_RANGE);
1314 }
1315}
1316
1317// Set value range VR to a ZERO range of type TYPE.
1318
1319inline void
1321{
1323 set (type, zero, zero);
1324}
1325
1326// Normalize a range to VARYING or UNDEFINED if possible.
1327
1328inline void
1330{
1331 if (m_num_ranges == 0)
1332 set_undefined ();
1333 else if (varying_compatible_p ())
1334 {
1335 if (m_kind == VR_RANGE)
1337 else if (m_kind == VR_ANTI_RANGE)
1338 set_undefined ();
1339 }
1340 if (flag_checking)
1341 verify_range ();
1342}
1343
1344inline wide_int
1350
1351inline wide_int
1357
1358inline
1360 : vrange (VR_PRANGE)
1361{
1362 set_undefined ();
1363}
1364
1365inline
1367 : vrange (VR_PRANGE)
1368{
1369 *this = r;
1370}
1371
1372inline
1374 : vrange (VR_PRANGE)
1375{
1376 set_varying (type);
1377}
1378
1379inline
1381 value_range_kind kind)
1382 : vrange (VR_PRANGE)
1383{
1384 set (type, lb, ub, kind);
1385}
1386
1387inline bool
1392
1393inline bool
1395{
1396 return POINTER_TYPE_P (type);
1397}
1398
1399inline void
1405
1406inline void
1408{
1410 m_type = type;
1413 m_bitmask.set_unknown (TYPE_PRECISION (type));
1414 set_pt_unknown ();
1415
1416 if (flag_checking)
1417 verify_range ();
1418}
1419
1420inline void
1422{
1423 m_kind = VR_RANGE;
1424 m_type = type;
1427 m_bitmask.set_unknown (TYPE_PRECISION (type));
1428 set_pt_unknown ();
1429
1430 if (flag_checking)
1431 verify_range ();
1432}
1433
1434inline void
1436{
1437 m_kind = VR_RANGE;
1438 m_type = type;
1440 m_min = m_max = zero;
1441 m_bitmask = irange_bitmask (zero, zero);
1442 set_pt_unknown ();
1443
1444 if (flag_checking)
1445 verify_range ();
1446}
1447
1448inline bool
1450{
1451 return contains_p (wi::to_wide (cst));
1452}
1453
1454inline bool
1456{
1457 bool ret = m_kind == VR_RANGE && m_min == 0 && m_max == 0;
1458 return ret;
1459}
1460
1461inline bool
1463{
1464 if (undefined_p ())
1465 return false;
1466
1467 wide_int zero = wi::zero (TYPE_PRECISION (type ()));
1468 return contains_p (zero);
1469}
1470
1471inline tree
1473{
1475 return m_type;
1476}
1477
1478inline wide_int
1480{
1482 return m_min;
1483}
1484
1485inline wide_int
1487{
1489 return m_max;
1490}
1491
1492inline bool
1494{
1495 return (!undefined_p () && m_min == 0 && m_max == -1
1496 && get_bitmask ().unknown_p () && pt_unknown_p ());
1497}
1498
1499inline irange_bitmask
1501{
1502 return m_bitmask;
1503}
1504
1505inline bool
1506prange::fits_p (const vrange &) const
1507{
1508 return true;
1509}
1510
1511// Set this range's point-to object to PTR, and POINTS_TO_P is TRUE if it
1512// does point to it, and FALSE if it does not point to it.
1513
1514inline void
1516{
1517 // Do not set points-to info if this is zero or undefined.
1518 if (!r.pt_unknown_p () && (undefined_p () || zero_p()))
1519 return;
1520
1521 m_pt = r.m_pt;
1522 m_points_to_p = r.m_points_to_p;
1523
1524 if (r.undefined_p ())
1525 return;
1526 // Check whether this is now VARYING or not.
1527 if (varying_compatible_p ())
1528 set_varying (type ());
1529 else
1530 m_kind = VR_RANGE;
1531}
1532
1533// prange_pt methods.
1534// ------------------------------------------------------------------
1535
1536inline void
1538{
1539 m_pt = NULL_TREE;
1540 m_points_to_p = false;
1541}
1542
1543inline bool
1545{
1546 return (m_pt == NULL_TREE);
1547}
1548
1549inline bool
1551{
1552 // A prange object invokes vrp_operand_equal_p as we want ranges to compare
1553 // equal to each other if they refer to the same object, even if the
1554 // tree has become unshared.
1555 return (m_points_to_p == p.m_points_to_p
1556 && vrp_operand_equal_p (m_pt, p.m_pt));
1557}
1558
1559inline bool
1561{
1562 return m_pt && vrp_operand_equal_p (m_pt, r.m_pt)
1563 && m_points_to_p != r.m_points_to_p;
1564}
1565
1566inline bool
1568{
1569 if (m_pt)
1570 {
1572 return true;
1573 }
1574 return false;
1575}
1576
1577inline tree
1579{
1580 if (m_pt && m_points_to_p)
1581 return m_pt;
1582 return NULL_TREE;
1583}
1584
1585inline tree
1587{
1588 if (m_pt && !m_points_to_p)
1589 return m_pt;
1590 return NULL_TREE;
1591}
1592
1593inline bool
1595{
1596 if (m_pt && m_points_to_p && vrp_operand_equal_p (r.m_pt, m_pt)
1597 && m_points_to_p == r.m_points_to_p)
1598 return true;
1599 return false;
1600}
1601
1602inline bool
1604{
1605 if (m_pt && !m_points_to_p && vrp_operand_equal_p (r.m_pt, m_pt)
1606 && m_points_to_p == r.m_points_to_p)
1607 return true;
1608 return false;
1609}
1610
1611
1612// -----------------------------------------------------------------------
1613
1614inline
1616 : vrange (VR_FRANGE)
1617{
1618 set_undefined ();
1619}
1620
1621inline
1623 : vrange (VR_FRANGE)
1624{
1625 *this = src;
1626}
1627
1628inline
1630 : vrange (VR_FRANGE)
1631{
1632 set_varying (type);
1633}
1634
1635// frange constructor from REAL_VALUE_TYPE endpoints.
1636
1637inline
1639 const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
1640 value_range_kind kind)
1641 : vrange (VR_FRANGE)
1642{
1643 set (type, min, max, kind);
1644}
1645
1646// frange constructor from trees.
1647
1648inline
1650 : vrange (VR_FRANGE)
1651{
1652 set (min, max, kind);
1653}
1654
1655inline tree
1657{
1659 return m_type;
1660}
1661
1662inline void
1664{
1666 m_type = type;
1667 m_num_ranges = 1;
1668 m_pairs[0].min = frange_val_min (type);
1669 m_pairs[0].max = frange_val_max (type);
1670 if (HONOR_NANS (m_type))
1671 {
1672 m_pos_nan = true;
1673 m_neg_nan = true;
1674 }
1675 else
1676 {
1677 m_pos_nan = false;
1678 m_neg_nan = false;
1679 }
1680}
1681
1682inline void
1684{
1686 m_type = NULL;
1687 m_num_ranges = 1;
1688 m_pos_nan = false;
1689 m_neg_nan = false;
1690 // Leave the rest undefined; as it speeds up initializing undefined ranges.
1691 if (flag_checking)
1692 verify_range ();
1693}
1694
1695// Set the NAN bits to NAN and adjust the range.
1696
1697inline void
1699{
1701 if (HONOR_NANS (m_type))
1702 {
1703 m_pos_nan = nan.pos_p ();
1704 m_neg_nan = nan.neg_p ();
1705 normalize_kind ();
1706 if (flag_checking)
1707 verify_range ();
1708 }
1709}
1710
1711// Set the NAN bit to +-NAN.
1712
1713inline void
1715{
1717 nan_state nan (true);
1718 update_nan (nan);
1719}
1720
1721// Like above, but set the sign of the NAN.
1722
1723inline void
1725{
1727 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1728 update_nan (nan);
1729}
1730
1731inline bool
1733{
1734 return contains_p (*TREE_REAL_CST_PTR (cst));
1735}
1736
1737// Clear the NAN bit and adjust the range.
1738
1739inline void
1741{
1743 m_pos_nan = false;
1744 m_neg_nan = false;
1745 normalize_kind ();
1746 if (flag_checking)
1747 verify_range ();
1748}
1749
1750// Set R to maximum representable value for TYPE.
1751
1752inline REAL_VALUE_TYPE
1754{
1756 char buf[128];
1758 buf, sizeof (buf), false);
1759 int res = real_from_string (&r, buf);
1760 gcc_checking_assert (!res);
1761 return r;
1762}
1763
1764// Return the minimum representable value for TYPE.
1765
1766inline REAL_VALUE_TYPE
1773
1774// Return the minimum value for TYPE.
1775
1776inline REAL_VALUE_TYPE
1778{
1779 if (HONOR_INFINITIES (type))
1780 return dconstninf;
1781 else
1783}
1784
1785// Return the maximum value for TYPE.
1786
1787inline REAL_VALUE_TYPE
1789{
1790 if (HONOR_INFINITIES (type))
1791 return dconstinf;
1792 else
1794}
1795
1796// Return TRUE if R is the minimum value for TYPE.
1797
1798inline bool
1800{
1802 return real_identical (&min, &r);
1803}
1804
1805// Return TRUE if R is the max value for TYPE.
1806
1807inline bool
1809{
1811 return real_identical (&max, &r);
1812}
1813
1814// Build a NAN with a state of NAN.
1815
1816inline void
1818{
1819 gcc_checking_assert (nan.pos_p () || nan.neg_p ());
1820 if (HONOR_NANS (type))
1821 {
1822 m_kind = VR_NAN;
1823 m_type = type;
1824 m_num_ranges = 1;
1825 m_neg_nan = nan.neg_p ();
1826 m_pos_nan = nan.pos_p ();
1827 if (flag_checking)
1828 verify_range ();
1829 }
1830 else
1831 set_undefined ();
1832}
1833
1834// Build a signless NAN of type TYPE.
1835
1836inline void
1838{
1839 nan_state nan (true);
1840 set_nan (type, nan);
1841}
1842
1843// Build a NAN of type TYPE with SIGN.
1844
1845inline void
1847{
1848 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1849 set_nan (type, nan);
1850}
1851
1852// Return TRUE if range is known to be finite.
1853
1854inline bool
1856{
1857 if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
1858 return false;
1859 return (!maybe_isnan ()
1860 && !real_isinf (&lower_bound ())
1861 && !real_isinf (&upper_bound ()));
1862}
1863
1864// Return TRUE if range is known to be normal.
1865
1866inline bool
1868{
1869 if (!known_isfinite ())
1870 return false;
1871
1872 machine_mode mode = TYPE_MODE (type ());
1873 const REAL_VALUE_TYPE &min = lower_bound ();
1874 const REAL_VALUE_TYPE &max = upper_bound ();
1875 return (!real_isdenormal (&min, mode) && !real_isdenormal (&max, mode)
1876 && !real_iszero (&min) && !real_iszero (&max)
1877 && (!real_isneg (&min) || real_isneg (&max)));
1878}
1879
1880// Return TRUE if range is known to be denormal.
1881
1882inline bool
1884{
1885 if (!known_isfinite ())
1886 return false;
1887
1888 machine_mode mode = TYPE_MODE (type ());
1889 const REAL_VALUE_TYPE &min = lower_bound ();
1890 const REAL_VALUE_TYPE &max = upper_bound ();
1891 return ((real_isdenormal (&min, mode) || real_iszero (&min))
1892 && (real_isdenormal (&max, mode) || real_iszero (&max)));
1893}
1894
1895// Return TRUE if range may be infinite.
1896
1897inline bool
1899{
1900 if (undefined_p () || m_kind == VR_ANTI_RANGE || m_kind == VR_NAN)
1901 return false;
1902 if (varying_p ())
1903 return true;
1904 return real_isinf (&lower_bound ()) || real_isinf (&upper_bound ());
1905}
1906
1907// Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
1908
1909inline bool
1911{
1912 return (m_kind == VR_RANGE
1913 && m_num_ranges == 1
1914 && !maybe_isnan ()
1915 && real_identical (&m_pairs[0].min, &m_pairs[0].max)
1916 && real_isinf (&m_pairs[0].min));
1917}
1918
1919// Return TRUE if range is possibly a NAN.
1920
1921inline bool
1923{
1924 if (undefined_p ())
1925 return false;
1926 return m_pos_nan || m_neg_nan;
1927}
1928
1929// Return TRUE if range is possibly a NAN with SIGN.
1930
1931inline bool
1932frange::maybe_isnan (bool sign) const
1933{
1934 if (undefined_p ())
1935 return false;
1936 if (sign)
1937 return m_neg_nan;
1938 return m_pos_nan;
1939}
1940
1941// Return TRUE if range is a +NAN or -NAN.
1942
1943inline bool
1945{
1946 return m_kind == VR_NAN;
1947}
1948
1949// If the signbit for the range is known, set it in SIGNBIT and return
1950// TRUE.
1951
1952inline bool
1953frange::signbit_p (bool &signbit) const
1954{
1955 if (undefined_p ())
1956 return false;
1957
1958 // NAN with unknown sign.
1959 if (m_pos_nan && m_neg_nan)
1960 return false;
1961 // No NAN.
1962 if (!m_pos_nan && !m_neg_nan)
1963 {
1964 if (lower_bound ().sign == upper_bound ().sign)
1965 {
1966 signbit = lower_bound ().sign;
1967 return true;
1968 }
1969 return false;
1970 }
1971 // NAN with known sign.
1972 bool nan_sign = m_neg_nan;
1973 if (known_isnan ()
1974 || (nan_sign == lower_bound ().sign
1975 && nan_sign == upper_bound ().sign))
1976 {
1977 signbit = nan_sign;
1978 return true;
1979 }
1980 return false;
1981}
1982
1983// If range has a NAN with a known sign, set it in SIGNBIT and return
1984// TRUE.
1985
1986inline bool
1987frange::nan_signbit_p (bool &signbit) const
1988{
1989 if (undefined_p ())
1990 return false;
1991
1992 if (m_pos_nan == m_neg_nan)
1993 return false;
1994
1995 signbit = m_neg_nan;
1996 return true;
1997}
1998
1999void frange_nextafter (enum machine_mode, REAL_VALUE_TYPE &,
2000 const REAL_VALUE_TYPE &);
2002 const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
2003 const REAL_VALUE_TYPE &);
2004
2005// Return true if TYPE1 and TYPE2 are compatible range types.
2006
2007inline bool
2009{
2010 // types_compatible_p requires conversion in both directions to be useless.
2011 // GIMPLE only requires a cast one way in order to be compatible.
2012 // Ranges really only need the sign and precision to be the same.
2013 return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
2014 && TYPE_SIGN (type1) == TYPE_SIGN (type2));
2015}
2016#endif // GCC_VALUE_RANGE_H
Definition value-range.h:603
tree m_type
Definition value-range.h:691
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:1283
void update_nan()
Definition value-range.h:1714
void clear_nan()
Definition value-range.h:1740
bool known_isfinite() const
Definition value-range.h:1855
bool known_isdenormal_or_zero() const
Definition value-range.h:1883
bool maybe_isinf() const
Definition value-range.h:1898
bool m_neg_nan
Definition value-range.h:695
bool known_isnormal() const
Definition value-range.h:1867
bool nan_signbit_p(bool &signbit) const
Definition value-range.h:1987
virtual void set_varying(tree type) override
Definition value-range.h:1663
bool m_pos_nan
Definition value-range.h:694
bool known_isnan() const
Definition value-range.h:1944
void flush_denormals_to_zero()
Definition value-range.cc:1055
virtual void set_undefined() override
Definition value-range.h:1683
bool maybe_isnan() const
Definition value-range.h:1922
bool normalize_kind()
Definition value-range.cc:1306
virtual void verify_range() const override
Definition value-range.cc:1630
unsigned char m_num_ranges
Definition value-range.h:693
bool known_isinf() const
Definition value-range.h:1910
frange_pair m_pairs[MAX_PAIRS]
Definition value-range.h:692
const REAL_VALUE_TYPE & upper_bound() const
Definition value-range.h:706
unsigned num_pairs() const
Definition value-range.h:672
void set_nan(tree type)
Definition value-range.h:1837
friend class vrange_printer
Definition value-range.h:605
frange()
Definition value-range.h:1615
const REAL_VALUE_TYPE & lower_bound() const
Definition value-range.h:699
friend class frange_storage
Definition value-range.h:604
bool signbit_p(bool &signbit) const
Definition value-range.h:1953
bool contains_p(const REAL_VALUE_TYPE &) const
Definition value-range.cc:1536
static bool supports_p(const_tree type)
Definition value-range.h:613
virtual tree type() const override
Definition value-range.h:1656
static const unsigned int MAX_PAIRS
Definition value-range.h:671
nan_state get_nan_state() const
Definition value-range.h:731
Definition inchash.h:38
Definition value-range.h:388
wide_int m_ranges[N *2]
Definition value-range.h:401
int_range()
Definition value-range.h:1184
int_range(tree type, const wide_int &, const wide_int &, value_range_kind=VR_RANGE)
Definition value-range.h:1211
int_range(tree type)
Definition value-range.h:1204
int_range(const irange &)
Definition value-range.h:1219
int_range(const int_range &)
Definition value-range.h:1190
int_range & operator=(const int_range &)
Definition value-range.h:1227
~int_range() final override
Definition value-range.h:824
Definition value-range.h:152
irange_bitmask(unsigned prec)
Definition value-range.h:155
void dump(FILE *) const
Definition value-range.cc:398
bool range_from_mask(irange &r, tree type) const
Definition value-range.cc:66
void verify_mask() const
Definition value-range.cc:3122
void set_nonzero_bits(const wide_int &bits)
Definition value-range.h:227
unsigned get_precision() const
Definition value-range.h:209
bool member_p(const wide_int &val) const
Definition value-range.h:238
void set_unknown(unsigned prec)
Definition value-range.h:183
bool unknown_p() const
Definition value-range.h:194
void union_(const irange_bitmask &src)
Definition value-range.h:259
bool operator==(const irange_bitmask &src) const
Definition value-range.h:249
wide_int get_nonzero_bits() const
Definition value-range.h:220
wide_int mask() const
Definition value-range.h:160
bool operator!=(const irange_bitmask &src) const
Definition value-range.h:167
bool intersect(const irange_bitmask &src)
Definition value-range.h:270
irange_bitmask()
Definition value-range.h:154
wide_int m_mask
Definition value-range.h:179
wide_int m_value
Definition value-range.h:178
wide_int value() const
Definition value-range.h:159
Definition value-range.h:291
friend class irange_storage
Definition value-range.h:292
bool invert()
Definition value-range.cc:2737
bool union_bitmask(const irange &r)
Definition value-range.cc:3081
virtual bool zero_p() const override
Definition value-range.h:1127
bool m_resizable
Definition value-range.h:371
virtual bool supports_type_p(const_tree type) const override
Definition value-range.cc:511
virtual void set_nonzero(tree type) override
Definition value-range.h:1294
unsigned num_pairs() const
Definition value-range.h:1080
unsigned char m_max_ranges
Definition value-range.h:372
virtual bool union_(const vrange &) override
Definition value-range.cc:2293
virtual void set_nonnegative(tree type) override
Definition value-range.cc:525
bool snap(const wide_int &, const wide_int &, wide_int &, wide_int &, bool &)
Definition value-range.cc:2859
void maybe_resize(int needed)
Definition value-range.h:806
bool union_append(const irange &r)
Definition value-range.cc:2255
virtual void set_varying(tree type) override
Definition value-range.h:1241
virtual bool contains_zero_p() const override
Definition value-range.h:1135
virtual tree lbound() const override
Definition value-range.cc:3110
bool intersect_bitmask(const irange &r)
Definition value-range.cc:3049
tree m_type
Definition value-range.h:373
virtual bool contains_p(tree cst) const override
Definition value-range.h:1151
virtual bool intersect(const vrange &) override
Definition value-range.cc:2483
bool nonnegative_p() const
Definition value-range.cc:499
virtual irange_bitmask get_bitmask() const override
Definition value-range.cc:2990
wide_int * m_base
Definition value-range.h:376
static const int HARD_MAX_RANGES
Definition value-range.h:358
bool operator==(const irange &) const
Definition value-range.cc:2097
virtual bool fits_p(const vrange &r) const override
Definition value-range.cc:519
void set(tree type, const wide_int &, const wide_int &, value_range_kind=VR_RANGE)
Definition value-range.cc:1973
unsigned char m_num_ranges
Definition value-range.h:370
virtual void accept(const vrange_visitor &v) const override
Definition value-range.cc:151
bool irange_single_pair_union(const irange &r)
Definition value-range.cc:2188
virtual bool singleton_p(tree *result=NULL) const override
Definition value-range.cc:2134
static bool supports_p(const_tree type)
Definition value-range.h:1145
wide_int upper_bound() const
Definition value-range.h:1284
wide_int lower_bound(unsigned=0) const
Definition value-range.h:1263
irange_bitmask m_bitmask
Definition value-range.h:374
virtual void set_undefined() override
Definition value-range.h:1234
virtual tree ubound() const override
Definition value-range.cc:3116
bool nonpositive_p() const
Definition value-range.cc:505
irange & operator=(const irange &)
Definition value-range.cc:1849
friend class vrange_printer
Definition value-range.h:293
virtual void set_zero(tree type) override
Definition value-range.h:1320
virtual void update_bitmask(const class irange_bitmask &) override
Definition value-range.cc:2967
bool contains_p(const wide_int &) const
Definition value-range.cc:2163
bool set_range_from_bitmask()
Definition value-range.cc:2950
bool irange_contains_p(const irange &) const
Definition value-range.cc:2432
bool varying_compatible_p() const
Definition value-range.h:1093
virtual tree type() const override
Definition value-range.h:1086
void normalize_kind()
Definition value-range.h:1329
bool snap_subranges()
Definition value-range.cc:2910
wide_int upper_bound(unsigned) const
Definition value-range.h:1274
bool operator!=(const irange &r) const
Definition value-range.h:334
irange(wide_int *, unsigned nranges, bool resizable)
Definition value-range.h:1171
virtual void verify_range() const override
Definition value-range.cc:2050
Definition value-range.h:541
bool neg_p() const
Definition value-range.h:584
bool m_neg_nan
Definition value-range.h:549
bool pos_p() const
Definition value-range.h:576
bool m_pos_nan
Definition value-range.h:548
nan_state(bool)
Definition value-range.h:556
Definition value-range.h:405
bool pt_equal_p(const class prange &p) const
Definition value-range.h:1550
bool pt_inverted_p(const prange &r) const
Definition value-range.h:1560
virtual bool supports_type_p(const_tree type) const final override
Definition value-range.h:1394
bool m_points_to_p
Definition value-range.h:494
wide_int m_min
Definition value-range.h:488
virtual bool intersect(const vrange &v) final override
Definition value-range.cc:777
virtual void set_nonnegative(tree type) final override
Definition value-range.cc:640
prange()
Definition value-range.h:1359
virtual void verify_range() const final override
Definition value-range.cc:931
virtual tree lbound() const final override
Definition value-range.cc:719
tree pt_base() const
Definition value-range.cc:584
wide_int upper_bound() const
Definition value-range.h:1486
irange_bitmask get_bitmask() const final override
Definition value-range.h:1500
wide_int m_max
Definition value-range.h:489
virtual bool contains_p(tree cst) const final override
Definition value-range.h:1449
tree m_type
Definition value-range.h:487
bool pt_invariant_p(const prange &r) const
Definition value-range.h:1594
virtual bool contains_zero_p() const final override
Definition value-range.h:1462
bool pt_unknown_p() const
Definition value-range.h:1544
bool varying_compatible_p() const
Definition value-range.h:1493
virtual void set_varying(tree type) final override
Definition value-range.h:1407
void set_pt_unknown()
Definition value-range.h:1537
tree m_pt
Definition value-range.h:493
static bool supports_p(const_tree type)
Definition value-range.h:1388
virtual void set_zero(tree type) final override
Definition value-range.h:1435
void pt_size(irange &) const
Definition value-range.cc:617
wide_int lower_bound() const
Definition value-range.h:1479
virtual bool fits_p(const vrange &v) const final override
Definition value-range.h:1506
virtual bool zero_p() const final override
Definition value-range.h:1455
void set_pt(const prange &r)
Definition value-range.h:1515
virtual void set_undefined() final override
Definition value-range.h:1400
bool pt_invariant_away_p(const prange &r) const
Definition value-range.h:1603
void update_bitmask(const irange_bitmask &) final override
Definition value-range.cc:959
virtual void set_nonzero(tree type) final override
Definition value-range.h:1421
friend class vrange_printer
Definition value-range.h:407
friend class prange_storage
Definition value-range.h:406
virtual bool singleton_p(tree *result=NULL) const final override
Definition value-range.cc:707
virtual tree ubound() const final override
Definition value-range.cc:725
tree pt_invariant() const
Definition value-range.h:1578
void pt_offset(irange &) const
Definition value-range.cc:599
bool pt_invert()
Definition value-range.h:1567
virtual tree type() const final override
Definition value-range.h:1472
virtual void set(tree, tree, value_range_kind=VR_RANGE) final override
Definition value-range.cc:648
virtual bool union_(const vrange &v) final override
Definition value-range.cc:731
bool invert()
Definition value-range.cc:891
irange_bitmask m_bitmask
Definition value-range.h:490
tree pt_invariant_away() const
Definition value-range.h:1586
Definition pretty-print.h:241
Definition value-range.h:503
unsupported_range & operator=(const unsupported_range &r)
Definition value-range.cc:327
unsupported_range(const unsupported_range &src)
Definition value-range.h:510
unsupported_range()
Definition value-range.h:505
Definition value-range.h:860
void verify_range() const
Definition value-range.h:900
void set_zero(tree type)
Definition value-range.h:889
~value_range()
Definition value-range.h:962
bool undefined_p() const
Definition value-range.h:881
bool contains_p(tree cst) const
Definition value-range.h:886
static bool supports_type_p(const_tree type)
Definition value-range.h:1064
void accept(const vrange_visitor &v) const
Definition value-range.h:899
bool varying_p() const
Definition value-range.h:880
vrange * m_vrange
Definition value-range.h:905
tree type()
Definition value-range.h:879
irange_bitmask get_bitmask() const
Definition value-range.h:896
tree ubound() const
Definition value-range.h:895
value_range()
Definition value-range.h:920
void print(pretty_printer *) const
Definition value-range.cc:166
bool intersect(const vrange &r)
Definition value-range.h:885
void update_bitmask(const class irange_bitmask &bm)
Definition value-range.h:897
bool union_(const vrange &r)
Definition value-range.h:884
void set_nonzero(tree type)
Definition value-range.h:890
void set_undefined()
Definition value-range.h:883
bool zero_p() const
Definition value-range.h:893
bool operator!=(const value_range &r) const
Definition value-range.h:1044
void set_range_class(tree type)
Definition value-range.h:973
bool contains_zero_p() const
Definition value-range.h:892
bool singleton_p(tree *result=NULL) const
Definition value-range.h:887
tree lbound() const
Definition value-range.h:894
void set_varying(tree type)
Definition value-range.h:882
vrange & operator=(const vrange &)
Definition value-range.h:1020
union value_range::buffer_type m_buffer
bool operator==(const value_range &r) const
Definition value-range.h:1038
void init(tree type)
Definition value-range.h:985
Definition value-range.h:837
virtual void visit(const unsupported_range &) const
Definition value-range.h:842
virtual void visit(const irange &) const
Definition value-range.h:839
virtual void visit(const frange &) const
Definition value-range.h:841
virtual void visit(const prange &) const
Definition value-range.h:840
Definition value-range.h:88
virtual void verify_range() const
Definition value-range.h:126
friend class value_range
Definition value-range.h:90
virtual irange_bitmask get_bitmask() const
Definition value-range.cc:205
vrange(enum value_range_discriminator d)
Definition value-range.h:128
enum value_range_kind m_kind
Definition value-range.h:129
virtual bool singleton_p(tree *result=NULL) const =0
bool operator!=(const vrange &r) const
Definition value-range.h:124
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:112
friend class range_op_handler
Definition value-range.h:92
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:1121
enum value_range_discriminator m_discriminator
Definition value-range.h:130
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:200
virtual bool contains_zero_p() const =0
virtual tree ubound() const =0
friend bool is_a(vrange &)
Definition value-range.h:741
void set_nonzero_bits(const wide_int &bits)
Definition value-range.cc:3028
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:354
virtual tree lbound() const =0
virtual tree type() const =0
void dump(FILE *) const
Definition value-range.cc:387
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:3038
virtual bool fits_p(const vrange &r) const =0
bool varying_p() const
Definition value-range.h:1115
bool operator==(const vrange &) const
Definition value-range.cc:373
const union tree_node * const_tree
Definition coretypes.h:98
union tree_node * tree
Definition coretypes.h:97
static bool operator!=(cfa_reg &cfa, rtx reg)
Definition dwarf2cfi.cc:1174
static bool operator==(cfa_reg &cfa, rtx reg)
Definition dwarf2cfi.cc:1164
REAL_VALUE_TYPE dconstninf
Definition emit-rtl.cc:113
REAL_VALUE_TYPE dconstinf
Definition emit-rtl.cc:112
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2003
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:4268
void add_vrange(const vrange &v, inchash::hash &hstate, unsigned int)
Definition value-range.cc:424
wide_int min_value(machine_mode, signop)
Definition rtl.h:2375
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:2383
tree_to_wide_ref to_wide(const_tree)
Definition tree.h:6673
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:279
static bool contains_zero_p(const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
Definition range-op-float.cc:2325
static bool zero_p(const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
Definition range-op-float.cc:2318
int real_from_string(REAL_VALUE_TYPE *r, const char *str)
Definition real.cc:2019
bool HONOR_NANS(machine_mode m)
Definition real.cc:5545
REAL_VALUE_TYPE real_value_negate(const REAL_VALUE_TYPE *op0)
Definition real.cc:1123
bool real_isneg(const REAL_VALUE_TYPE *r)
Definition real.cc:1288
bool real_isinf(const REAL_VALUE_TYPE *r)
Definition real.cc:1250
static bool real_isdenormal(const REAL_VALUE_TYPE *r)
Definition real.cc:124
bool real_identical(const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
Definition real.cc:1320
bool HONOR_INFINITIES(machine_mode m)
Definition real.cc:5586
bool real_iszero(const REAL_VALUE_TYPE *r)
Definition real.cc:1296
void get_max_float(const struct real_format *fmt, char *buf, size_t len, bool norm_max)
Definition real.cc:5463
#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 value-range.h:592
REAL_VALUE_TYPE min
Definition value-range.h:593
REAL_VALUE_TYPE max
Definition value-range.h:594
Definition lto-streamer.h:745
Definition gengtype.h:218
Definition cse.cc:4181
Definition gengtype.h:252
#define NULL
Definition system.h:58
#define gcc_unreachable()
Definition system.h:855
#define true
Definition system.h:901
#define gcc_checking_assert(EXPR)
Definition system.h:835
tree build_zero_cst(tree type)
Definition tree.cc:2781
#define DECIMAL_FLOAT_TYPE_P(TYPE)
Definition tree.h:693
#define TYPE_PRECISION(NODE)
Definition tree.h:2440
#define SCALAR_FLOAT_TYPE_P(TYPE)
Definition tree.h:661
#define TREE_REAL_CST_PTR(NODE)
Definition tree.h:1185
#define TYPE_UNSIGNED(NODE)
Definition tree.h:980
#define TYPE_MODE(NODE)
Definition tree.h:2449
#define TYPE_SIGN(NODE)
Definition tree.h:983
#define POINTER_TYPE_P(TYPE)
Definition tree.h:713
#define TYPE_P(NODE)
Definition tree.h:227
#define TREE_TYPE(NODE)
Definition tree.h:513
#define INTEGRAL_TYPE_P(TYPE)
Definition tree.h:614
#define error_mark_node
Definition tree.h:4616
#define NULL_TREE
Definition tree.h:318
unsupported_range unsupported
Definition value-range.h:909
buffer_type()
Definition value-range.h:911
prange pointers
Definition value-range.h:910
~buffer_type()
Definition value-range.h:912
frange floats
Definition value-range.h:908
int_range_max ints
Definition value-range.h:907
T & as_a(vrange &v)
Definition value-range.h:758
REAL_VALUE_TYPE frange_val_max(const_tree type)
Definition value-range.h:1788
bool range_includes_zero_p(const vrange &vr)
Definition value-range.h:1157
wide_int irange_val_max(const_tree type)
Definition value-range.h:1352
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:3129
bool is_a< prange >(vrange &v)
Definition value-range.h:783
bool is_a< unsupported_range >(vrange &v)
Definition value-range.h:797
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:1767
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:371
int_range< 3, true > int_range_max
Definition value-range.h:834
value_range_kind get_legacy_range(const vrange &, tree &min, tree &max)
Definition value-range.cc:1955
bool is_a< frange >(vrange &v)
Definition value-range.h:790
void frange_nextafter(enum machine_mode, REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &)
Definition range-op-float.cc:338
REAL_VALUE_TYPE real_max_representable(const_tree type)
Definition value-range.h:1753
wide_int irange_val_min(const_tree type)
Definition value-range.h:1345
bool range_compatible_p(tree type1, tree type2)
Definition value-range.h:2008
bool frange_val_is_min(const REAL_VALUE_TYPE &r, const_tree type)
Definition value-range.h:1799
bool frange_val_is_max(const REAL_VALUE_TYPE &r, const_tree type)
Definition value-range.h:1808
bool vrp_operand_equal_p(const_tree, const_tree)
Definition value-range.cc:3150
REAL_VALUE_TYPE frange_val_min(const_tree type)
Definition value-range.h:1777
bool is_a< irange >(vrange &v)
Definition value-range.h:776
generic_wide_int< wide_int_storage > wide_int
Definition wide-int.h:343