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