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