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