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