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