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