]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/value-range.h
check undefine_p for one more vr
[thirdparty/gcc.git] / gcc / value-range.h
1 /* Support routines for value ranges.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew Macleod <amacleod@redhat.com>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along 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
25 class irange;
26
27 // Types of value ranges.
28 enum value_range_kind
29 {
30 /* Empty range. */
31 VR_UNDEFINED,
32 /* Range spans the entire domain. */
33 VR_VARYING,
34 /* Range is [MIN, MAX]. */
35 VR_RANGE,
36 /* Range is ~[MIN, MAX]. */
37 VR_ANTI_RANGE,
38 /* Range is a NAN. */
39 VR_NAN,
40 /* Range is a nice guy. */
41 VR_LAST
42 };
43
44 // Discriminator between different vrange types.
45
46 enum value_range_discriminator
47 {
48 // Range holds an integer or pointer.
49 VR_IRANGE,
50 // Floating point range.
51 VR_FRANGE,
52 // Range holds an unsupported type.
53 VR_UNKNOWN
54 };
55
56 // Abstract class for ranges of any of the supported types.
57 //
58 // To query what types ranger and the entire ecosystem can support,
59 // use Value_Range::supports_type_p(tree type). This is a static
60 // method available independently of any vrange object.
61 //
62 // To query what a given vrange variant can support, use:
63 // irange::supports_p ()
64 // frange::supports_p ()
65 // etc
66 //
67 // To query what a range object can support, use:
68 // void foo (vrange &v, irange &i, frange &f)
69 // {
70 // if (v.supports_type_p (type)) ...
71 // if (i.supports_type_p (type)) ...
72 // if (f.supports_type_p (type)) ...
73 // }
74
75 class GTY((user)) vrange
76 {
77 template <typename T> friend bool is_a (vrange &);
78 friend class Value_Range;
79 friend void streamer_write_vrange (struct output_block *, const vrange &);
80 friend class range_op_handler;
81 public:
82 virtual void accept (const class vrange_visitor &v) const = 0;
83 virtual void set (tree, tree, value_range_kind = VR_RANGE);
84 virtual tree type () const;
85 virtual bool supports_type_p (const_tree type) const;
86 virtual void set_varying (tree type);
87 virtual void set_undefined ();
88 virtual bool union_ (const vrange &);
89 virtual bool intersect (const vrange &);
90 virtual bool singleton_p (tree *result = NULL) const;
91 virtual bool contains_p (tree cst) const;
92 virtual bool zero_p () const;
93 virtual bool nonzero_p () const;
94 virtual void set_nonzero (tree type);
95 virtual void set_zero (tree type);
96 virtual void set_nonnegative (tree type);
97 virtual bool fits_p (const vrange &r) const;
98
99 bool varying_p () const;
100 bool undefined_p () const;
101 vrange& operator= (const vrange &);
102 bool operator== (const vrange &) const;
103 bool operator!= (const vrange &r) const { return !(*this == r); }
104 void dump (FILE *) const;
105 protected:
106 vrange (enum value_range_discriminator d) : m_discriminator (d) { }
107 ENUM_BITFIELD(value_range_kind) m_kind : 8;
108 const ENUM_BITFIELD(value_range_discriminator) m_discriminator : 4;
109 };
110
111 namespace inchash
112 {
113 extern void add_vrange (const vrange &, hash &, unsigned flags = 0);
114 }
115
116 // A pair of values representing the known bits in a range. Zero bits
117 // in MASK cover constant values. Set bits in MASK cover unknown
118 // values. VALUE are the known bits.
119 //
120 // Set bits in MASK (no meaningful information) must have their
121 // corresponding bits in VALUE cleared, as this speeds up union and
122 // intersect.
123
124 class irange_bitmask
125 {
126 public:
127 irange_bitmask () { /* uninitialized */ }
128 irange_bitmask (unsigned prec) { set_unknown (prec); }
129 irange_bitmask (const wide_int &value, const wide_int &mask);
130 wide_int value () const { return m_value; }
131 wide_int mask () const { return m_mask; }
132 void set_unknown (unsigned prec);
133 bool unknown_p () const;
134 unsigned get_precision () const;
135 bool union_ (const irange_bitmask &src);
136 bool intersect (const irange_bitmask &src);
137 bool operator== (const irange_bitmask &src) const;
138 bool operator!= (const irange_bitmask &src) const { return !(*this == src); }
139 void verify_mask () const;
140 void dump (FILE *) const;
141
142 // Convenience functions for nonzero bitmask compatibility.
143 wide_int get_nonzero_bits () const;
144 void set_nonzero_bits (const wide_int &bits);
145 private:
146 wide_int m_value;
147 wide_int m_mask;
148 };
149
150 inline void
151 irange_bitmask::set_unknown (unsigned prec)
152 {
153 m_value = wi::zero (prec);
154 m_mask = wi::minus_one (prec);
155 if (flag_checking)
156 verify_mask ();
157 }
158
159 // Return TRUE if THIS does not have any meaningful information.
160
161 inline bool
162 irange_bitmask::unknown_p () const
163 {
164 return m_mask == -1;
165 }
166
167 inline
168 irange_bitmask::irange_bitmask (const wide_int &value, const wide_int &mask)
169 {
170 m_value = value;
171 m_mask = mask;
172 if (flag_checking)
173 verify_mask ();
174 }
175
176 inline unsigned
177 irange_bitmask::get_precision () const
178 {
179 return m_mask.get_precision ();
180 }
181
182 // The following two functions are meant for backwards compatability
183 // with the nonzero bitmask. A cleared bit means the value must be 0.
184 // A set bit means we have no information for the bit.
185
186 // Return the nonzero bits.
187 inline wide_int
188 irange_bitmask::get_nonzero_bits () const
189 {
190 return m_value | m_mask;
191 }
192
193 // Set the bitmask to the nonzero bits in BITS.
194 inline void
195 irange_bitmask::set_nonzero_bits (const wide_int &bits)
196 {
197 m_value = wi::zero (bits.get_precision ());
198 m_mask = bits;
199 if (flag_checking)
200 verify_mask ();
201 }
202
203 inline bool
204 irange_bitmask::operator== (const irange_bitmask &src) const
205 {
206 bool unknown1 = unknown_p ();
207 bool unknown2 = src.unknown_p ();
208 if (unknown1 || unknown2)
209 return unknown1 == unknown2;
210 return m_value == src.m_value && m_mask == src.m_mask;
211 }
212
213 inline bool
214 irange_bitmask::union_ (const irange_bitmask &orig_src)
215 {
216 // Normalize mask.
217 irange_bitmask src (orig_src.m_value & ~orig_src.m_mask, orig_src.m_mask);
218 m_value &= ~m_mask;
219
220 irange_bitmask save (*this);
221 m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
222 m_value = m_value & src.m_value;
223 if (flag_checking)
224 verify_mask ();
225 return *this != save;
226 }
227
228 inline bool
229 irange_bitmask::intersect (const irange_bitmask &orig_src)
230 {
231 // Normalize mask.
232 irange_bitmask src (orig_src.m_value & ~orig_src.m_mask, orig_src.m_mask);
233 m_value &= ~m_mask;
234
235 irange_bitmask save (*this);
236 // If we have two known bits that are incompatible, the resulting
237 // bit is undefined. It is unclear whether we should set the entire
238 // range to UNDEFINED, or just a subset of it. For now, set the
239 // entire bitmask to unknown (VARYING).
240 if (wi::bit_and (~(m_mask | src.m_mask),
241 m_value ^ src.m_value) != 0)
242 {
243 unsigned prec = m_mask.get_precision ();
244 m_mask = wi::minus_one (prec);
245 m_value = wi::zero (prec);
246 }
247 else
248 {
249 m_mask = m_mask & src.m_mask;
250 m_value = m_value | src.m_value;
251 }
252 if (flag_checking)
253 verify_mask ();
254 return *this != save;
255 }
256
257 // An integer range without any storage.
258
259 class GTY((user)) irange : public vrange
260 {
261 friend value_range_kind get_legacy_range (const irange &, tree &, tree &);
262 friend class irange_storage;
263 friend class vrange_printer;
264 public:
265 // In-place setters.
266 void set (tree type, const wide_int &, const wide_int &,
267 value_range_kind = VR_RANGE);
268 virtual void set_nonzero (tree type) override;
269 virtual void set_zero (tree type) override;
270 virtual void set_nonnegative (tree type) override;
271 virtual void set_varying (tree type) override;
272 virtual void set_undefined () override;
273
274 // Range types.
275 static bool supports_p (const_tree type);
276 virtual bool supports_type_p (const_tree type) const override;
277 virtual tree type () const override;
278
279 // Iteration over sub-ranges.
280 unsigned num_pairs () const;
281 wide_int lower_bound (unsigned = 0) const;
282 wide_int upper_bound (unsigned) const;
283 wide_int upper_bound () const;
284
285 // Predicates.
286 virtual bool zero_p () const override;
287 virtual bool nonzero_p () const override;
288 virtual bool singleton_p (tree *result = NULL) const override;
289 bool singleton_p (wide_int &) const;
290 bool contains_p (const wide_int &) const;
291 bool nonnegative_p () const;
292 bool nonpositive_p () const;
293
294 // In-place operators.
295 virtual bool union_ (const vrange &) override;
296 virtual bool intersect (const vrange &) override;
297 void invert ();
298
299 // Operator overloads.
300 irange& operator= (const irange &);
301 bool operator== (const irange &) const;
302 bool operator!= (const irange &r) const { return !(*this == r); }
303
304 // Misc methods.
305 virtual bool fits_p (const vrange &r) const override;
306 virtual void accept (const vrange_visitor &v) const override;
307
308 void update_bitmask (const irange_bitmask &);
309 irange_bitmask get_bitmask () const;
310 // Nonzero masks.
311 wide_int get_nonzero_bits () const;
312 void set_nonzero_bits (const wide_int &bits);
313
314 protected:
315 void maybe_resize (int needed);
316 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
317 virtual bool contains_p (tree cst) const override;
318 irange (wide_int *, unsigned nranges, bool resizable);
319
320 // In-place operators.
321 bool irange_contains_p (const irange &) const;
322 bool irange_single_pair_union (const irange &r);
323
324 void normalize_kind ();
325
326 void verify_range ();
327
328 // Hard limit on max ranges allowed.
329 static const int HARD_MAX_RANGES = 255;
330 private:
331 friend void gt_ggc_mx (irange *);
332 friend void gt_pch_nx (irange *);
333 friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
334
335 bool varying_compatible_p () const;
336 bool intersect_bitmask (const irange &r);
337 bool union_bitmask (const irange &r);
338 irange_bitmask get_bitmask_from_range () const;
339 bool set_range_from_bitmask ();
340
341 bool intersect (const wide_int& lb, const wide_int& ub);
342 unsigned char m_num_ranges;
343 bool m_resizable;
344 unsigned char m_max_ranges;
345 tree m_type;
346 irange_bitmask m_bitmask;
347 protected:
348 wide_int *m_base;
349 };
350
351 // Here we describe an irange with N pairs of ranges. The storage for
352 // the pairs is embedded in the class as an array.
353 //
354 // If RESIZABLE is true, the storage will be resized on the heap when
355 // the number of ranges needed goes past N up to a max of
356 // HARD_MAX_RANGES. This new storage is freed upon destruction.
357
358 template<unsigned N, bool RESIZABLE = false>
359 class GTY((user)) int_range : public irange
360 {
361 public:
362 int_range ();
363 int_range (tree type, const wide_int &, const wide_int &,
364 value_range_kind = VR_RANGE);
365 int_range (tree type);
366 int_range (const int_range &);
367 int_range (const irange &);
368 virtual ~int_range ();
369 int_range& operator= (const int_range &);
370 protected:
371 int_range (tree, tree, value_range_kind = VR_RANGE);
372 private:
373 wide_int m_ranges[N*2];
374 };
375
376 // Unsupported temporaries may be created by ranger before it's known
377 // they're unsupported, or by vr_values::get_value_range.
378
379 class unsupported_range : public vrange
380 {
381 public:
382 unsupported_range ()
383 : vrange (VR_UNKNOWN)
384 {
385 set_undefined ();
386 }
387 virtual void set_undefined () final override
388 {
389 m_kind = VR_UNDEFINED;
390 }
391 virtual void accept (const vrange_visitor &v) const override;
392 };
393
394 // The NAN state as an opaque object.
395
396 class nan_state
397 {
398 public:
399 nan_state (bool);
400 nan_state (bool pos_nan, bool neg_nan);
401 bool neg_p () const;
402 bool pos_p () const;
403 private:
404 bool m_pos_nan;
405 bool m_neg_nan;
406 };
407
408 // Set NAN state to +-NAN if NAN_P is true. Otherwise set NAN state
409 // to false.
410
411 inline
412 nan_state::nan_state (bool nan_p)
413 {
414 m_pos_nan = nan_p;
415 m_neg_nan = nan_p;
416 }
417
418 // Constructor initializing the object to +NAN if POS_NAN is set, -NAN
419 // if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
420 // NEG_NAN are clear, and the object cannot be a NAN.
421
422 inline
423 nan_state::nan_state (bool pos_nan, bool neg_nan)
424 {
425 m_pos_nan = pos_nan;
426 m_neg_nan = neg_nan;
427 }
428
429 // Return if +NAN is possible.
430
431 inline bool
432 nan_state::pos_p () const
433 {
434 return m_pos_nan;
435 }
436
437 // Return if -NAN is possible.
438
439 inline bool
440 nan_state::neg_p () const
441 {
442 return m_neg_nan;
443 }
444
445 // A floating point range.
446 //
447 // The representation is a type with a couple of endpoints, unioned
448 // with the set of { -NAN, +Nan }.
449
450 class GTY((user)) frange : public vrange
451 {
452 friend class frange_storage;
453 friend class vrange_printer;
454 friend void gt_ggc_mx (frange *);
455 friend void gt_pch_nx (frange *);
456 friend void gt_pch_nx (frange *, gt_pointer_operator, void *);
457 public:
458 frange ();
459 frange (const frange &);
460 frange (tree, tree, value_range_kind = VR_RANGE);
461 frange (tree type);
462 frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
463 value_range_kind = VR_RANGE);
464 static bool supports_p (const_tree type)
465 {
466 // ?? Decimal floats can have multiple representations for the
467 // same number. Supporting them may be as simple as just
468 // disabling them in singleton_p. No clue.
469 return SCALAR_FLOAT_TYPE_P (type) && !DECIMAL_FLOAT_TYPE_P (type);
470 }
471 virtual tree type () const override;
472 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
473 value_range_kind = VR_RANGE);
474 void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
475 const nan_state &, value_range_kind = VR_RANGE);
476 void set_nan (tree type);
477 void set_nan (tree type, bool sign);
478 void set_nan (tree type, const nan_state &);
479 virtual void set_varying (tree type) override;
480 virtual void set_undefined () override;
481 virtual bool union_ (const vrange &) override;
482 virtual bool intersect (const vrange &) override;
483 bool contains_p (const REAL_VALUE_TYPE &) const;
484 virtual bool singleton_p (tree *result = NULL) const override;
485 bool singleton_p (REAL_VALUE_TYPE &r) const;
486 virtual bool supports_type_p (const_tree type) const override;
487 virtual void accept (const vrange_visitor &v) const override;
488 virtual bool zero_p () const override;
489 virtual bool nonzero_p () const override;
490 virtual void set_nonzero (tree type) override;
491 virtual void set_zero (tree type) override;
492 virtual void set_nonnegative (tree type) override;
493 frange& operator= (const frange &);
494 bool operator== (const frange &) const;
495 bool operator!= (const frange &r) const { return !(*this == r); }
496 const REAL_VALUE_TYPE &lower_bound () const;
497 const REAL_VALUE_TYPE &upper_bound () const;
498 nan_state get_nan_state () const;
499 void update_nan ();
500 void update_nan (bool sign);
501 void update_nan (tree) = delete; // Disallow silent conversion to bool.
502 void update_nan (const nan_state &);
503 void clear_nan ();
504 void flush_denormals_to_zero ();
505
506 // fpclassify like API
507 bool known_isfinite () const;
508 bool known_isnan () const;
509 bool known_isinf () const;
510 bool maybe_isnan () const;
511 bool maybe_isnan (bool sign) const;
512 bool maybe_isinf () const;
513 bool signbit_p (bool &signbit) const;
514 bool nan_signbit_p (bool &signbit) const;
515
516 protected:
517 virtual bool contains_p (tree cst) const override;
518 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
519
520 private:
521 bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const;
522 void verify_range ();
523 bool normalize_kind ();
524 bool union_nans (const frange &);
525 bool intersect_nans (const frange &);
526 bool combine_zeros (const frange &, bool union_p);
527
528 tree m_type;
529 REAL_VALUE_TYPE m_min;
530 REAL_VALUE_TYPE m_max;
531 bool m_pos_nan;
532 bool m_neg_nan;
533 };
534
535 inline const REAL_VALUE_TYPE &
536 frange::lower_bound () const
537 {
538 gcc_checking_assert (!undefined_p () && !known_isnan ());
539 return m_min;
540 }
541
542 inline const REAL_VALUE_TYPE &
543 frange::upper_bound () const
544 {
545 gcc_checking_assert (!undefined_p () && !known_isnan ());
546 return m_max;
547 }
548
549 // Return the NAN state.
550
551 inline nan_state
552 frange::get_nan_state () const
553 {
554 return nan_state (m_pos_nan, m_neg_nan);
555 }
556
557 // is_a<> and as_a<> implementation for vrange.
558
559 // Anything we haven't specialized is a hard fail.
560 template <typename T>
561 inline bool
562 is_a (vrange &)
563 {
564 gcc_unreachable ();
565 return false;
566 }
567
568 template <typename T>
569 inline bool
570 is_a (const vrange &v)
571 {
572 // Reuse is_a <vrange> to implement the const version.
573 const T &derived = static_cast<const T &> (v);
574 return is_a <T> (const_cast<T &> (derived));
575 }
576
577 template <typename T>
578 inline T &
579 as_a (vrange &v)
580 {
581 gcc_checking_assert (is_a <T> (v));
582 return static_cast <T &> (v);
583 }
584
585 template <typename T>
586 inline const T &
587 as_a (const vrange &v)
588 {
589 gcc_checking_assert (is_a <T> (v));
590 return static_cast <const T &> (v);
591 }
592
593 // Specializations for the different range types.
594
595 template <>
596 inline bool
597 is_a <irange> (vrange &v)
598 {
599 return v.m_discriminator == VR_IRANGE;
600 }
601
602 template <>
603 inline bool
604 is_a <frange> (vrange &v)
605 {
606 return v.m_discriminator == VR_FRANGE;
607 }
608
609 template <>
610 inline bool
611 is_a <unsupported_range> (vrange &v)
612 {
613 return v.m_discriminator == VR_UNKNOWN;
614 }
615
616 // For resizable ranges, resize the range up to HARD_MAX_RANGES if the
617 // NEEDED pairs is greater than the current capacity of the range.
618
619 inline void
620 irange::maybe_resize (int needed)
621 {
622 if (!m_resizable || m_max_ranges == HARD_MAX_RANGES)
623 return;
624
625 if (needed > m_max_ranges)
626 {
627 m_max_ranges = HARD_MAX_RANGES;
628 wide_int *newmem = new wide_int[m_max_ranges * 2];
629 memcpy (newmem, m_base, sizeof (wide_int) * num_pairs () * 2);
630 m_base = newmem;
631 }
632 }
633
634 template<unsigned N, bool RESIZABLE>
635 inline
636 int_range<N, RESIZABLE>::~int_range ()
637 {
638 if (RESIZABLE && m_base != m_ranges)
639 delete[] m_base;
640 }
641
642 // This is an "infinite" precision irange for use in temporary
643 // calculations. It starts with a sensible default covering 99% of
644 // uses, and goes up to HARD_MAX_RANGES when needed. Any allocated
645 // storage is freed upon destruction.
646 typedef int_range<3, /*RESIZABLE=*/true> int_range_max;
647
648 class vrange_visitor
649 {
650 public:
651 virtual void visit (const irange &) const { }
652 virtual void visit (const frange &) const { }
653 virtual void visit (const unsupported_range &) const { }
654 };
655
656 typedef int_range<2> value_range;
657
658 // This is an "infinite" precision range object for use in temporary
659 // calculations for any of the handled types. The object can be
660 // transparently used as a vrange.
661
662 class Value_Range
663 {
664 public:
665 Value_Range ();
666 Value_Range (const vrange &r);
667 Value_Range (tree type);
668 Value_Range (tree, tree, value_range_kind kind = VR_RANGE);
669 Value_Range (const Value_Range &);
670 void set_type (tree type);
671 vrange& operator= (const vrange &);
672 Value_Range& operator= (const Value_Range &);
673 bool operator== (const Value_Range &r) const;
674 bool operator!= (const Value_Range &r) const;
675 operator vrange &();
676 operator const vrange &() const;
677 void dump (FILE *) const;
678 static bool supports_type_p (const_tree type);
679
680 // Convenience methods for vrange compatibility.
681 tree type () { return m_vrange->type (); }
682 bool varying_p () const { return m_vrange->varying_p (); }
683 bool undefined_p () const { return m_vrange->undefined_p (); }
684 void set_varying (tree type) { init (type); m_vrange->set_varying (type); }
685 void set_undefined () { m_vrange->set_undefined (); }
686 bool union_ (const vrange &r) { return m_vrange->union_ (r); }
687 bool intersect (const vrange &r) { return m_vrange->intersect (r); }
688 bool contains_p (tree cst) const { return m_vrange->contains_p (cst); }
689 bool singleton_p (tree *result = NULL) const
690 { return m_vrange->singleton_p (result); }
691 void set_zero (tree type) { init (type); return m_vrange->set_zero (type); }
692 void set_nonzero (tree type)
693 { init (type); return m_vrange->set_nonzero (type); }
694 bool nonzero_p () const { return m_vrange->nonzero_p (); }
695 bool zero_p () const { return m_vrange->zero_p (); }
696 wide_int lower_bound () const; // For irange/prange comparability.
697 wide_int upper_bound () const; // For irange/prange comparability.
698 void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
699 private:
700 void init (tree type);
701 unsupported_range m_unsupported;
702 vrange *m_vrange;
703 int_range_max m_irange;
704 frange m_frange;
705 };
706
707 inline
708 Value_Range::Value_Range ()
709 {
710 m_vrange = &m_unsupported;
711 }
712
713 // Copy constructor from a vrange.
714
715 inline
716 Value_Range::Value_Range (const vrange &r)
717 {
718 *this = r;
719 }
720
721 // Copy constructor from a TYPE. The range of the temporary is set to
722 // UNDEFINED.
723
724 inline
725 Value_Range::Value_Range (tree type)
726 {
727 init (type);
728 }
729
730 inline
731 Value_Range::Value_Range (tree min, tree max, value_range_kind kind)
732 {
733 init (TREE_TYPE (min));
734 m_vrange->set (min, max, kind);
735 }
736
737 inline
738 Value_Range::Value_Range (const Value_Range &r)
739 {
740 *this = *r.m_vrange;
741 }
742
743 // Initialize object so it is possible to store temporaries of TYPE
744 // into it.
745
746 inline void
747 Value_Range::init (tree type)
748 {
749 gcc_checking_assert (TYPE_P (type));
750
751 if (irange::supports_p (type))
752 m_vrange = &m_irange;
753 else if (frange::supports_p (type))
754 m_vrange = &m_frange;
755 else
756 m_vrange = &m_unsupported;
757 }
758
759 // Set the temporary to allow storing temporaries of TYPE. The range
760 // of the temporary is set to UNDEFINED.
761
762 inline void
763 Value_Range::set_type (tree type)
764 {
765 init (type);
766 m_vrange->set_undefined ();
767 }
768
769 // Assignment operator for temporaries. Copying incompatible types is
770 // allowed.
771
772 inline vrange &
773 Value_Range::operator= (const vrange &r)
774 {
775 if (is_a <irange> (r))
776 {
777 m_irange = as_a <irange> (r);
778 m_vrange = &m_irange;
779 }
780 else if (is_a <frange> (r))
781 {
782 m_frange = as_a <frange> (r);
783 m_vrange = &m_frange;
784 }
785 else if (is_a <unsupported_range> (r))
786 {
787 m_unsupported = as_a <unsupported_range> (r);
788 m_vrange = &m_unsupported;
789 }
790 else
791 gcc_unreachable ();
792
793 return *m_vrange;
794 }
795
796 inline Value_Range &
797 Value_Range::operator= (const Value_Range &r)
798 {
799 if (r.m_vrange == &r.m_irange)
800 {
801 m_irange = r.m_irange;
802 m_vrange = &m_irange;
803 }
804 else if (r.m_vrange == &r.m_frange)
805 {
806 m_frange = r.m_frange;
807 m_vrange = &m_frange;
808 }
809 else if (r.m_vrange == &r.m_unsupported)
810 {
811 m_unsupported = r.m_unsupported;
812 m_vrange = &m_unsupported;
813 }
814 else
815 gcc_unreachable ();
816
817 return *this;
818 }
819
820 inline bool
821 Value_Range::operator== (const Value_Range &r) const
822 {
823 return *m_vrange == *r.m_vrange;
824 }
825
826 inline bool
827 Value_Range::operator!= (const Value_Range &r) const
828 {
829 return *m_vrange != *r.m_vrange;
830 }
831
832 inline
833 Value_Range::operator vrange &()
834 {
835 return *m_vrange;
836 }
837
838 inline
839 Value_Range::operator const vrange &() const
840 {
841 return *m_vrange;
842 }
843
844 // Return TRUE if TYPE is supported by the vrange infrastructure.
845
846 inline bool
847 Value_Range::supports_type_p (const_tree type)
848 {
849 return irange::supports_p (type) || frange::supports_p (type);
850 }
851
852 extern value_range_kind get_legacy_range (const irange &, tree &min, tree &max);
853 extern void dump_value_range (FILE *, const vrange *);
854 extern bool vrp_operand_equal_p (const_tree, const_tree);
855 inline REAL_VALUE_TYPE frange_val_min (const_tree type);
856 inline REAL_VALUE_TYPE frange_val_max (const_tree type);
857
858 // Number of sub-ranges in a range.
859
860 inline unsigned
861 irange::num_pairs () const
862 {
863 return m_num_ranges;
864 }
865
866 inline tree
867 irange::type () const
868 {
869 gcc_checking_assert (m_num_ranges > 0);
870 return m_type;
871 }
872
873 inline bool
874 irange::varying_compatible_p () const
875 {
876 if (m_num_ranges != 1)
877 return false;
878
879 const wide_int &l = m_base[0];
880 const wide_int &u = m_base[1];
881 tree t = m_type;
882
883 if (m_kind == VR_VARYING && t == error_mark_node)
884 return true;
885
886 unsigned prec = TYPE_PRECISION (t);
887 signop sign = TYPE_SIGN (t);
888 if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
889 return (l == wi::min_value (prec, sign)
890 && u == wi::max_value (prec, sign)
891 && m_bitmask.unknown_p ());
892 return true;
893 }
894
895 inline bool
896 vrange::varying_p () const
897 {
898 return m_kind == VR_VARYING;
899 }
900
901 inline bool
902 vrange::undefined_p () const
903 {
904 return m_kind == VR_UNDEFINED;
905 }
906
907 inline bool
908 irange::zero_p () const
909 {
910 return (m_kind == VR_RANGE && m_num_ranges == 1
911 && lower_bound (0) == 0
912 && upper_bound (0) == 0);
913 }
914
915 inline bool
916 irange::nonzero_p () const
917 {
918 if (undefined_p ())
919 return false;
920
921 wide_int zero = wi::zero (TYPE_PRECISION (type ()));
922 return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
923 }
924
925 inline bool
926 irange::supports_p (const_tree type)
927 {
928 return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
929 }
930
931 inline bool
932 irange::contains_p (tree cst) const
933 {
934 return contains_p (wi::to_wide (cst));
935 }
936
937 inline bool
938 range_includes_zero_p (const irange *vr)
939 {
940 if (vr->undefined_p ())
941 return false;
942
943 if (vr->varying_p ())
944 return true;
945
946 wide_int zero = wi::zero (TYPE_PRECISION (vr->type ()));
947 return vr->contains_p (zero);
948 }
949
950 extern void gt_ggc_mx (vrange *);
951 extern void gt_pch_nx (vrange *);
952 extern void gt_pch_nx (vrange *, gt_pointer_operator, void *);
953 extern void gt_ggc_mx (irange *);
954 extern void gt_pch_nx (irange *);
955 extern void gt_pch_nx (irange *, gt_pointer_operator, void *);
956 extern void gt_ggc_mx (frange *);
957 extern void gt_pch_nx (frange *);
958 extern void gt_pch_nx (frange *, gt_pointer_operator, void *);
959
960 template<unsigned N>
961 inline void
962 gt_ggc_mx (int_range<N> *x)
963 {
964 gt_ggc_mx ((irange *) x);
965 }
966
967 template<unsigned N>
968 inline void
969 gt_pch_nx (int_range<N> *x)
970 {
971 gt_pch_nx ((irange *) x);
972 }
973
974 template<unsigned N>
975 inline void
976 gt_pch_nx (int_range<N> *x, gt_pointer_operator op, void *cookie)
977 {
978 gt_pch_nx ((irange *) x, op, cookie);
979 }
980
981 // Constructors for irange
982
983 inline
984 irange::irange (wide_int *base, unsigned nranges, bool resizable)
985 : vrange (VR_IRANGE),
986 m_resizable (resizable),
987 m_max_ranges (nranges)
988 {
989 m_base = base;
990 set_undefined ();
991 }
992
993 // Constructors for int_range<>.
994
995 template<unsigned N, bool RESIZABLE>
996 inline
997 int_range<N, RESIZABLE>::int_range ()
998 : irange (m_ranges, N, RESIZABLE)
999 {
1000 }
1001
1002 template<unsigned N, bool RESIZABLE>
1003 int_range<N, RESIZABLE>::int_range (const int_range &other)
1004 : irange (m_ranges, N, RESIZABLE)
1005 {
1006 irange::operator= (other);
1007 }
1008
1009 template<unsigned N, bool RESIZABLE>
1010 int_range<N, RESIZABLE>::int_range (tree min, tree max, value_range_kind kind)
1011 : irange (m_ranges, N, RESIZABLE)
1012 {
1013 irange::set (min, max, kind);
1014 }
1015
1016 template<unsigned N, bool RESIZABLE>
1017 int_range<N, RESIZABLE>::int_range (tree type)
1018 : irange (m_ranges, N, RESIZABLE)
1019 {
1020 set_varying (type);
1021 }
1022
1023 template<unsigned N, bool RESIZABLE>
1024 int_range<N, RESIZABLE>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
1025 value_range_kind kind)
1026 : irange (m_ranges, N, RESIZABLE)
1027 {
1028 set (type, wmin, wmax, kind);
1029 }
1030
1031 template<unsigned N, bool RESIZABLE>
1032 int_range<N, RESIZABLE>::int_range (const irange &other)
1033 : irange (m_ranges, N, RESIZABLE)
1034 {
1035 irange::operator= (other);
1036 }
1037
1038 template<unsigned N, bool RESIZABLE>
1039 int_range<N, RESIZABLE>&
1040 int_range<N, RESIZABLE>::operator= (const int_range &src)
1041 {
1042 irange::operator= (src);
1043 return *this;
1044 }
1045
1046 inline void
1047 irange::set_undefined ()
1048 {
1049 m_kind = VR_UNDEFINED;
1050 m_num_ranges = 0;
1051 }
1052
1053 inline void
1054 irange::set_varying (tree type)
1055 {
1056 m_kind = VR_VARYING;
1057 m_num_ranges = 1;
1058 m_bitmask.set_unknown (TYPE_PRECISION (type));
1059
1060 if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
1061 {
1062 m_type = type;
1063 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
1064 // min_value and max_value.
1065 m_base[0] = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1066 m_base[1] = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1067 }
1068 else
1069 m_type = error_mark_node;
1070 }
1071
1072 // Return the lower bound of a sub-range. PAIR is the sub-range in
1073 // question.
1074
1075 inline wide_int
1076 irange::lower_bound (unsigned pair) const
1077 {
1078 gcc_checking_assert (m_num_ranges > 0);
1079 gcc_checking_assert (pair + 1 <= num_pairs ());
1080 return m_base[pair * 2];
1081 }
1082
1083 // Return the upper bound of a sub-range. PAIR is the sub-range in
1084 // question.
1085
1086 inline wide_int
1087 irange::upper_bound (unsigned pair) const
1088 {
1089 gcc_checking_assert (m_num_ranges > 0);
1090 gcc_checking_assert (pair + 1 <= num_pairs ());
1091 return m_base[pair * 2 + 1];
1092 }
1093
1094 // Return the highest bound of a range.
1095
1096 inline wide_int
1097 irange::upper_bound () const
1098 {
1099 unsigned pairs = num_pairs ();
1100 gcc_checking_assert (pairs > 0);
1101 return upper_bound (pairs - 1);
1102 }
1103
1104 // Set value range VR to a nonzero range of type TYPE.
1105
1106 inline void
1107 irange::set_nonzero (tree type)
1108 {
1109 unsigned prec = TYPE_PRECISION (type);
1110
1111 if (TYPE_UNSIGNED (type))
1112 {
1113 m_type = type;
1114 m_kind = VR_RANGE;
1115 m_base[0] = wi::one (prec);
1116 m_base[1] = wi::minus_one (prec);
1117 m_bitmask.set_unknown (prec);
1118 m_num_ranges = 1;
1119
1120 if (flag_checking)
1121 verify_range ();
1122 }
1123 else
1124 {
1125 wide_int zero = wi::zero (prec);
1126 set (type, zero, zero, VR_ANTI_RANGE);
1127 }
1128 }
1129
1130 // Set value range VR to a ZERO range of type TYPE.
1131
1132 inline void
1133 irange::set_zero (tree type)
1134 {
1135 wide_int zero = wi::zero (TYPE_PRECISION (type));
1136 set (type, zero, zero);
1137 }
1138
1139 // Normalize a range to VARYING or UNDEFINED if possible.
1140
1141 inline void
1142 irange::normalize_kind ()
1143 {
1144 if (m_num_ranges == 0)
1145 set_undefined ();
1146 else if (varying_compatible_p ())
1147 {
1148 if (m_kind == VR_RANGE)
1149 m_kind = VR_VARYING;
1150 else if (m_kind == VR_ANTI_RANGE)
1151 set_undefined ();
1152 }
1153 if (flag_checking)
1154 verify_range ();
1155 }
1156
1157 inline bool
1158 contains_zero_p (const irange &r)
1159 {
1160 if (r.undefined_p ())
1161 return false;
1162
1163 wide_int zero = wi::zero (TYPE_PRECISION (r.type ()));
1164 return r.contains_p (zero);
1165 }
1166
1167 inline wide_int
1168 irange_val_min (const_tree type)
1169 {
1170 gcc_checking_assert (irange::supports_p (type));
1171 return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1172 }
1173
1174 inline wide_int
1175 irange_val_max (const_tree type)
1176 {
1177 gcc_checking_assert (irange::supports_p (type));
1178 return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1179 }
1180
1181 inline
1182 frange::frange ()
1183 : vrange (VR_FRANGE)
1184 {
1185 set_undefined ();
1186 }
1187
1188 inline
1189 frange::frange (const frange &src)
1190 : vrange (VR_FRANGE)
1191 {
1192 *this = src;
1193 }
1194
1195 inline
1196 frange::frange (tree type)
1197 : vrange (VR_FRANGE)
1198 {
1199 set_varying (type);
1200 }
1201
1202 // frange constructor from REAL_VALUE_TYPE endpoints.
1203
1204 inline
1205 frange::frange (tree type,
1206 const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
1207 value_range_kind kind)
1208 : vrange (VR_FRANGE)
1209 {
1210 set (type, min, max, kind);
1211 }
1212
1213 // frange constructor from trees.
1214
1215 inline
1216 frange::frange (tree min, tree max, value_range_kind kind)
1217 : vrange (VR_FRANGE)
1218 {
1219 set (min, max, kind);
1220 }
1221
1222 inline tree
1223 frange::type () const
1224 {
1225 gcc_checking_assert (!undefined_p ());
1226 return m_type;
1227 }
1228
1229 inline void
1230 frange::set_varying (tree type)
1231 {
1232 m_kind = VR_VARYING;
1233 m_type = type;
1234 m_min = frange_val_min (type);
1235 m_max = frange_val_max (type);
1236 if (HONOR_NANS (m_type))
1237 {
1238 m_pos_nan = true;
1239 m_neg_nan = true;
1240 }
1241 else
1242 {
1243 m_pos_nan = false;
1244 m_neg_nan = false;
1245 }
1246 }
1247
1248 inline void
1249 frange::set_undefined ()
1250 {
1251 m_kind = VR_UNDEFINED;
1252 m_type = NULL;
1253 m_pos_nan = false;
1254 m_neg_nan = false;
1255 // m_min and m_min are uninitialized as they are REAL_VALUE_TYPE ??.
1256 if (flag_checking)
1257 verify_range ();
1258 }
1259
1260 // Set the NAN bits to NAN and adjust the range.
1261
1262 inline void
1263 frange::update_nan (const nan_state &nan)
1264 {
1265 gcc_checking_assert (!undefined_p ());
1266 if (HONOR_NANS (m_type))
1267 {
1268 m_pos_nan = nan.pos_p ();
1269 m_neg_nan = nan.neg_p ();
1270 normalize_kind ();
1271 if (flag_checking)
1272 verify_range ();
1273 }
1274 }
1275
1276 // Set the NAN bit to +-NAN.
1277
1278 inline void
1279 frange::update_nan ()
1280 {
1281 gcc_checking_assert (!undefined_p ());
1282 nan_state nan (true);
1283 update_nan (nan);
1284 }
1285
1286 // Like above, but set the sign of the NAN.
1287
1288 inline void
1289 frange::update_nan (bool sign)
1290 {
1291 gcc_checking_assert (!undefined_p ());
1292 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1293 update_nan (nan);
1294 }
1295
1296 inline bool
1297 frange::contains_p (tree cst) const
1298 {
1299 return contains_p (*TREE_REAL_CST_PTR (cst));
1300 }
1301
1302 // Clear the NAN bit and adjust the range.
1303
1304 inline void
1305 frange::clear_nan ()
1306 {
1307 gcc_checking_assert (!undefined_p ());
1308 m_pos_nan = false;
1309 m_neg_nan = false;
1310 normalize_kind ();
1311 if (flag_checking)
1312 verify_range ();
1313 }
1314
1315 // Set R to maximum representable value for TYPE.
1316
1317 inline REAL_VALUE_TYPE
1318 real_max_representable (const_tree type)
1319 {
1320 REAL_VALUE_TYPE r;
1321 char buf[128];
1322 get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type)),
1323 buf, sizeof (buf), false);
1324 int res = real_from_string (&r, buf);
1325 gcc_checking_assert (!res);
1326 return r;
1327 }
1328
1329 // Return the minimum representable value for TYPE.
1330
1331 inline REAL_VALUE_TYPE
1332 real_min_representable (const_tree type)
1333 {
1334 REAL_VALUE_TYPE r = real_max_representable (type);
1335 r = real_value_negate (&r);
1336 return r;
1337 }
1338
1339 // Return the minimum value for TYPE.
1340
1341 inline REAL_VALUE_TYPE
1342 frange_val_min (const_tree type)
1343 {
1344 if (HONOR_INFINITIES (type))
1345 return dconstninf;
1346 else
1347 return real_min_representable (type);
1348 }
1349
1350 // Return the maximum value for TYPE.
1351
1352 inline REAL_VALUE_TYPE
1353 frange_val_max (const_tree type)
1354 {
1355 if (HONOR_INFINITIES (type))
1356 return dconstinf;
1357 else
1358 return real_max_representable (type);
1359 }
1360
1361 // Return TRUE if R is the minimum value for TYPE.
1362
1363 inline bool
1364 frange_val_is_min (const REAL_VALUE_TYPE &r, const_tree type)
1365 {
1366 REAL_VALUE_TYPE min = frange_val_min (type);
1367 return real_identical (&min, &r);
1368 }
1369
1370 // Return TRUE if R is the max value for TYPE.
1371
1372 inline bool
1373 frange_val_is_max (const REAL_VALUE_TYPE &r, const_tree type)
1374 {
1375 REAL_VALUE_TYPE max = frange_val_max (type);
1376 return real_identical (&max, &r);
1377 }
1378
1379 // Build a NAN with a state of NAN.
1380
1381 inline void
1382 frange::set_nan (tree type, const nan_state &nan)
1383 {
1384 gcc_checking_assert (nan.pos_p () || nan.neg_p ());
1385 if (HONOR_NANS (type))
1386 {
1387 m_kind = VR_NAN;
1388 m_type = type;
1389 m_neg_nan = nan.neg_p ();
1390 m_pos_nan = nan.pos_p ();
1391 if (flag_checking)
1392 verify_range ();
1393 }
1394 else
1395 set_undefined ();
1396 }
1397
1398 // Build a signless NAN of type TYPE.
1399
1400 inline void
1401 frange::set_nan (tree type)
1402 {
1403 nan_state nan (true);
1404 set_nan (type, nan);
1405 }
1406
1407 // Build a NAN of type TYPE with SIGN.
1408
1409 inline void
1410 frange::set_nan (tree type, bool sign)
1411 {
1412 nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1413 set_nan (type, nan);
1414 }
1415
1416 // Return TRUE if range is known to be finite.
1417
1418 inline bool
1419 frange::known_isfinite () const
1420 {
1421 if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
1422 return false;
1423 return (!maybe_isnan () && !real_isinf (&m_min) && !real_isinf (&m_max));
1424 }
1425
1426 // Return TRUE if range may be infinite.
1427
1428 inline bool
1429 frange::maybe_isinf () const
1430 {
1431 if (undefined_p () || m_kind == VR_ANTI_RANGE || m_kind == VR_NAN)
1432 return false;
1433 if (varying_p ())
1434 return true;
1435 return real_isinf (&m_min) || real_isinf (&m_max);
1436 }
1437
1438 // Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
1439
1440 inline bool
1441 frange::known_isinf () const
1442 {
1443 return (m_kind == VR_RANGE
1444 && !maybe_isnan ()
1445 && real_identical (&m_min, &m_max)
1446 && real_isinf (&m_min));
1447 }
1448
1449 // Return TRUE if range is possibly a NAN.
1450
1451 inline bool
1452 frange::maybe_isnan () const
1453 {
1454 if (undefined_p ())
1455 return false;
1456 return m_pos_nan || m_neg_nan;
1457 }
1458
1459 // Return TRUE if range is possibly a NAN with SIGN.
1460
1461 inline bool
1462 frange::maybe_isnan (bool sign) const
1463 {
1464 if (undefined_p ())
1465 return false;
1466 if (sign)
1467 return m_neg_nan;
1468 return m_pos_nan;
1469 }
1470
1471 // Return TRUE if range is a +NAN or -NAN.
1472
1473 inline bool
1474 frange::known_isnan () const
1475 {
1476 return m_kind == VR_NAN;
1477 }
1478
1479 // If the signbit for the range is known, set it in SIGNBIT and return
1480 // TRUE.
1481
1482 inline bool
1483 frange::signbit_p (bool &signbit) const
1484 {
1485 if (undefined_p ())
1486 return false;
1487
1488 // NAN with unknown sign.
1489 if (m_pos_nan && m_neg_nan)
1490 return false;
1491 // No NAN.
1492 if (!m_pos_nan && !m_neg_nan)
1493 {
1494 if (m_min.sign == m_max.sign)
1495 {
1496 signbit = m_min.sign;
1497 return true;
1498 }
1499 return false;
1500 }
1501 // NAN with known sign.
1502 bool nan_sign = m_neg_nan;
1503 if (known_isnan ()
1504 || (nan_sign == m_min.sign && nan_sign == m_max.sign))
1505 {
1506 signbit = nan_sign;
1507 return true;
1508 }
1509 return false;
1510 }
1511
1512 // If range has a NAN with a known sign, set it in SIGNBIT and return
1513 // TRUE.
1514
1515 inline bool
1516 frange::nan_signbit_p (bool &signbit) const
1517 {
1518 if (undefined_p ())
1519 return false;
1520
1521 if (m_pos_nan == m_neg_nan)
1522 return false;
1523
1524 signbit = m_neg_nan;
1525 return true;
1526 }
1527
1528 void frange_nextafter (enum machine_mode, REAL_VALUE_TYPE &,
1529 const REAL_VALUE_TYPE &);
1530 void frange_arithmetic (enum tree_code, tree, REAL_VALUE_TYPE &,
1531 const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
1532 const REAL_VALUE_TYPE &);
1533
1534 #endif // GCC_VALUE_RANGE_H