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 bool range_from_mask (irange &r, tree type) const;
154
155 bool member_p (const wide_int &val) const;
156
157 // Convenience functions for nonzero bitmask compatibility.
158 wide_int get_nonzero_bits () const;
159 void set_nonzero_bits (const wide_int &bits);
160private:
163};
164
165inline void
167{
168 m_value = wi::zero (prec);
169 m_mask = wi::minus_one (prec);
170 if (flag_checking)
171 verify_mask ();
172}
173
174// Return TRUE if THIS does not have any meaningful information.
175
176inline bool
178{
179 return m_mask == -1;
180}
181
182inline
184{
185 m_value = value;
186 m_mask = mask;
187 if (flag_checking)
188 verify_mask ();
189}
190
191inline unsigned
193{
194 return m_mask.get_precision ();
195}
196
197// The following two functions are meant for backwards compatability
198// with the nonzero bitmask. A cleared bit means the value must be 0.
199// A set bit means we have no information for the bit.
200
201// Return the nonzero bits.
202inline wide_int
204{
205 return m_value | m_mask;
206}
207
208// Set the bitmask to the nonzero bits in BITS.
209inline void
211{
212 m_value = wi::zero (bits.get_precision ());
213 m_mask = bits;
214 if (flag_checking)
215 verify_mask ();
216}
217
218// Return TRUE if val could be a valid value with this bitmask.
219
220inline bool
222{
223 if (unknown_p ())
224 return true;
225 wide_int res = m_mask & val;
226 if (m_value != 0)
227 res |= ~m_mask & m_value;
228 return res == val;
229}
230
231inline bool
233{
234 bool unknown1 = unknown_p ();
235 bool unknown2 = src.unknown_p ();
236 if (unknown1 || unknown2)
237 return unknown1 == unknown2;
238 return m_value == src.m_value && m_mask == src.m_mask;
239}
240
241inline void
243{
244 m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
245 m_value = m_value & src.m_value;
246 if (flag_checking)
247 verify_mask ();
248}
249
250inline void
252{
253 // If we have two known bits that are incompatible, the resulting
254 // bit is undefined. It is unclear whether we should set the entire
255 // range to UNDEFINED, or just a subset of it. For now, set the
256 // entire bitmask to unknown (VARYING).
257 if (wi::bit_and (~(m_mask | src.m_mask),
258 m_value ^ src.m_value) != 0)
259 {
260 unsigned prec = m_mask.get_precision ();
261 m_mask = wi::minus_one (prec);
262 m_value = wi::zero (prec);
263 }
264 else
265 {
266 m_mask = m_mask & src.m_mask;
267 m_value = m_value | src.m_value;
268 }
269 if (flag_checking)
270 verify_mask ();
271}
272
273// An integer range without any storage.
274
275class irange : public vrange
276{
277 friend class irange_storage;
278 friend class vrange_printer;
279public:
280 // In-place setters.
281 void set (tree type, const wide_int &, const wide_int &,
283 virtual void set_nonzero (tree type) override;
284 virtual void set_zero (tree type) override;
285 virtual void set_nonnegative (tree type) override;
286 virtual void set_varying (tree type) override;
287 virtual void set_undefined () override;
288
289 // Range types.
291 virtual bool supports_type_p (const_tree type) const override;
292 virtual tree type () const override;
293
294 // Iteration over sub-ranges.
295 unsigned num_pairs () const;
296 wide_int lower_bound (unsigned = 0) const;
297 wide_int upper_bound (unsigned) const;
299 virtual tree lbound () const override;
300 virtual tree ubound () const override;
301
302 // Predicates.
303 virtual bool zero_p () const override;
304 virtual bool nonzero_p () const override;
305 virtual bool singleton_p (tree *result = NULL) const override;
306 bool singleton_p (wide_int &) const;
307 bool contains_p (const wide_int &) const;
308 bool nonnegative_p () const;
309 bool nonpositive_p () const;
310
311 // In-place operators.
312 virtual bool union_ (const vrange &) override;
313 virtual bool intersect (const vrange &) override;
314 void invert ();
315
316 // Operator overloads.
317 irange& operator= (const irange &);
318 bool operator== (const irange &) const;
319 bool operator!= (const irange &r) const { return !(*this == r); }
320
321 // Misc methods.
322 virtual bool fits_p (const vrange &r) const override;
323 virtual void accept (const vrange_visitor &v) const override;
324
325 virtual void update_bitmask (const class irange_bitmask &) override;
326 virtual irange_bitmask get_bitmask () const override;
327
328 virtual void verify_range () const override;
329protected:
330 void maybe_resize (int needed);
331 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
332 virtual bool contains_p (tree cst) const override;
333 irange (wide_int *, unsigned nranges, bool resizable);
334
335 // In-place operators.
336 bool irange_contains_p (const irange &) const;
337 bool irange_single_pair_union (const irange &r);
338
340
341
342 // Hard limit on max ranges allowed.
343 static const int HARD_MAX_RANGES = 255;
344private:
345 bool varying_compatible_p () const;
346 bool intersect_bitmask (const irange &r);
347 bool union_bitmask (const irange &r);
349 bool snap_subranges ();
350 bool snap (const wide_int &, const wide_int &, wide_int &, wide_int &,
351 bool &);
352
353 bool intersect (const wide_int& lb, const wide_int& ub);
354 bool union_append (const irange &r);
355 unsigned char m_num_ranges;
357 unsigned char m_max_ranges;
360protected:
362};
363
364// Here we describe an irange with N pairs of ranges. The storage for
365// the pairs is embedded in the class as an array.
366//
367// If RESIZABLE is true, the storage will be resized on the heap when
368// the number of ranges needed goes past N up to a max of
369// HARD_MAX_RANGES. This new storage is freed upon destruction.
370
371template<unsigned N, bool RESIZABLE = false>
372class int_range final : public irange
373{
374public:
376 int_range (tree type, const wide_int &, const wide_int &,
380 int_range (const irange &);
381 ~int_range () final override;
382 int_range& operator= (const int_range &);
383protected:
385private:
387};
388
389class prange final : public vrange
390{
391 friend class prange_storage;
392 friend class vrange_printer;
393public:
394 prange ();
395 prange (const prange &);
396 prange (tree type);
397 prange (tree type, const wide_int &, const wide_int &,
399 static bool supports_p (const_tree type);
400 virtual bool supports_type_p (const_tree type) const final override;
401 virtual void accept (const vrange_visitor &v) const final override;
402 virtual void set_undefined () final override;
403 virtual void set_varying (tree type) final override;
404 virtual void set_nonzero (tree type) final override;
405 virtual void set_zero (tree type) final override;
406 virtual void set_nonnegative (tree type) final override;
407 virtual bool contains_p (tree cst) const final override;
408 virtual bool fits_p (const vrange &v) const final override;
409 virtual bool singleton_p (tree *result = NULL) const final override;
410 virtual bool zero_p () const final override;
411 virtual bool nonzero_p () const final override;
412 virtual void set (tree, tree, value_range_kind = VR_RANGE) final override;
413 virtual tree type () const final override;
414 virtual bool union_ (const vrange &v) final override;
415 virtual bool intersect (const vrange &v) final override;
416 virtual tree lbound () const final override;
417 virtual tree ubound () const final override;
418
419 prange& operator= (const prange &);
420 bool operator== (const prange &) const;
421 void set (tree type, const wide_int &, const wide_int &,
423 void invert ();
424 bool contains_p (const wide_int &) const;
425 wide_int lower_bound () const;
426 wide_int upper_bound () const;
427 virtual void verify_range () const final override;
428 irange_bitmask get_bitmask () const final override;
429 void update_bitmask (const irange_bitmask &) final override;
430protected:
431 bool varying_compatible_p () const;
432
437};
438
439// Unsupported temporaries may be created by ranger before it's known
440// they're unsupported, or by vr_values::get_value_range.
441
443{
444public:
447 {
448 set_undefined ();
449 }
455 void set (tree min, tree, value_range_kind = VR_RANGE) final override;
456 tree type () const final override;
457 bool supports_type_p (const_tree) const final override;
458 void set_varying (tree) final override;
459 void set_undefined () final override;
460 void accept (const vrange_visitor &v) const final override;
461 bool union_ (const vrange &r) final override;
462 bool intersect (const vrange &r) final override;
463 bool singleton_p (tree * = NULL) const final override;
464 bool contains_p (tree) const final override;
465 bool zero_p () const final override;
466 bool nonzero_p () const final override;
467 void set_nonzero (tree type) final override;
468 void set_zero (tree type) final override;
469 void set_nonnegative (tree type) final override;
470 bool fits_p (const vrange &) const final override;
471 unsupported_range& operator= (const unsupported_range &r);
472 tree lbound () const final override;
473 tree ubound () const final override;
474};
475
476// The NAN state as an opaque object.
477
479{
480public:
481 nan_state (bool);
482 nan_state (bool pos_nan, bool neg_nan);
483 bool neg_p () const;
484 bool pos_p () const;
485private:
488};
489
490// Set NAN state to +-NAN if NAN_P is true. Otherwise set NAN state
491// to false.
492
493inline
495{
496 m_pos_nan = nan_p;
497 m_neg_nan = nan_p;
498}
499
500// Constructor initializing the object to +NAN if POS_NAN is set, -NAN
501// if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
502// NEG_NAN are clear, and the object cannot be a NAN.
503
504inline
505nan_state::nan_state (bool pos_nan, bool neg_nan)
506{
507 m_pos_nan = pos_nan;
508 m_neg_nan = neg_nan;
509}
510
511// Return if +NAN is possible.
512
513inline bool
515{
516 return m_pos_nan;
517}
518
519// Return if -NAN is possible.
520
521inline bool
523{
524 return m_neg_nan;
525}
526
527// A floating point range.
528//
529// The representation is a type with a couple of endpoints, unioned
530// with the set of { -NAN, +Nan }.
531
532class frange final : public vrange
533{
534 friend class frange_storage;
535 friend class vrange_printer;
536public:
537 frange ();
538 frange (const frange &);
540 frange (tree type);
541 frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
544 {
545 // ?? Decimal floats can have multiple representations for the
546 // same number. Supporting them may be as simple as just
547 // disabling them in singleton_p. No clue.
549 }
550 virtual tree type () const override;
551 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
553 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
555 void set_nan (tree type);
556 void set_nan (tree type, bool sign);
557 void set_nan (tree type, const nan_state &);
558 virtual void set_varying (tree type) override;
559 virtual void set_undefined () override;
560 virtual bool union_ (const vrange &) override;
561 virtual bool intersect (const vrange &) override;
562 bool contains_p (const REAL_VALUE_TYPE &) const;
563 virtual bool singleton_p (tree *result = NULL) const override;
564 bool singleton_p (REAL_VALUE_TYPE &r) const;
565 virtual bool supports_type_p (const_tree type) const override;
566 virtual void accept (const vrange_visitor &v) const override;
567 virtual bool zero_p () const override;
568 virtual bool nonzero_p () const override;
569 virtual void set_nonzero (tree type) override;
570 virtual void set_zero (tree type) override;
571 virtual void set_nonnegative (tree type) override;
572 virtual bool fits_p (const vrange &) const override;
573 frange& operator= (const frange &);
574 bool operator== (const frange &) const;
575 bool operator!= (const frange &r) const { return !(*this == r); }
576 const REAL_VALUE_TYPE &lower_bound () const;
577 const REAL_VALUE_TYPE &upper_bound () const;
578 virtual tree lbound () const override;
579 virtual tree ubound () const override;
580 nan_state get_nan_state () const;
581 void update_nan ();
582 void update_nan (bool sign);
583 void update_nan (tree) = delete; // Disallow silent conversion to bool.
584 void update_nan (const nan_state &);
585 void clear_nan ();
587
588 // fpclassify like API
589 bool known_isfinite () const;
590 bool known_isnan () const;
591 bool known_isinf () const;
592 bool maybe_isnan () const;
593 bool maybe_isnan (bool sign) const;
594 bool maybe_isinf () const;
595 bool signbit_p (bool &signbit) const;
596 bool nan_signbit_p (bool &signbit) const;
597 bool known_isnormal () const;
598 bool known_isdenormal_or_zero () const;
599 virtual void verify_range () const override;
600protected:
601 virtual bool contains_p (tree cst) const override;
602 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
603
604private:
606 bool normalize_kind ();
607 bool union_nans (const frange &);
608 bool intersect_nans (const frange &);
609 bool combine_zeros (const frange &, bool union_p);
610
616};
617
618inline const REAL_VALUE_TYPE &
620{
622 return m_min;
623}
624
625inline const REAL_VALUE_TYPE &
627{
629 return m_max;
630}
631
632// Return the NAN state.
633
634inline nan_state
636{
637 return nan_state (m_pos_nan, m_neg_nan);
638}
639
640// is_a<> and as_a<> implementation for vrange.
641
642// Anything we haven't specialized is a hard fail.
643template <typename T>
644inline bool
646{
648 return false;
649}
650
651template <typename T>
652inline bool
653is_a (const vrange &v)
654{
655 // Reuse is_a <vrange> to implement the const version.
656 const T &derived = static_cast<const T &> (v);
657 return is_a <T> (const_cast<T &> (derived));
658}
659
660template <typename T>
661inline T &
663{
665 return static_cast <T &> (v);
666}
667
668template <typename T>
669inline const T &
670as_a (const vrange &v)
671{
673 return static_cast <const T &> (v);
674}
675
676// Specializations for the different range types.
677
678template <>
679inline bool
681{
682 return v.m_discriminator == VR_IRANGE;
683}
684
685template <>
686inline bool
688{
689 return v.m_discriminator == VR_PRANGE;
690}
691
692template <>
693inline bool
695{
696 return v.m_discriminator == VR_FRANGE;
697}
698
699template <>
700inline bool
702{
703 return v.m_discriminator == VR_UNKNOWN;
704}
705
706// For resizable ranges, resize the range up to HARD_MAX_RANGES if the
707// NEEDED pairs is greater than the current capacity of the range.
708
709inline void
711{
713 return;
714
715 if (needed > m_max_ranges)
716 {
718 wide_int *newmem = new wide_int[m_max_ranges * 2];
719 unsigned n = num_pairs () * 2;
720 for (unsigned i = 0; i < n; ++i)
721 newmem[i] = m_base[i];
722 m_base = newmem;
723 }
724}
725
726template<unsigned N, bool RESIZABLE>
727inline
729{
730 if (RESIZABLE && m_base != m_ranges)
731 delete[] m_base;
732}
733
734// This is an "infinite" precision irange for use in temporary
735// calculations. It starts with a sensible default covering 99% of
736// uses, and goes up to HARD_MAX_RANGES when needed. Any allocated
737// storage is freed upon destruction.
738typedef int_range<3, /*RESIZABLE=*/true> int_range_max;
739
741{
742public:
743 virtual void visit (const irange &) const { }
744 virtual void visit (const prange &) const { }
745 virtual void visit (const frange &) const { }
746 virtual void visit (const unsupported_range &) const { }
747};
748
749// This is an "infinite" precision range object for use in temporary
750// calculations for any of the handled types. The object can be
751// transparently used as a vrange.
752//
753// Using any of the various constructors initializes the object
754// appropriately, but the default constructor is uninitialized and
755// must be initialized either with set_type() or by assigning into it.
756//
757// Assigning between incompatible types is allowed. For example if a
758// temporary holds an irange, you can assign an frange into it, and
759// all the right things will happen. However, before passing this
760// object to a function accepting a vrange, the correct type must be
761// set. If it isn't, you can do so with set_type().
762
764{
765public:
766 value_range ();
767 value_range (const vrange &r);
770 value_range (const value_range &);
771 ~value_range ();
772 void set_type (tree type);
773 vrange& operator= (const vrange &);
775 bool operator== (const value_range &r) const;
776 bool operator!= (const value_range &r) const;
777 operator vrange &();
778 operator const vrange &() const;
779 void dump (FILE *) const;
780 static bool supports_type_p (const_tree type);
781
782 tree type () { return m_vrange->type (); }
783 bool varying_p () const { return m_vrange->varying_p (); }
784 bool undefined_p () const { return m_vrange->undefined_p (); }
785 void set_varying (tree type) { init (type); m_vrange->set_varying (type); }
786 void set_undefined () { m_vrange->set_undefined (); }
787 bool union_ (const vrange &r) { return m_vrange->union_ (r); }
788 bool intersect (const vrange &r) { return m_vrange->intersect (r); }
789 bool contains_p (tree cst) const { return m_vrange->contains_p (cst); }
790 bool singleton_p (tree *result = NULL) const
791 { return m_vrange->singleton_p (result); }
792 void set_zero (tree type) { init (type); return m_vrange->set_zero (type); }
794 { init (type); return m_vrange->set_nonzero (type); }
795 bool nonzero_p () const { return m_vrange->nonzero_p (); }
796 bool zero_p () const { return m_vrange->zero_p (); }
797 tree lbound () const { return m_vrange->lbound (); }
798 tree ubound () const { return m_vrange->ubound (); }
799 irange_bitmask get_bitmask () const { return m_vrange->get_bitmask (); }
800 void update_bitmask (const class irange_bitmask &bm)
801 { return m_vrange->update_bitmask (bm); }
802 void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
803 void verify_range () const { m_vrange->verify_range (); }
804private:
805 void init (tree type);
806 void init (const vrange &);
807
817};
818
819// The default constructor is uninitialized and must be initialized
820// with either set_type() or with an assignment into it.
821
822inline
824 : m_buffer ()
825{
826 m_vrange = NULL;
827}
828
829// Copy constructor.
830
831inline
833{
834 init (*r.m_vrange);
835}
836
837// Copy constructor from a vrange.
838
839inline
841{
842 init (r);
843}
844
845// Construct an UNDEFINED range that can hold ranges of TYPE. If TYPE
846// is not supported, default to unsupported_range.
847
848inline
853
854// Construct a range that can hold a range of [MIN, MAX], where MIN
855// and MAX are trees.
856
857inline
859{
860 init (TREE_TYPE (min));
861 m_vrange->set (min, max, kind);
862}
863
864inline
866{
867 if (m_vrange)
868 m_vrange->~vrange ();
869}
870
871// Initialize object to an UNDEFINED range that can hold ranges of
872// TYPE. Clean-up memory if there was a previous object.
873
874inline void
876{
877 if (m_vrange)
878 m_vrange->~vrange ();
879 init (type);
880}
881
882// Initialize object to an UNDEFINED range that can hold ranges of
883// TYPE.
884
885inline void
887{
889
891 m_vrange = new (&m_buffer.ints) int_range_max ();
892 else if (prange::supports_p (type))
893 m_vrange = new (&m_buffer.pointers) prange ();
894 else if (frange::supports_p (type))
895 m_vrange = new (&m_buffer.floats) frange ();
896 else
897 m_vrange = new (&m_buffer.unsupported) unsupported_range ();
898}
899
900// Initialize object with a copy of R.
901
902inline void
904{
905 if (is_a <irange> (r))
907 else if (is_a <prange> (r))
908 m_vrange = new (&m_buffer.pointers) prange (as_a <prange> (r));
909 else if (is_a <frange> (r))
910 m_vrange = new (&m_buffer.floats) frange (as_a <frange> (r));
911 else
912 m_vrange = new (&m_buffer.unsupported)
914}
915
916// Assignment operator. Copying incompatible types is allowed. That
917// is, assigning an frange to an object holding an irange does the
918// right thing.
919
920inline vrange &
922{
923 if (m_vrange)
924 m_vrange->~vrange ();
925 init (r);
926 return *m_vrange;
927}
928
929inline value_range &
931{
932 // No need to call the m_vrange destructor here, as we will do so in
933 // the assignment below.
934 *this = *r.m_vrange;
935 return *this;
936}
937
938inline bool
940{
941 return *m_vrange == *r.m_vrange;
942}
943
944inline bool
946{
947 return *m_vrange != *r.m_vrange;
948}
949
950inline
951value_range::operator vrange &()
952{
953 return *m_vrange;
954}
955
956inline
957value_range::operator const vrange &() const
958{
959 return *m_vrange;
960}
961
962// Return TRUE if TYPE is supported by the vrange infrastructure.
963
964inline bool
971
972extern value_range_kind get_legacy_range (const vrange &, tree &min, tree &max);
973extern void dump_value_range (FILE *, const vrange *);
977
978// Number of sub-ranges in a range.
979
980inline unsigned
982{
983 return m_num_ranges;
984}
985
986inline tree
988{
990 return m_type;
991}
992
993inline bool
995{
996 if (m_num_ranges != 1)
997 return false;
998
999 const wide_int &l = m_base[0];
1000 const wide_int &u = m_base[1];
1001 tree t = m_type;
1002
1003 if (m_kind == VR_VARYING)
1004 return true;
1005
1006 unsigned prec = TYPE_PRECISION (t);
1007 signop sign = TYPE_SIGN (t);
1008 if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
1009 return (l == wi::min_value (prec, sign)
1010 && u == wi::max_value (prec, sign)
1011 && m_bitmask.unknown_p ());
1012 return true;
1013}
1014
1015inline bool
1017{
1018 return m_kind == VR_VARYING;
1019}
1020
1021inline bool
1023{
1024 return m_kind == VR_UNDEFINED;
1025}
1026
1027inline bool
1029{
1030 return (m_kind == VR_RANGE && m_num_ranges == 1
1031 && lower_bound (0) == 0
1032 && upper_bound (0) == 0);
1033}
1034
1035inline bool
1037{
1038 if (undefined_p ())
1039 return false;
1040
1041 wide_int zero = wi::zero (TYPE_PRECISION (type ()));
1042 return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
1043}
1044
1045inline bool
1050
1051inline bool
1053{
1054 return contains_p (wi::to_wide (cst));
1055}
1056
1057inline bool
1059{
1060 if (vr.undefined_p ())
1061 return false;
1062
1063 if (vr.varying_p ())
1064 return true;
1065
1066 return vr.contains_p (build_zero_cst (vr.type ()));
1067}
1068
1069// Constructors for irange
1070
1071inline
1072irange::irange (wide_int *base, unsigned nranges, bool resizable)
1073 : vrange (VR_IRANGE),
1074 m_resizable (resizable),
1075 m_max_ranges (nranges)
1076{
1077 m_base = base;
1078 set_undefined ();
1079}
1080
1081// Constructors for int_range<>.
1082
1083template<unsigned N, bool RESIZABLE>
1084inline
1086 : irange (m_ranges, N, RESIZABLE)
1087{
1088}
1089
1090template<unsigned N, bool RESIZABLE>
1092 : irange (m_ranges, N, RESIZABLE)
1093{
1094 irange::operator= (other);
1095}
1096
1097template<unsigned N, bool RESIZABLE>
1099 : irange (m_ranges, N, RESIZABLE)
1100{
1101 irange::set (min, max, kind);
1102}
1103
1104template<unsigned N, bool RESIZABLE>
1110
1111template<unsigned N, bool RESIZABLE>
1113 value_range_kind kind)
1114 : irange (m_ranges, N, RESIZABLE)
1115{
1116 set (type, wmin, wmax, kind);
1117}
1118
1119template<unsigned N, bool RESIZABLE>
1121 : irange (m_ranges, N, RESIZABLE)
1122{
1123 irange::operator= (other);
1124}
1125
1126template<unsigned N, bool RESIZABLE>
1129{
1130 irange::operator= (src);
1131 return *this;
1132}
1133
1134inline void
1140
1141inline void
1143{
1145 m_num_ranges = 1;
1146 m_bitmask.set_unknown (TYPE_PRECISION (type));
1147
1149 {
1150 m_type = type;
1151 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
1152 // min_value and max_value.
1155 }
1156 else
1158}
1159
1160// Return the lower bound of a sub-range. PAIR is the sub-range in
1161// question.
1162
1163inline wide_int
1165{
1168 return m_base[pair * 2];
1169}
1170
1171// Return the upper bound of a sub-range. PAIR is the sub-range in
1172// question.
1173
1174inline wide_int
1176{
1179 return m_base[pair * 2 + 1];
1180}
1181
1182// Return the highest bound of a range.
1183
1184inline wide_int
1186{
1187 unsigned pairs = num_pairs ();
1188 gcc_checking_assert (pairs > 0);
1189 return upper_bound (pairs - 1);
1190}
1191
1192// Set value range VR to a nonzero range of type TYPE.
1193
1194inline void
1196{
1197 unsigned prec = TYPE_PRECISION (type);
1198
1199 if (TYPE_UNSIGNED (type))
1200 {
1201 m_type = type;
1202 m_kind = VR_RANGE;
1203 m_base[0] = wi::one (prec);
1204 m_base[1] = wi::minus_one (prec);
1205 m_bitmask.set_unknown (prec);
1206 m_num_ranges = 1;
1207
1208 if (flag_checking)
1209 verify_range ();
1210 }
1211 else
1212 {
1213 wide_int zero = wi::zero (prec);
1214 set (type, zero, zero, VR_ANTI_RANGE);
1215 }
1216}
1217
1218// Set value range VR to a ZERO range of type TYPE.
1219
1220inline void
1222{
1224 set (type, zero, zero);
1225}
1226
1227// Normalize a range to VARYING or UNDEFINED if possible.
1228
1229inline void
1231{
1232 if (m_num_ranges == 0)
1233 set_undefined ();
1234 else if (varying_compatible_p ())
1235 {
1236 if (m_kind == VR_RANGE)
1238 else if (m_kind == VR_ANTI_RANGE)
1239 set_undefined ();
1240 }
1241 if (flag_checking)
1242 verify_range ();
1243}
1244
1245inline bool
1247{
1248 if (r.undefined_p ())
1249 return false;
1250
1251 wide_int zero = wi::zero (TYPE_PRECISION (r.type ()));
1252 return r.contains_p (zero);
1253}
1254
1255inline wide_int
1261
1262inline wide_int
1268
1269inline
1271 : vrange (VR_PRANGE)
1272{
1273 set_undefined ();
1274}
1275
1276inline
1278 : vrange (VR_PRANGE)
1279{
1280 *this = r;
1281}
1282
1283inline
1285 : vrange (VR_PRANGE)
1286{
1287 set_varying (type);
1288}
1289
1290inline
1292 value_range_kind kind)
1293 : vrange (VR_PRANGE)
1294{
1295 set (type, lb, ub, kind);
1296}
1297
1298inline bool
1303
1304inline bool
1306{
1307 return POINTER_TYPE_P (type);
1308}
1309
1310inline void
1315
1316inline void
1318{
1320 m_type = type;
1323 m_bitmask.set_unknown (TYPE_PRECISION (type));
1324
1325 if (flag_checking)
1326 verify_range ();
1327}
1328
1329inline void
1331{
1332 m_kind = VR_RANGE;
1333 m_type = type;
1336 m_bitmask.set_unknown (TYPE_PRECISION (type));
1337
1338 if (flag_checking)
1339 verify_range ();
1340}
1341
1342inline void
1344{
1345 m_kind = VR_RANGE;
1346 m_type = type;
1348 m_min = m_max = zero;
1349 m_bitmask = irange_bitmask (zero, zero);
1350
1351 if (flag_checking)
1352 verify_range ();
1353}
1354
1355inline bool
1357{
1358 return contains_p (wi::to_wide (cst));
1359}
1360
1361inline bool
1363{
1364 return m_kind == VR_RANGE && m_min == 0 && m_max == 0;
1365}
1366
1367inline bool
1369{
1370 return m_kind == VR_RANGE && m_min == 1 && m_max == -1;
1371}
1372
1373inline tree
1375{
1377 return m_type;
1378}
1379
1380inline wide_int
1382{
1384 return m_min;
1385}
1386
1387inline wide_int
1389{
1391 return m_max;
1392}
1393
1394inline bool
1396{
1397 return (!undefined_p ()
1398 && m_min == 0 && m_max == -1 && get_bitmask ().unknown_p ());
1399}
1400
1401inline irange_bitmask
1403{
1404 return m_bitmask;
1405}
1406
1407inline bool
1408prange::fits_p (const vrange &) const
1409{
1410 return true;
1411}
1412
1413
1414inline
1416 : vrange (VR_FRANGE)
1417{
1418 set_undefined ();
1419}
1420
1421inline
1423 : vrange (VR_FRANGE)
1424{
1425 *this = src;
1426}
1427
1428inline
1430 : vrange (VR_FRANGE)
1431{
1432 set_varying (type);
1433}
1434
1435// frange constructor from REAL_VALUE_TYPE endpoints.
1436
1437inline
1439 const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
1440 value_range_kind kind)
1441 : vrange (VR_FRANGE)
1442{
1443 set (type, min, max, kind);
1444}
1445
1446// frange constructor from trees.
1447
1448inline
1450 : vrange (VR_FRANGE)
1451{
1452 set (min, max, kind);
1453}
1454
1455inline tree
1457{
1459 return m_type;
1460}
1461
1462inline void
1464{
1466 m_type = type;
1469 if (HONOR_NANS (m_type))
1470 {
1471 m_pos_nan = true;
1472 m_neg_nan = true;
1473 }
1474 else
1475 {
1476 m_pos_nan = false;
1477 m_neg_nan = false;
1478 }
1479}
1480
1481inline void
1483{
1485 m_type = NULL;
1486 m_pos_nan = false;
1487 m_neg_nan = false;
1488 // m_min and m_min are uninitialized as they are REAL_VALUE_TYPE ??.
1489 if (flag_checking)
1490 verify_range ();
1491}
1492
1493// Set the NAN bits to NAN and adjust the range.
1494
1495inline void
1497{
1499 if (HONOR_NANS (m_type))
1500 {
1501 m_pos_nan = nan.pos_p ();
1502 m_neg_nan = nan.neg_p ();
1503 normalize_kind ();
1504 if (flag_checking)
1505 verify_range ();
1506 }
1507}
1508
1509// Set the NAN bit to +-NAN.
1510
1511inline void
1513{
1515 nan_state nan (true);
1516 update_nan (nan);
1517}
1518
1519// Like above, but set the sign of the NAN.
1520
1521inline void
1523{
1525 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1526 update_nan (nan);
1527}
1528
1529inline bool
1531{
1532 return contains_p (*TREE_REAL_CST_PTR (cst));
1533}
1534
1535// Clear the NAN bit and adjust the range.
1536
1537inline void
1539{
1541 m_pos_nan = false;
1542 m_neg_nan = false;
1543 normalize_kind ();
1544 if (flag_checking)
1545 verify_range ();
1546}
1547
1548// Set R to maximum representable value for TYPE.
1549
1550inline REAL_VALUE_TYPE
1552{
1554 char buf[128];
1556 buf, sizeof (buf), false);
1557 int res = real_from_string (&r, buf);
1558 gcc_checking_assert (!res);
1559 return r;
1560}
1561
1562// Return the minimum representable value for TYPE.
1563
1564inline REAL_VALUE_TYPE
1571
1572// Return the minimum value for TYPE.
1573
1574inline REAL_VALUE_TYPE
1576{
1577 if (HONOR_INFINITIES (type))
1578 return dconstninf;
1579 else
1581}
1582
1583// Return the maximum value for TYPE.
1584
1585inline REAL_VALUE_TYPE
1587{
1588 if (HONOR_INFINITIES (type))
1589 return dconstinf;
1590 else
1592}
1593
1594// Return TRUE if R is the minimum value for TYPE.
1595
1596inline bool
1598{
1600 return real_identical (&min, &r);
1601}
1602
1603// Return TRUE if R is the max value for TYPE.
1604
1605inline bool
1607{
1609 return real_identical (&max, &r);
1610}
1611
1612// Build a NAN with a state of NAN.
1613
1614inline void
1616{
1617 gcc_checking_assert (nan.pos_p () || nan.neg_p ());
1618 if (HONOR_NANS (type))
1619 {
1620 m_kind = VR_NAN;
1621 m_type = type;
1622 m_neg_nan = nan.neg_p ();
1623 m_pos_nan = nan.pos_p ();
1624 if (flag_checking)
1625 verify_range ();
1626 }
1627 else
1628 set_undefined ();
1629}
1630
1631// Build a signless NAN of type TYPE.
1632
1633inline void
1635{
1636 nan_state nan (true);
1637 set_nan (type, nan);
1638}
1639
1640// Build a NAN of type TYPE with SIGN.
1641
1642inline void
1644{
1645 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1646 set_nan (type, nan);
1647}
1648
1649// Return TRUE if range is known to be finite.
1650
1651inline bool
1653{
1654 if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
1655 return false;
1656 return (!maybe_isnan () && !real_isinf (&m_min) && !real_isinf (&m_max));
1657}
1658
1659// Return TRUE if range is known to be normal.
1660
1661inline bool
1663{
1664 if (!known_isfinite ())
1665 return false;
1666
1667 machine_mode mode = TYPE_MODE (type ());
1668 return (!real_isdenormal (&m_min, mode) && !real_isdenormal (&m_max, mode)
1669 && !real_iszero (&m_min) && !real_iszero (&m_max)
1670 && (!real_isneg (&m_min) || real_isneg (&m_max)));
1671}
1672
1673// Return TRUE if range is known to be denormal.
1674
1675inline bool
1677{
1678 if (!known_isfinite ())
1679 return false;
1680
1681 machine_mode mode = TYPE_MODE (type ());
1682 return ((real_isdenormal (&m_min, mode) || real_iszero (&m_min))
1683 && (real_isdenormal (&m_max, mode) || real_iszero (&m_max)));
1684}
1685
1686// Return TRUE if range may be infinite.
1687
1688inline bool
1690{
1691 if (undefined_p () || m_kind == VR_ANTI_RANGE || m_kind == VR_NAN)
1692 return false;
1693 if (varying_p ())
1694 return true;
1695 return real_isinf (&m_min) || real_isinf (&m_max);
1696}
1697
1698// Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
1699
1700inline bool
1702{
1703 return (m_kind == VR_RANGE
1704 && !maybe_isnan ()
1705 && real_identical (&m_min, &m_max)
1706 && real_isinf (&m_min));
1707}
1708
1709// Return TRUE if range is possibly a NAN.
1710
1711inline bool
1713{
1714 if (undefined_p ())
1715 return false;
1716 return m_pos_nan || m_neg_nan;
1717}
1718
1719// Return TRUE if range is possibly a NAN with SIGN.
1720
1721inline bool
1722frange::maybe_isnan (bool sign) const
1723{
1724 if (undefined_p ())
1725 return false;
1726 if (sign)
1727 return m_neg_nan;
1728 return m_pos_nan;
1729}
1730
1731// Return TRUE if range is a +NAN or -NAN.
1732
1733inline bool
1735{
1736 return m_kind == VR_NAN;
1737}
1738
1739// If the signbit for the range is known, set it in SIGNBIT and return
1740// TRUE.
1741
1742inline bool
1743frange::signbit_p (bool &signbit) const
1744{
1745 if (undefined_p ())
1746 return false;
1747
1748 // NAN with unknown sign.
1749 if (m_pos_nan && m_neg_nan)
1750 return false;
1751 // No NAN.
1752 if (!m_pos_nan && !m_neg_nan)
1753 {
1754 if (m_min.sign == m_max.sign)
1755 {
1756 signbit = m_min.sign;
1757 return true;
1758 }
1759 return false;
1760 }
1761 // NAN with known sign.
1762 bool nan_sign = m_neg_nan;
1763 if (known_isnan ()
1764 || (nan_sign == m_min.sign && nan_sign == m_max.sign))
1765 {
1766 signbit = nan_sign;
1767 return true;
1768 }
1769 return false;
1770}
1771
1772// If range has a NAN with a known sign, set it in SIGNBIT and return
1773// TRUE.
1774
1775inline bool
1776frange::nan_signbit_p (bool &signbit) const
1777{
1778 if (undefined_p ())
1779 return false;
1780
1781 if (m_pos_nan == m_neg_nan)
1782 return false;
1783
1784 signbit = m_neg_nan;
1785 return true;
1786}
1787
1788void frange_nextafter (enum machine_mode, REAL_VALUE_TYPE &,
1789 const REAL_VALUE_TYPE &);
1791 const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
1792 const REAL_VALUE_TYPE &);
1793
1794// Return true if TYPE1 and TYPE2 are compatible range types.
1795
1796inline bool
1798{
1799 // types_compatible_p requires conversion in both directions to be useless.
1800 // GIMPLE only requires a cast one way in order to be compatible.
1801 // Ranges really only need the sign and precision to be the same.
1802 return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
1803 && TYPE_SIGN (type1) == TYPE_SIGN (type2));
1804}
1805#endif // GCC_VALUE_RANGE_H
Definition value-range.h:533
tree m_type
Definition value-range.h:611
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:914
void update_nan()
Definition value-range.h:1512
void clear_nan()
Definition value-range.h:1538
REAL_VALUE_TYPE m_min
Definition value-range.h:612
bool known_isfinite() const
Definition value-range.h:1652
bool known_isdenormal_or_zero() const
Definition value-range.h:1676
REAL_VALUE_TYPE m_max
Definition value-range.h:613
bool intersect_nans(const frange &)
Definition value-range.cc:1079
bool maybe_isinf() const
Definition value-range.h:1689
bool internal_singleton_p(REAL_VALUE_TYPE *=NULL) const
Definition value-range.cc:1240
bool m_neg_nan
Definition value-range.h:615
bool known_isnormal() const
Definition value-range.h:1662
bool nan_signbit_p(bool &signbit) const
Definition value-range.h:1776
virtual void set_varying(tree type) override
Definition value-range.h:1463
bool m_pos_nan
Definition value-range.h:614
bool known_isnan() const
Definition value-range.h:1734
void flush_denormals_to_zero()
Definition value-range.cc:815
bool union_nans(const frange &)
Definition value-range.cc:1007
virtual void set_undefined() override
Definition value-range.h:1482
bool maybe_isnan() const
Definition value-range.h:1712
bool normalize_kind()
Definition value-range.cc:937
virtual void verify_range() const override
Definition value-range.cc:1295
bool known_isinf() const
Definition value-range.h:1701
const REAL_VALUE_TYPE & upper_bound() const
Definition value-range.h:626
void set_nan(tree type)
Definition value-range.h:1634
friend class vrange_printer
Definition value-range.h:535
frange()
Definition value-range.h:1415
const REAL_VALUE_TYPE & lower_bound() const
Definition value-range.h:619
bool combine_zeros(const frange &, bool union_p)
Definition value-range.cc:975
friend class frange_storage
Definition value-range.h:534
bool signbit_p(bool &signbit) const
Definition value-range.h:1743
bool contains_p(const REAL_VALUE_TYPE &) const
Definition value-range.cc:1201
static bool supports_p(const_tree type)
Definition value-range.h:543
virtual tree type() const override
Definition value-range.h:1456
nan_state get_nan_state() const
Definition value-range.h:635
Definition inchash.h:38
Definition value-range.h:373
wide_int m_ranges[N *2]
Definition value-range.h:386
int_range()
Definition value-range.h:1085
int_range(tree type, const wide_int &, const wide_int &, value_range_kind=VR_RANGE)
Definition value-range.h:1112
int_range(tree type)
Definition value-range.h:1105
int_range(const irange &)
Definition value-range.h:1120
int_range(const int_range &)
Definition value-range.h:1091
int_range & operator=(const int_range &)
Definition value-range.h:1128
~int_range() final override
Definition value-range.h:728
Definition value-range.h:135
irange_bitmask(unsigned prec)
Definition value-range.h:138
void dump(FILE *) const
Definition value-range.cc:381
bool range_from_mask(irange &r, tree type) const
Definition value-range.cc:63
void verify_mask() const
Definition value-range.cc:2634
void set_nonzero_bits(const wide_int &bits)
Definition value-range.h:210
unsigned get_precision() const
Definition value-range.h:192
bool member_p(const wide_int &val) const
Definition value-range.h:221
void set_unknown(unsigned prec)
Definition value-range.h:166
bool unknown_p() const
Definition value-range.h:177
void union_(const irange_bitmask &src)
Definition value-range.h:242
bool operator==(const irange_bitmask &src) const
Definition value-range.h:232
wide_int get_nonzero_bits() const
Definition value-range.h:203
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:162
void intersect(const irange_bitmask &src)
Definition value-range.h:251
wide_int m_value
Definition value-range.h:161
wide_int value() const
Definition value-range.h:142
Definition value-range.h:276
friend class irange_storage
Definition value-range.h:277
void invert()
Definition value-range.cc:2268
bool union_bitmask(const irange &r)
Definition value-range.cc:2593
virtual bool nonzero_p() const override
Definition value-range.h:1036
virtual bool zero_p() const override
Definition value-range.h:1028
bool m_resizable
Definition value-range.h:356
virtual bool supports_type_p(const_tree type) const override
Definition value-range.cc:486
virtual void set_nonzero(tree type) override
Definition value-range.h:1195
unsigned num_pairs() const
Definition value-range.h:981
unsigned char m_max_ranges
Definition value-range.h:357
virtual bool union_(const vrange &) override
Definition value-range.cc:1848
virtual void set_nonnegative(tree type) override
Definition value-range.cc:500
bool snap(const wide_int &, const wide_int &, wide_int &, wide_int &, bool &)
Definition value-range.cc:2375
void maybe_resize(int needed)
Definition value-range.h:710
bool union_append(const irange &r)
Definition value-range.cc:1810
virtual void set_varying(tree type) override
Definition value-range.h:1142
virtual tree lbound() const override
Definition value-range.cc:2622
bool intersect_bitmask(const irange &r)
Definition value-range.cc:2565
tree m_type
Definition value-range.h:358
virtual bool contains_p(tree cst) const override
Definition value-range.h:1052
virtual bool intersect(const vrange &) override
Definition value-range.cc:2038
bool nonnegative_p() const
Definition value-range.cc:474
virtual irange_bitmask get_bitmask() const override
Definition value-range.cc:2505
wide_int * m_base
Definition value-range.h:361
static const int HARD_MAX_RANGES
Definition value-range.h:343
bool operator==(const irange &) const
Definition value-range.cc:1652
virtual bool fits_p(const vrange &r) const override
Definition value-range.cc:494
void set(tree type, const wide_int &, const wide_int &, value_range_kind=VR_RANGE)
Definition value-range.cc:1528
unsigned char m_num_ranges
Definition value-range.h:355
virtual void accept(const vrange_visitor &v) const override
Definition value-range.cc:146
bool irange_single_pair_union(const irange &r)
Definition value-range.cc:1743
virtual bool singleton_p(tree *result=NULL) const override
Definition value-range.cc:1689
static bool supports_p(const_tree type)
Definition value-range.h:1046
wide_int upper_bound() const
Definition value-range.h:1185
wide_int lower_bound(unsigned=0) const
Definition value-range.h:1164
irange_bitmask m_bitmask
Definition value-range.h:359
virtual void set_undefined() override
Definition value-range.h:1135
virtual tree ubound() const override
Definition value-range.cc:2628
bool nonpositive_p() const
Definition value-range.cc:480
irange & operator=(const irange &)
Definition value-range.cc:1407
friend class vrange_printer
Definition value-range.h:278
virtual void set_zero(tree type) override
Definition value-range.h:1221
virtual void update_bitmask(const class irange_bitmask &) override
Definition value-range.cc:2482
bool contains_p(const wide_int &) const
Definition value-range.cc:1718
bool set_range_from_bitmask()
Definition value-range.cc:2465
bool irange_contains_p(const irange &) const
Definition value-range.cc:1987
bool varying_compatible_p() const
Definition value-range.h:994
virtual tree type() const override
Definition value-range.h:987
void normalize_kind()
Definition value-range.h:1230
bool snap_subranges()
Definition value-range.cc:2426
wide_int upper_bound(unsigned) const
Definition value-range.h:1175
bool operator!=(const irange &r) const
Definition value-range.h:319
irange(wide_int *, unsigned nranges, bool resizable)
Definition value-range.h:1072
virtual void verify_range() const override
Definition value-range.cc:1605
Definition value-range.h:479
bool neg_p() const
Definition value-range.h:522
bool m_neg_nan
Definition value-range.h:487
bool pos_p() const
Definition value-range.h:514
bool m_pos_nan
Definition value-range.h:486
nan_state(bool)
Definition value-range.h:494
Definition value-range.h:390
virtual bool supports_type_p(const_tree type) const final override
Definition value-range.h:1305
wide_int m_min
Definition value-range.h:434
virtual bool intersect(const vrange &v) final override
Definition value-range.cc:645
virtual void set_nonnegative(tree type) final override
Definition value-range.cc:516
void invert()
Definition value-range.cc:723
prange()
Definition value-range.h:1270
virtual void verify_range() const final override
Definition value-range.cc:755
virtual tree lbound() const final override
Definition value-range.cc:593
wide_int upper_bound() const
Definition value-range.h:1388
irange_bitmask get_bitmask() const final override
Definition value-range.h:1402
wide_int m_max
Definition value-range.h:435
virtual bool contains_p(tree cst) const final override
Definition value-range.h:1356
tree m_type
Definition value-range.h:433
bool varying_compatible_p() const
Definition value-range.h:1395
virtual void set_varying(tree type) final override
Definition value-range.h:1317
static bool supports_p(const_tree type)
Definition value-range.h:1299
virtual void set_zero(tree type) final override
Definition value-range.h:1343
wide_int lower_bound() const
Definition value-range.h:1381
virtual bool fits_p(const vrange &v) const final override
Definition value-range.h:1408
virtual bool zero_p() const final override
Definition value-range.h:1362
virtual void set_undefined() final override
Definition value-range.h:1311
void update_bitmask(const irange_bitmask &) final override
Definition value-range.cc:774
virtual void set_nonzero(tree type) final override
Definition value-range.h:1330
virtual bool nonzero_p() const final override
Definition value-range.h:1368
friend class vrange_printer
Definition value-range.h:392
friend class prange_storage
Definition value-range.h:391
virtual bool singleton_p(tree *result=NULL) const final override
Definition value-range.cc:581
virtual tree ubound() const final override
Definition value-range.cc:599
virtual tree type() const final override
Definition value-range.h:1374
virtual void set(tree, tree, value_range_kind=VR_RANGE) final override
Definition value-range.cc:524
virtual bool union_(const vrange &v) final override
Definition value-range.cc:605
irange_bitmask m_bitmask
Definition value-range.h:436
Definition value-range.h:443
unsupported_range & operator=(const unsupported_range &r)
Definition value-range.cc:310
unsupported_range(const unsupported_range &src)
Definition value-range.h:450
unsupported_range()
Definition value-range.h:445
Definition value-range.h:764
void verify_range() const
Definition value-range.h:803
void set_zero(tree type)
Definition value-range.h:792
~value_range()
Definition value-range.h:865
bool undefined_p() const
Definition value-range.h:784
bool contains_p(tree cst) const
Definition value-range.h:789
static bool supports_type_p(const_tree type)
Definition value-range.h:965
void accept(const vrange_visitor &v) const
Definition value-range.h:802
bool nonzero_p() const
Definition value-range.h:795
bool varying_p() const
Definition value-range.h:783
vrange * m_vrange
Definition value-range.h:808
tree type()
Definition value-range.h:782
irange_bitmask get_bitmask() const
Definition value-range.h:799
tree ubound() const
Definition value-range.h:798
value_range()
Definition value-range.h:823
bool intersect(const vrange &r)
Definition value-range.h:788
void update_bitmask(const class irange_bitmask &bm)
Definition value-range.h:800
bool union_(const vrange &r)
Definition value-range.h:787
void set_nonzero(tree type)
Definition value-range.h:793
void set_type(tree type)
Definition value-range.h:875
void set_undefined()
Definition value-range.h:786
bool zero_p() const
Definition value-range.h:796
bool operator!=(const value_range &r) const
Definition value-range.h:945
bool singleton_p(tree *result=NULL) const
Definition value-range.h:790
tree lbound() const
Definition value-range.h:797
void set_varying(tree type)
Definition value-range.h:785
vrange & operator=(const vrange &)
Definition value-range.h:921
union value_range::buffer_type m_buffer
bool operator==(const value_range &r) const
Definition value-range.h:939
void init(tree type)
Definition value-range.h:886
Definition value-range.h:741
virtual void visit(const unsupported_range &) const
Definition value-range.h:746
virtual void visit(const irange &) const
Definition value-range.h:743
virtual void visit(const frange &) const
Definition value-range.h:745
virtual void visit(const prange &) const
Definition value-range.h:744
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:188
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:1022
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:183
virtual tree ubound() const =0
friend bool is_a(vrange &)
Definition value-range.h:645
void set_nonzero_bits(const wide_int &bits)
Definition value-range.cc:2544
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:337
virtual tree lbound() const =0
virtual tree type() const =0
void dump(FILE *) const
Definition value-range.cc:370
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:2554
virtual bool fits_p(const vrange &r) const =0
bool varying_p() const
Definition value-range.h:1016
bool operator==(const vrange &) const
Definition value-range.cc:356
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:114
REAL_VALUE_TYPE dconstinf
Definition emit-rtl.cc:113
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:4345
void add_vrange(const vrange &v, inchash::hash &hstate, unsigned int)
Definition value-range.cc:407
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:6537
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: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: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:2778
#define DECIMAL_FLOAT_TYPE_P(TYPE)
Definition tree.h:681
#define TYPE_PRECISION(NODE)
Definition tree.h:2360
#define SCALAR_FLOAT_TYPE_P(TYPE)
Definition tree.h:649
#define TREE_REAL_CST_PTR(NODE)
Definition tree.h:1174
#define TYPE_UNSIGNED(NODE)
Definition tree.h:963
#define TYPE_MODE(NODE)
Definition tree.h:2369
#define TYPE_SIGN(NODE)
Definition tree.h:966
#define POINTER_TYPE_P(TYPE)
Definition tree.h:701
#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:4531
unsupported_range unsupported
Definition value-range.h:812
buffer_type()
Definition value-range.h:814
prange pointers
Definition value-range.h:813
~buffer_type()
Definition value-range.h:815
frange floats
Definition value-range.h:811
int_range_max ints
Definition value-range.h:810
T & as_a(vrange &v)
Definition value-range.h:662
REAL_VALUE_TYPE frange_val_max(const_tree type)
Definition value-range.h:1586
bool range_includes_zero_p(const vrange &vr)
Definition value-range.h:1058
wide_int irange_val_max(const_tree type)
Definition value-range.h:1263
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:2641
bool is_a< prange >(vrange &v)
Definition value-range.h:687
bool is_a< unsupported_range >(vrange &v)
Definition value-range.h:701
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:1565
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:738
value_range_kind get_legacy_range(const vrange &, tree &min, tree &max)
Definition value-range.cc:1510
bool is_a< frange >(vrange &v)
Definition value-range.h:694
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:1551
wide_int irange_val_min(const_tree type)
Definition value-range.h:1256
bool range_compatible_p(tree type1, tree type2)
Definition value-range.h:1797
bool frange_val_is_min(const REAL_VALUE_TYPE &r, const_tree type)
Definition value-range.h:1597
bool contains_zero_p(const irange &r)
Definition value-range.h:1246
bool frange_val_is_max(const REAL_VALUE_TYPE &r, const_tree type)
Definition value-range.h:1606
bool vrp_operand_equal_p(const_tree, const_tree)
Definition value-range.cc:2662
REAL_VALUE_TYPE frange_val_min(const_tree type)
Definition value-range.h:1575
bool is_a< irange >(vrange &v)
Definition value-range.h:680
generic_wide_int< wide_int_storage > wide_int
Definition wide-int.h:343