Line data Source code
1 : /* Support routines for value ranges.
2 : Copyright (C) 2019-2026 Free Software Foundation, Inc.
3 : Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 : Andrew Macleod <amacleod@redhat.com>.
5 :
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 : // Pointer range.
51 : VR_PRANGE,
52 : // Floating point range.
53 : VR_FRANGE,
54 : // Range holds an unsupported type.
55 : VR_UNKNOWN
56 : };
57 :
58 : // Abstract class for representing subsets of values for various
59 : // supported types, such as the possible values of a variable.
60 : //
61 : // There are subclasses for each of integer, floating point, and pointer
62 : // types, each with their own strategies for efficiently representing
63 : // subsets of values.
64 : //
65 : // For efficiency, we can't precisely represent any arbitrary subset
66 : // of values of a type (which could require 2^N bits for a type of size N)
67 : // Hence operations on the subclasses may introduce imprecision
68 : // due to over-approximating the possible subsets.
69 : //
70 : // To query what types ranger and the entire ecosystem can support,
71 : // use value_range::supports_type_p(tree type). This is a static
72 : // method available independently of any vrange object.
73 : //
74 : // To query what a given vrange variant can support, use:
75 : // irange::supports_p ()
76 : // frange::supports_p ()
77 : // etc
78 : //
79 : // To query what a range object can support, use:
80 : // void foo (vrange &v, irange &i, frange &f)
81 : // {
82 : // if (v.supports_type_p (type)) ...
83 : // if (i.supports_type_p (type)) ...
84 : // if (f.supports_type_p (type)) ...
85 : // }
86 :
87 : class vrange
88 : {
89 : template <typename T> friend bool is_a (vrange &);
90 : friend class value_range;
91 : friend void streamer_write_vrange (struct output_block *, const vrange &);
92 : friend class range_op_handler;
93 : public:
94 : virtual void accept (const class vrange_visitor &v) const = 0;
95 : virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
96 : virtual tree type () const = 0;
97 : virtual bool supports_type_p (const_tree type) const = 0;
98 : virtual void set_varying (tree type) = 0;
99 : virtual void set_undefined () = 0;
100 : virtual bool union_ (const vrange &) = 0;
101 : virtual bool intersect (const vrange &) = 0;
102 : virtual bool singleton_p (tree *result = NULL) const = 0;
103 : virtual bool contains_p (tree cst) const = 0;
104 : virtual bool zero_p () const = 0;
105 : // True if val == 0 may hold for some value in the range; for a float
106 : // range that means +0.0 or -0.0.
107 : virtual bool contains_zero_p () const = 0;
108 : virtual void set_nonzero (tree type) = 0;
109 : virtual void set_zero (tree type) = 0;
110 : virtual void set_nonnegative (tree type) = 0;
111 : virtual bool fits_p (const vrange &r) const = 0;
112 5921542906 : virtual ~vrange () { }
113 : virtual tree lbound () const = 0;
114 : virtual tree ubound () const = 0;
115 : virtual void update_bitmask (const class irange_bitmask &);
116 : virtual irange_bitmask get_bitmask () const;
117 : wide_int get_nonzero_bits () const;
118 : void set_nonzero_bits (const wide_int &bits);
119 :
120 : bool varying_p () const;
121 : bool undefined_p () const;
122 : vrange& operator= (const vrange &);
123 : bool operator== (const vrange &) const;
124 14474034 : bool operator!= (const vrange &r) const { return !(*this == r); }
125 : void dump (FILE *) const;
126 0 : virtual void verify_range () const { }
127 : protected:
128 7395010954 : vrange (enum value_range_discriminator d) : m_discriminator (d) { }
129 : enum value_range_kind m_kind : 8;
130 : const enum value_range_discriminator m_discriminator : 4;
131 : };
132 :
133 : namespace inchash
134 : {
135 : extern void add_vrange (const vrange &, hash &, unsigned flags = 0);
136 : }
137 :
138 : // A pair of values representing the known bits of a value. Zero bits
139 : // in MASK cover constant values. Set bits in MASK cover unknown
140 : // values. VALUE are the known bits for the bits where MASK is zero,
141 : // and must be zero for the unknown bits where MASK is set (needed as an
142 : // optimization of union and intersect)
143 : // For example:
144 : // VALUE: [..., 0, 1, 0]
145 : // MASK: [..., 1, 0, 0]
146 : // ^ ^ ^
147 : // | | known bit: {0}
148 : // | known bit: {1}
149 : // unknown bit: {0, 1}
150 :
151 : class irange_bitmask
152 : {
153 : public:
154 7164769001 : irange_bitmask () { /* uninitialized */ }
155 0 : irange_bitmask (unsigned prec) { set_unknown (prec); }
156 : irange_bitmask (const wide_int &value, const wide_int &mask);
157 : irange_bitmask (tree type, const wide_int &min, const wide_int &max);
158 :
159 1694331593 : wide_int value () const { return m_value; }
160 2048732465 : wide_int mask () const { return m_mask; }
161 : void set_unknown (unsigned prec);
162 : bool unknown_p () const;
163 : unsigned get_precision () const;
164 : void union_ (const irange_bitmask &src);
165 : bool intersect (const irange_bitmask &src);
166 : bool operator== (const irange_bitmask &src) const;
167 8755824 : bool operator!= (const irange_bitmask &src) const { return !(*this == src); }
168 : void verify_mask () const;
169 : void dump (FILE *) const;
170 : bool range_from_mask (irange &r, tree type) const;
171 :
172 : bool member_p (const wide_int &val) const;
173 :
174 : // Convenience functions for nonzero bitmask compatibility.
175 : wide_int get_nonzero_bits () const;
176 : void set_nonzero_bits (const wide_int &bits);
177 : private:
178 : wide_int m_value;
179 : wide_int m_mask;
180 : };
181 :
182 : inline void
183 4032766258 : irange_bitmask::set_unknown (unsigned prec)
184 : {
185 4032766258 : m_value = wi::zero (prec);
186 4032766258 : m_mask = wi::minus_one (prec);
187 4032766258 : if (flag_checking)
188 4032753462 : verify_mask ();
189 4032766258 : }
190 :
191 : // Return TRUE if THIS does not have any meaningful information.
192 :
193 : inline bool
194 5655128718 : irange_bitmask::unknown_p () const
195 : {
196 2516559526 : return m_mask == -1;
197 : }
198 :
199 : inline
200 1245212320 : irange_bitmask::irange_bitmask (const wide_int &value, const wide_int &mask)
201 : {
202 1245212320 : m_value = value;
203 1245212320 : m_mask = mask;
204 1245212320 : if (flag_checking)
205 1245208707 : verify_mask ();
206 1245212320 : }
207 :
208 : inline unsigned
209 : irange_bitmask::get_precision () const
210 : {
211 : return m_mask.get_precision ();
212 : }
213 :
214 : // The following two functions are meant for backwards compatibility
215 : // with the nonzero bitmask. A cleared bit means the value must be 0.
216 : // A set bit means we have no information for the bit.
217 :
218 : // Return the nonzero bits.
219 : inline wide_int
220 4745 : irange_bitmask::get_nonzero_bits () const
221 : {
222 4745 : return m_value | m_mask;
223 : }
224 :
225 : // Set the bitmask to the nonzero bits in BITS.
226 : inline void
227 : irange_bitmask::set_nonzero_bits (const wide_int &bits)
228 : {
229 : m_value = wi::zero (bits.get_precision ());
230 : m_mask = bits;
231 : if (flag_checking)
232 : verify_mask ();
233 : }
234 :
235 : // Return TRUE if val could be a valid value with this bitmask.
236 :
237 : inline bool
238 282239529 : irange_bitmask::member_p (const wide_int &val) const
239 : {
240 282239529 : if (unknown_p ())
241 : return true;
242 32918617 : wide_int res = m_mask & val;
243 32918617 : if (m_value != 0)
244 1133934 : res |= ~m_mask & m_value;
245 32918617 : return res == val;
246 32918617 : }
247 :
248 : inline bool
249 1358461685 : irange_bitmask::operator== (const irange_bitmask &src) const
250 : {
251 1358461685 : bool unknown1 = unknown_p ();
252 1358461685 : bool unknown2 = src.unknown_p ();
253 1358461685 : if (unknown1 || unknown2)
254 1038462916 : return unknown1 == unknown2;
255 319998769 : return m_value == src.m_value && m_mask == src.m_mask;
256 : }
257 :
258 : inline void
259 21135408 : irange_bitmask::union_ (const irange_bitmask &src)
260 : {
261 21135994 : m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
262 21135408 : m_value = m_value & src.m_value;
263 21135408 : if (flag_checking)
264 21135408 : verify_mask ();
265 21135408 : }
266 :
267 : // Return FALSE if the bitmask intersection is undefined.
268 :
269 : inline bool
270 872490941 : irange_bitmask::intersect (const irange_bitmask &src)
271 : {
272 : // If we have two known bits that are incompatible, the resulting
273 : // bit and therefore entire range is undefined. Return FALSE.
274 1745121968 : if (wi::bit_and (~(m_mask | src.m_mask),
275 2617472823 : m_value ^ src.m_value) != 0)
276 : return false;
277 : else
278 : {
279 872408788 : m_mask = m_mask & src.m_mask;
280 872408788 : m_value = m_value | src.m_value;
281 : }
282 872408788 : if (flag_checking)
283 872406243 : verify_mask ();
284 : return true;
285 : }
286 :
287 : // A subset of possible values for an integer type, leaving
288 : // allocation of storage to subclasses.
289 :
290 11786046470 : class irange : public vrange
291 : {
292 : friend class irange_storage;
293 : friend class vrange_printer;
294 : public:
295 : // In-place setters.
296 : void set (tree type, const wide_int &, const wide_int &,
297 : value_range_kind = VR_RANGE);
298 : virtual void set_nonzero (tree type) override;
299 : virtual void set_zero (tree type) override;
300 : virtual void set_nonnegative (tree type) override;
301 : virtual void set_varying (tree type) override;
302 : virtual void set_undefined () override;
303 :
304 : // Range types.
305 : static bool supports_p (const_tree type);
306 : virtual bool supports_type_p (const_tree type) const override;
307 : virtual tree type () const override;
308 :
309 : // Iteration over sub-ranges.
310 : unsigned num_pairs () const;
311 : wide_int lower_bound (unsigned = 0) const;
312 : wide_int upper_bound (unsigned) const;
313 : wide_int upper_bound () const;
314 : virtual tree lbound () const override;
315 : virtual tree ubound () const override;
316 :
317 : // Predicates.
318 : virtual bool zero_p () const override;
319 : virtual bool contains_zero_p () const override;
320 : virtual bool singleton_p (tree *result = NULL) const override;
321 : bool singleton_p (wide_int &) const;
322 : bool contains_p (const wide_int &) const;
323 : bool nonnegative_p () const;
324 : bool nonpositive_p () const;
325 :
326 : // In-place operators.
327 : virtual bool union_ (const vrange &) override;
328 : virtual bool intersect (const vrange &) override;
329 : bool invert ();
330 :
331 : // Operator overloads.
332 : irange& operator= (const irange &);
333 : bool operator== (const irange &) const;
334 : bool operator!= (const irange &r) const { return !(*this == r); }
335 :
336 : // Misc methods.
337 : virtual bool fits_p (const vrange &r) const override;
338 : virtual void accept (const vrange_visitor &v) const override;
339 :
340 : virtual void update_bitmask (const class irange_bitmask &) override;
341 : virtual irange_bitmask get_bitmask () const override;
342 :
343 : virtual void verify_range () const override;
344 : protected:
345 : void maybe_resize (int needed);
346 : virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
347 : virtual bool contains_p (tree cst) const override;
348 : irange (wide_int *, unsigned nranges, bool resizable);
349 :
350 : // In-place operators.
351 : bool irange_contains_p (const irange &) const;
352 : bool irange_single_pair_union (const irange &r);
353 :
354 : void normalize_kind ();
355 :
356 :
357 : // Hard limit on max ranges allowed.
358 : static const int HARD_MAX_RANGES = 255;
359 : private:
360 : bool varying_compatible_p () const;
361 : bool intersect_bitmask (const irange &r);
362 : bool union_bitmask (const irange &r);
363 : bool set_range_from_bitmask ();
364 : bool snap_subranges ();
365 : bool snap (const wide_int &, const wide_int &, wide_int &, wide_int &,
366 : bool &);
367 :
368 : bool intersect (const wide_int& lb, const wide_int& ub);
369 : bool union_append (const irange &r);
370 : unsigned char m_num_ranges;
371 : bool m_resizable;
372 : unsigned char m_max_ranges;
373 : tree m_type;
374 : irange_bitmask m_bitmask;
375 : protected:
376 : wide_int *m_base;
377 : };
378 :
379 : // Here we describe an irange with N pairs of ranges. The storage for
380 : // the pairs is embedded in the class as an array.
381 : //
382 : // If RESIZABLE is true, the storage will be resized on the heap when
383 : // the number of ranges needed goes past N up to a max of
384 : // HARD_MAX_RANGES. This new storage is freed upon destruction.
385 :
386 : template<unsigned N, bool RESIZABLE = false>
387 : class int_range final : public irange
388 : {
389 : public:
390 : int_range ();
391 : int_range (tree type, const wide_int &, const wide_int &,
392 : value_range_kind = VR_RANGE);
393 : int_range (tree type);
394 : int_range (const int_range &);
395 : int_range (const irange &);
396 : ~int_range () final override;
397 : int_range& operator= (const int_range &);
398 : protected:
399 : int_range (tree, tree, value_range_kind = VR_RANGE);
400 : private:
401 : wide_int m_ranges[N*2];
402 : };
403 :
404 : class prange final : public vrange
405 : {
406 : friend class prange_storage;
407 : friend class vrange_printer;
408 : public:
409 : prange ();
410 : prange (const prange &);
411 : prange (tree type);
412 : prange (tree type, const wide_int &, const wide_int &,
413 : value_range_kind = VR_RANGE);
414 : static bool supports_p (const_tree type);
415 : virtual bool supports_type_p (const_tree type) const final override;
416 : virtual void accept (const vrange_visitor &v) const final override;
417 : virtual void set_undefined () final override;
418 : virtual void set_varying (tree type) final override;
419 : virtual void set_nonzero (tree type) final override;
420 : virtual void set_zero (tree type) final override;
421 : virtual void set_nonnegative (tree type) final override;
422 : virtual bool contains_p (tree cst) const final override;
423 : virtual bool fits_p (const vrange &v) const final override;
424 : virtual bool singleton_p (tree *result = NULL) const final override;
425 : virtual bool zero_p () const final override;
426 : virtual bool contains_zero_p () const final override;
427 : virtual void set (tree, tree, value_range_kind = VR_RANGE) final override;
428 : virtual tree type () const final override;
429 : virtual bool union_ (const vrange &v) final override;
430 : virtual bool intersect (const vrange &v) final override;
431 : virtual tree lbound () const final override;
432 : virtual tree ubound () const final override;
433 :
434 : prange& operator= (const prange &);
435 : bool operator== (const prange &) const;
436 : void set (tree type, const wide_int &, const wide_int &,
437 : value_range_kind = VR_RANGE);
438 : bool invert ();
439 : bool contains_p (const wide_int &) const;
440 : wide_int lower_bound () const;
441 : wide_int upper_bound () const;
442 : virtual void verify_range () const final override;
443 : irange_bitmask get_bitmask () const final override;
444 : void update_bitmask (const irange_bitmask &) final override;
445 :
446 : // prange interface to points to information.
447 : // It can point_to or point_away from an object. This represents both
448 : // sides of a conditional. ie:
449 : // if (p == &foo)
450 : // // p points to foo.
451 : // else
452 : // // p points away from foo.
453 : // pt_invariant () and pt_invariant_away () - Return pt if this is invariant.
454 : void set_pt (const prange &r);
455 : void set_pt (tree ptr, bool points_to_p = true);
456 :
457 : // unknown_p () is true if no object is pointed to.
458 : void set_pt_unknown ();
459 : bool pt_unknown_p () const;
460 :
461 : // Invariant points-to are is_gimple_min_invariant_p ().
462 : // Return expression or NULL_TREE for points-to or away
463 : tree pt_invariant () const;
464 : tree pt_invariant_away () const;
465 :
466 : // Return true if THIS and R both point to the same object.
467 : bool pt_invariant_p (const prange &r) const;
468 : // Return true if THIS and R both point away from the same object.
469 : bool pt_invariant_away_p (const prange &r) const;
470 : // Return true if THIS and R refer to the same object, and one is inverted
471 : // from the other, Ie, both to and away.
472 : bool pt_inverted_p (const prange &r) const;
473 :
474 : // Invert THIS if it points either to or away from an object.
475 : bool pt_invert ();
476 :
477 : // pt_base () - object/allocation the pointer refers into.
478 : tree pt_base () const;
479 : // pt_offset () - possible byte offset range from BASE.
480 : void pt_offset (irange &) const;
481 : // pt_size () - possible size range of the referenced object.
482 : void pt_size (irange &) const;
483 :
484 : protected:
485 : bool varying_compatible_p () const;
486 :
487 : tree m_type;
488 : wide_int m_min;
489 : wide_int m_max;
490 : irange_bitmask m_bitmask;
491 :
492 : // A prange can point to an object, or NOT point to an object.
493 : tree m_pt; // object points-to refers to.
494 : bool m_points_to_p; // Does it point to it (TRUE), or not (FALSE).
495 : // If P has the same points to fields as THIS.
496 : bool pt_equal_p (const class prange &p) const;
497 : };
498 :
499 : // Unsupported temporaries may be created by ranger before it's known
500 : // they're unsupported, or by vr_values::get_value_range.
501 :
502 0 : class unsupported_range : public vrange
503 : {
504 : public:
505 76014246 : unsupported_range ()
506 76014246 : : vrange (VR_UNKNOWN)
507 : {
508 76014246 : set_undefined ();
509 : }
510 669356 : unsupported_range (const unsupported_range &src)
511 669356 : : vrange (VR_UNKNOWN)
512 : {
513 669356 : unsupported_range::operator= (src);
514 : }
515 : void set (tree min, tree, value_range_kind = VR_RANGE) final override;
516 : tree type () const final override;
517 : bool supports_type_p (const_tree) const final override;
518 : void set_varying (tree) final override;
519 : void set_undefined () final override;
520 : void accept (const vrange_visitor &v) const final override;
521 : bool union_ (const vrange &r) final override;
522 : bool intersect (const vrange &r) final override;
523 : bool singleton_p (tree * = NULL) const final override;
524 : bool contains_p (tree) const final override;
525 : bool zero_p () const final override;
526 : bool contains_zero_p () const final override;
527 : void set_nonzero (tree type) final override;
528 : void set_zero (tree type) final override;
529 : void set_nonnegative (tree type) final override;
530 : bool fits_p (const vrange &) const final override;
531 : unsupported_range& operator= (const unsupported_range &r);
532 : tree lbound () const final override;
533 : tree ubound () const final override;
534 : };
535 :
536 : // The possible NAN state of a floating point value as an opaque object.
537 : // This represents one of the four subsets of { -NaN, +NaN },
538 : // i.e. one of {}, { -NaN }, { +NaN}, or { -NaN, +NaN }.
539 :
540 : class nan_state
541 : {
542 : public:
543 : nan_state (bool);
544 : nan_state (bool pos_nan, bool neg_nan);
545 : bool neg_p () const;
546 : bool pos_p () const;
547 : private:
548 : bool m_pos_nan;
549 : bool m_neg_nan;
550 : };
551 :
552 : // Set NAN state to +-NAN if NAN_P is true. Otherwise set NAN state
553 : // to false.
554 :
555 : inline
556 36440842 : nan_state::nan_state (bool nan_p)
557 : {
558 36440842 : m_pos_nan = nan_p;
559 32199898 : m_neg_nan = nan_p;
560 : }
561 :
562 : // Constructor initializing the object to +NAN if POS_NAN is set, -NAN
563 : // if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
564 : // NEG_NAN are clear, and the object cannot be a NAN.
565 :
566 : inline
567 3452822 : nan_state::nan_state (bool pos_nan, bool neg_nan)
568 : {
569 3452822 : m_pos_nan = pos_nan;
570 3441822 : m_neg_nan = neg_nan;
571 : }
572 :
573 : // Return if +NAN is possible.
574 :
575 : inline bool
576 39427492 : nan_state::pos_p () const
577 : {
578 39323728 : return m_pos_nan;
579 : }
580 :
581 : // Return if -NAN is possible.
582 :
583 : inline bool
584 39170119 : nan_state::neg_p () const
585 : {
586 39118193 : return m_neg_nan;
587 : }
588 :
589 : // A sub-range in an frange.
590 :
591 : struct frange_pair
592 : {
593 : REAL_VALUE_TYPE min;
594 : REAL_VALUE_TYPE max;
595 : };
596 :
597 : // A subset of possible values for a floating point type.
598 : //
599 : // The representation is a handful of disjoint intervals, unioned with a
600 : // subset of { -NaN, +NaN }.
601 :
602 27512583 : class frange final : public vrange
603 : {
604 : friend class frange_storage;
605 : friend class vrange_printer;
606 : public:
607 : frange ();
608 : frange (const frange &);
609 : frange (tree, tree, value_range_kind = VR_RANGE);
610 : frange (tree type);
611 : frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
612 : value_range_kind = VR_RANGE);
613 538290050 : static bool supports_p (const_tree type)
614 : {
615 : // ?? Decimal floats can have multiple representations for the
616 : // same number. Supporting them may be as simple as just
617 : // disabling them in singleton_p. No clue.
618 538290050 : return SCALAR_FLOAT_TYPE_P (type) && !DECIMAL_FLOAT_TYPE_P (type);
619 : }
620 : virtual tree type () const override;
621 : void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
622 : value_range_kind = VR_RANGE);
623 : void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
624 : const nan_state &, value_range_kind = VR_RANGE);
625 : void set_nan (tree type);
626 : void set_nan (tree type, bool sign);
627 : void set_nan (tree type, const nan_state &);
628 : virtual void set_varying (tree type) override;
629 : virtual void set_undefined () override;
630 : virtual bool union_ (const vrange &) override;
631 : virtual bool intersect (const vrange &) override;
632 : bool contains_p (const REAL_VALUE_TYPE &) const;
633 : virtual bool singleton_p (tree *result = NULL) const override;
634 : bool singleton_p (REAL_VALUE_TYPE &r) const;
635 : virtual bool supports_type_p (const_tree type) const override;
636 : virtual void accept (const vrange_visitor &v) const override;
637 : virtual bool zero_p () const override;
638 : virtual bool contains_zero_p () const override;
639 : virtual void set_nonzero (tree type) override;
640 : virtual void set_zero (tree type) override;
641 : virtual void set_nonnegative (tree type) override;
642 : virtual bool fits_p (const vrange &) const override;
643 : frange& operator= (const frange &);
644 : bool operator== (const frange &) const;
645 10674193 : bool operator!= (const frange &r) const { return !(*this == r); }
646 : const REAL_VALUE_TYPE &lower_bound () const;
647 : const REAL_VALUE_TYPE &upper_bound () const;
648 : virtual tree lbound () const override;
649 : virtual tree ubound () const override;
650 : nan_state get_nan_state () const;
651 : void update_nan ();
652 : void update_nan (bool sign);
653 : void update_nan (tree) = delete; // Disallow silent conversion to bool.
654 : void update_nan (const nan_state &);
655 : void clear_nan ();
656 : void flush_denormals_to_zero ();
657 :
658 : // fpclassify like API
659 : bool known_isfinite () const;
660 : bool known_isnan () const;
661 : bool known_isinf () const;
662 : bool maybe_isnan () const;
663 : bool maybe_isnan (bool sign) const;
664 : bool maybe_isinf () const;
665 : bool signbit_p (bool &signbit) const;
666 : bool nan_signbit_p (bool &signbit) const;
667 : bool known_isnormal () const;
668 : bool known_isdenormal_or_zero () const;
669 : virtual void verify_range () const override;
670 :
671 : static const unsigned int MAX_PAIRS = 2;
672 35368515 : unsigned num_pairs () const { return m_num_ranges; }
673 : const REAL_VALUE_TYPE &lower_bound (unsigned pair) const;
674 : const REAL_VALUE_TYPE &upper_bound (unsigned pair) const;
675 :
676 : void widen (tree);
677 : protected:
678 : virtual bool contains_p (tree cst) const override;
679 : virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
680 :
681 : private:
682 : bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const;
683 : bool normalize_kind ();
684 : bool union_nans (const frange &);
685 : bool intersect_nans (const frange &);
686 : void set_pairs (frange_pair *, unsigned);
687 : void canonicalize_zeros (frange_pair &);
688 : void set_excluding (tree type, const REAL_VALUE_TYPE &,
689 : const REAL_VALUE_TYPE &, const nan_state &);
690 :
691 : tree m_type;
692 : frange_pair m_pairs[MAX_PAIRS];
693 : unsigned char m_num_ranges;
694 : bool m_pos_nan;
695 : bool m_neg_nan;
696 : };
697 :
698 : inline const REAL_VALUE_TYPE &
699 6894096 : frange::lower_bound () const
700 : {
701 6894096 : gcc_checking_assert (!undefined_p () && !known_isnan ());
702 6894096 : return m_pairs[0].min;
703 : }
704 :
705 : inline const REAL_VALUE_TYPE &
706 5056476 : frange::upper_bound () const
707 : {
708 5056476 : gcc_checking_assert (!undefined_p () && !known_isnan ());
709 5056476 : return m_pairs[m_num_ranges - 1].max;
710 : }
711 :
712 : inline const REAL_VALUE_TYPE &
713 14308389 : frange::lower_bound (unsigned pair) const
714 : {
715 14308389 : gcc_checking_assert (!undefined_p () && !known_isnan ());
716 14308389 : gcc_checking_assert (pair < m_num_ranges);
717 14308389 : return m_pairs[pair].min;
718 : }
719 :
720 : inline const REAL_VALUE_TYPE &
721 14308389 : frange::upper_bound (unsigned pair) const
722 : {
723 14308389 : gcc_checking_assert (!undefined_p () && !known_isnan ());
724 14308389 : gcc_checking_assert (pair < m_num_ranges);
725 14308389 : return m_pairs[pair].max;
726 : }
727 :
728 : // Return the NAN state.
729 :
730 : inline nan_state
731 1125963 : frange::get_nan_state () const
732 : {
733 1125963 : return nan_state (m_pos_nan, m_neg_nan);
734 : }
735 :
736 : // is_a<> and as_a<> implementation for vrange.
737 :
738 : // Anything we haven't specialized is a hard fail.
739 : template <typename T>
740 : inline bool
741 : is_a (vrange &)
742 : {
743 : gcc_unreachable ();
744 : return false;
745 : }
746 :
747 : template <typename T>
748 : inline bool
749 4810108532 : is_a (const vrange &v)
750 : {
751 : // Reuse is_a <vrange> to implement the const version.
752 5028394326 : const T &derived = static_cast<const T &> (v);
753 2246752436 : return is_a <T> (const_cast<T &> (derived));
754 : }
755 :
756 : template <typename T>
757 : inline T &
758 2823381384 : as_a (vrange &v)
759 : {
760 0 : gcc_checking_assert (is_a <T> (v));
761 2823381384 : return static_cast <T &> (v);
762 : }
763 :
764 : template <typename T>
765 : inline const T &
766 4125628117 : as_a (const vrange &v)
767 : {
768 0 : gcc_checking_assert (is_a <T> (v));
769 4125628117 : return static_cast <const T &> (v);
770 : }
771 :
772 : // Specializations for the different range types.
773 :
774 : template <>
775 : inline bool
776 8159965988 : is_a <irange> (vrange &v)
777 : {
778 8022408037 : return v.m_discriminator == VR_IRANGE;
779 : }
780 :
781 : template <>
782 : inline bool
783 1554036659 : is_a <prange> (vrange &v)
784 : {
785 1406341002 : return v.m_discriminator == VR_PRANGE;
786 : }
787 :
788 : template <>
789 : inline bool
790 224491567 : is_a <frange> (vrange &v)
791 : {
792 224491567 : return v.m_discriminator == VR_FRANGE;
793 : }
794 :
795 : template <>
796 : inline bool
797 669356 : is_a <unsupported_range> (vrange &v)
798 : {
799 669356 : return v.m_discriminator == VR_UNKNOWN;
800 : }
801 :
802 : // For resizable ranges, resize the range up to HARD_MAX_RANGES if the
803 : // NEEDED pairs is greater than the current capacity of the range.
804 :
805 : inline void
806 1504722080 : irange::maybe_resize (int needed)
807 : {
808 1504722080 : if (!m_resizable || m_max_ranges == HARD_MAX_RANGES)
809 : return;
810 :
811 989561033 : if (needed > m_max_ranges)
812 : {
813 71422039 : m_max_ranges = HARD_MAX_RANGES;
814 36496661929 : wide_int *newmem = new wide_int[m_max_ranges * 2];
815 71422039 : unsigned n = num_pairs () * 2;
816 404608687 : for (unsigned i = 0; i < n; ++i)
817 333186648 : newmem[i] = m_base[i];
818 71422039 : m_base = newmem;
819 : }
820 : }
821 :
822 : template<unsigned N, bool RESIZABLE>
823 : inline
824 5893023235 : int_range<N, RESIZABLE>::~int_range ()
825 : {
826 4468417484 : if (RESIZABLE && m_base != m_ranges)
827 36496661929 : delete[] m_base;
828 36834018352 : }
829 :
830 : // This is an "infinite" precision irange for use in temporary
831 : // calculations. It starts with a sensible default covering 99% of
832 : // uses, and goes up to HARD_MAX_RANGES when needed. Any allocated
833 : // storage is freed upon destruction.
834 : typedef int_range<3, /*RESIZABLE=*/true> int_range_max;
835 :
836 41550 : class vrange_visitor
837 : {
838 : public:
839 0 : virtual void visit (const irange &) const { }
840 0 : virtual void visit (const prange &) const { }
841 0 : virtual void visit (const frange &) const { }
842 0 : virtual void visit (const unsupported_range &) const { }
843 : };
844 :
845 : // This is an "infinite" precision range object for use in temporary
846 : // calculations for any of the handled types. The object can be
847 : // transparently used as a vrange.
848 : //
849 : // Using any of the various constructors initializes the object
850 : // appropriately, but the default constructor is uninitialized and
851 : // must be initialized either with set_range_class() or by assigning into it.
852 : //
853 : // Assigning between incompatible types is allowed. For example if a
854 : // temporary holds an irange, you can assign an frange into it, and
855 : // all the right things will happen. However, before passing this
856 : // object to a function accepting a vrange, the correct type must be
857 : // set. If it isn't, you can do so with set_range_class().
858 :
859 : class value_range
860 : {
861 : public:
862 : value_range ();
863 : value_range (const vrange &r);
864 : value_range (tree type);
865 : value_range (tree, tree, value_range_kind kind = VR_RANGE);
866 : value_range (const value_range &);
867 : ~value_range ();
868 : void set_range_class (tree type);
869 : vrange& operator= (const vrange &);
870 : value_range& operator= (const value_range &);
871 : bool operator== (const value_range &r) const;
872 : bool operator!= (const value_range &r) const;
873 : operator vrange &();
874 : operator const vrange &() const;
875 : void dump (FILE *) const;
876 : void print (pretty_printer *) const;
877 : static bool supports_type_p (const_tree type);
878 :
879 3682319 : tree type () { return m_vrange->type (); }
880 166664255 : bool varying_p () const { return m_vrange->varying_p (); }
881 172849064 : bool undefined_p () const { return m_vrange->undefined_p (); }
882 311082516 : void set_varying (tree type) { init (type); m_vrange->set_varying (type); }
883 23690174 : void set_undefined () { m_vrange->set_undefined (); }
884 19324941 : bool union_ (const vrange &r) { return m_vrange->union_ (r); }
885 102813269 : bool intersect (const vrange &r) { return m_vrange->intersect (r); }
886 1572226 : bool contains_p (tree cst) const { return m_vrange->contains_p (cst); }
887 427980004 : bool singleton_p (tree *result = NULL) const
888 427980004 : { return m_vrange->singleton_p (result); }
889 1029 : void set_zero (tree type) { init (type); return m_vrange->set_zero (type); }
890 0 : void set_nonzero (tree type)
891 0 : { init (type); return m_vrange->set_nonzero (type); }
892 269954 : bool contains_zero_p () const { return m_vrange->contains_zero_p (); }
893 4734 : bool zero_p () const { return m_vrange->zero_p (); }
894 10985881 : tree lbound () const { return m_vrange->lbound (); }
895 354787 : tree ubound () const { return m_vrange->ubound (); }
896 516209 : irange_bitmask get_bitmask () const { return m_vrange->get_bitmask (); }
897 1486344 : void update_bitmask (const class irange_bitmask &bm)
898 1486344 : { return m_vrange->update_bitmask (bm); }
899 2713 : void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
900 : void verify_range () const { m_vrange->verify_range (); }
901 : private:
902 : void init (tree type);
903 : void init (const vrange &);
904 :
905 : vrange *m_vrange;
906 : union buffer_type {
907 : int_range_max ints;
908 : frange floats;
909 : unsupported_range unsupported;
910 : prange pointers;
911 7356498248 : buffer_type () { }
912 7499178527 : ~buffer_type () { }
913 : } m_buffer;
914 : };
915 :
916 : // The default constructor is uninitialized and must be initialized
917 : // with either set_range_class() or with an assignment into it.
918 :
919 : inline
920 4113774838 : value_range::value_range ()
921 4113774838 : : m_buffer ()
922 : {
923 4113774838 : m_vrange = NULL;
924 : }
925 :
926 : // Copy constructor.
927 :
928 : inline
929 12881181 : value_range::value_range (const value_range &r)
930 : {
931 12881181 : init (*r.m_vrange);
932 : }
933 :
934 : // Copy constructor from a vrange.
935 :
936 : inline
937 88965152 : value_range::value_range (const vrange &r)
938 : {
939 88965152 : init (r);
940 : }
941 :
942 : // Construct an UNDEFINED range that can hold ranges of TYPE. If TYPE
943 : // is not supported, default to unsupported_range.
944 :
945 : inline
946 3140823745 : value_range::value_range (tree type)
947 : {
948 2946786103 : init (type);
949 : }
950 :
951 : // Construct a range that can hold a range of [MIN, MAX], where MIN
952 : // and MAX are trees.
953 :
954 : inline
955 53332 : value_range::value_range (tree min, tree max, value_range_kind kind)
956 : {
957 53332 : init (TREE_TYPE (min));
958 53332 : m_vrange->set (min, max, kind);
959 53332 : }
960 :
961 : inline
962 7499178527 : value_range::~value_range ()
963 : {
964 7499178527 : if (m_vrange)
965 3569017253 : m_vrange->~vrange ();
966 7499178527 : }
967 :
968 : // Initialize object to an UNDEFINED range that can hold ranges of
969 : // TYPE. Clean-up memory if there was a previous object.
970 : // Note that this does *not* set the type of the underlying vrange.
971 :
972 : inline void
973 121516017 : value_range::set_range_class (tree type)
974 : {
975 121516017 : if (m_vrange)
976 9563851 : m_vrange->~vrange ();
977 121516017 : init (type);
978 121516017 : }
979 :
980 : // Initialize object to an UNDEFINED range that can hold ranges of
981 : // TYPE.
982 : // Note that this does *not* set the type of the underlying vrange.
983 :
984 : inline void
985 3573476639 : value_range::init (tree type)
986 : {
987 3573476639 : gcc_checking_assert (TYPE_P (type));
988 :
989 3573476639 : if (irange::supports_p (type))
990 2565750447 : m_vrange = new (&m_buffer.ints) int_range_max ();
991 1007726192 : else if (prange::supports_p (type))
992 821390972 : m_vrange = new (&m_buffer.pointers) prange ();
993 186335220 : else if (frange::supports_p (type))
994 110320974 : m_vrange = new (&m_buffer.floats) frange ();
995 : else
996 76014246 : m_vrange = new (&m_buffer.unsupported) unsupported_range ();
997 3573476639 : }
998 :
999 : // Initialize object with a copy of R.
1000 :
1001 : inline void
1002 137117650 : value_range::init (const vrange &r)
1003 : {
1004 137117650 : if (is_a <irange> (r))
1005 82998627 : m_vrange = new (&m_buffer.ints) int_range_max (as_a <irange> (r));
1006 54119023 : else if (is_a <prange> (r))
1007 106474888 : m_vrange = new (&m_buffer.pointers) prange (as_a <prange> (r));
1008 881579 : else if (is_a <frange> (r))
1009 424446 : m_vrange = new (&m_buffer.floats) frange (as_a <frange> (r));
1010 : else
1011 1338712 : m_vrange = new (&m_buffer.unsupported)
1012 669356 : unsupported_range (as_a <unsupported_range> (r));
1013 137117650 : }
1014 :
1015 : // Assignment operator. Copying incompatible types is allowed. That
1016 : // is, assigning an frange to an object holding an irange does the
1017 : // right thing.
1018 :
1019 : inline vrange &
1020 35271317 : value_range::operator= (const vrange &r)
1021 : {
1022 35271317 : if (m_vrange)
1023 10762640 : m_vrange->~vrange ();
1024 35271317 : init (r);
1025 35271317 : return *m_vrange;
1026 : }
1027 :
1028 : inline value_range &
1029 10815944 : value_range::operator= (const value_range &r)
1030 : {
1031 : // No need to call the m_vrange destructor here, as we will do so in
1032 : // the assignment below.
1033 1592339 : *this = *r.m_vrange;
1034 10815944 : return *this;
1035 : }
1036 :
1037 : inline bool
1038 27531020 : value_range::operator== (const value_range &r) const
1039 : {
1040 27531020 : return *m_vrange == *r.m_vrange;
1041 : }
1042 :
1043 : inline bool
1044 13977838 : value_range::operator!= (const value_range &r) const
1045 : {
1046 13977838 : return *m_vrange != *r.m_vrange;
1047 : }
1048 :
1049 : inline
1050 4781709827 : value_range::operator vrange &()
1051 : {
1052 4454934947 : return *m_vrange;
1053 : }
1054 :
1055 : inline
1056 44493322 : value_range::operator const vrange &() const
1057 : {
1058 44493322 : return *m_vrange;
1059 : }
1060 :
1061 : // Return TRUE if TYPE is supported by the vrange infrastructure.
1062 :
1063 : inline bool
1064 6797285363 : value_range::supports_type_p (const_tree type)
1065 : {
1066 6797285363 : return irange::supports_p (type)
1067 1662094229 : || prange::supports_p (type)
1068 253377533 : || frange::supports_p (type);
1069 : }
1070 :
1071 : extern value_range_kind get_legacy_range (const vrange &, tree &min, tree &max);
1072 : extern void dump_value_range (FILE *, const vrange *);
1073 : extern bool vrp_operand_equal_p (const_tree, const_tree);
1074 : inline REAL_VALUE_TYPE frange_val_min (const_tree type);
1075 : inline REAL_VALUE_TYPE frange_val_max (const_tree type);
1076 :
1077 : // Number of sub-ranges in a range.
1078 :
1079 : inline unsigned
1080 38088906364 : irange::num_pairs () const
1081 : {
1082 6270722044 : return m_num_ranges;
1083 : }
1084 :
1085 : inline tree
1086 13134031625 : irange::type () const
1087 : {
1088 13134031625 : gcc_checking_assert (m_num_ranges > 0);
1089 13134031625 : return m_type;
1090 : }
1091 :
1092 : inline bool
1093 5641708572 : irange::varying_compatible_p () const
1094 : {
1095 5641708572 : if (m_num_ranges != 1)
1096 : return false;
1097 :
1098 4181362410 : const wide_int &l = m_base[0];
1099 4181362410 : const wide_int &u = m_base[1];
1100 4181362410 : tree t = m_type;
1101 :
1102 4181362410 : if (m_kind == VR_VARYING)
1103 : return true;
1104 :
1105 3914691284 : unsigned prec = TYPE_PRECISION (t);
1106 3914691284 : signop sign = TYPE_SIGN (t);
1107 3914691284 : if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
1108 7829382568 : return (l == wi::min_value (prec, sign)
1109 5105578893 : && u == wi::max_value (prec, sign)
1110 3922267155 : && m_bitmask.unknown_p ());
1111 : return true;
1112 : }
1113 :
1114 : inline bool
1115 1109073709 : vrange::varying_p () const
1116 : {
1117 1105284718 : return m_kind == VR_VARYING;
1118 : }
1119 :
1120 : inline bool
1121 23527496135 : vrange::undefined_p () const
1122 : {
1123 12953882183 : return m_kind == VR_UNDEFINED;
1124 : }
1125 :
1126 : inline bool
1127 255858380 : irange::zero_p () const
1128 : {
1129 242762489 : return (m_kind == VR_RANGE && m_num_ranges == 1
1130 470734006 : && lower_bound (0) == 0
1131 498620888 : && upper_bound (0) == 0);
1132 : }
1133 :
1134 : inline bool
1135 37825609 : irange::contains_zero_p () const
1136 : {
1137 37825609 : if (undefined_p ())
1138 : return false;
1139 :
1140 37825609 : wide_int zero = wi::zero (TYPE_PRECISION (type ()));
1141 37825609 : return contains_p (zero);
1142 37825609 : }
1143 :
1144 : inline bool
1145 17071730313 : irange::supports_p (const_tree type)
1146 : {
1147 16102366858 : return INTEGRAL_TYPE_P (type);
1148 : }
1149 :
1150 : inline bool
1151 81291386 : irange::contains_p (tree cst) const
1152 : {
1153 81291386 : return contains_p (wi::to_wide (cst));
1154 : }
1155 :
1156 : inline bool
1157 38698177 : range_includes_zero_p (const vrange &vr)
1158 : {
1159 38698177 : if (vr.undefined_p ())
1160 : return false;
1161 :
1162 38698177 : if (vr.varying_p ())
1163 : return true;
1164 :
1165 29474369 : return vr.contains_p (build_zero_cst (vr.type ()));
1166 : }
1167 :
1168 : // Constructors for irange
1169 :
1170 : inline
1171 5983624627 : irange::irange (wide_int *base, unsigned nranges, bool resizable)
1172 : : vrange (VR_IRANGE),
1173 5983624627 : m_resizable (resizable),
1174 5983624627 : m_max_ranges (nranges)
1175 : {
1176 5983624627 : m_base = base;
1177 5983624627 : set_undefined ();
1178 : }
1179 :
1180 : // Constructors for int_range<>.
1181 :
1182 : template<unsigned N, bool RESIZABLE>
1183 : inline
1184 4522797474 : int_range<N, RESIZABLE>::int_range ()
1185 30939928244 : : irange (m_ranges, N, RESIZABLE)
1186 : {
1187 4522797474 : }
1188 :
1189 : template<unsigned N, bool RESIZABLE>
1190 546386 : int_range<N, RESIZABLE>::int_range (const int_range &other)
1191 3824694 : : irange (m_ranges, N, RESIZABLE)
1192 : {
1193 546386 : irange::operator= (other);
1194 546386 : }
1195 :
1196 : template<unsigned N, bool RESIZABLE>
1197 : int_range<N, RESIZABLE>::int_range (tree min, tree max, value_range_kind kind)
1198 : : irange (m_ranges, N, RESIZABLE)
1199 : {
1200 : irange::set (min, max, kind);
1201 : }
1202 :
1203 : template<unsigned N, bool RESIZABLE>
1204 169869997 : int_range<N, RESIZABLE>::int_range (tree type)
1205 668228487 : : irange (m_ranges, N, RESIZABLE)
1206 : {
1207 169869997 : set_varying (type);
1208 169869997 : }
1209 :
1210 : template<unsigned N, bool RESIZABLE>
1211 860052705 : int_range<N, RESIZABLE>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
1212 : value_range_kind kind)
1213 3010447927 : : irange (m_ranges, N, RESIZABLE)
1214 : {
1215 860052705 : set (type, wmin, wmax, kind);
1216 860052705 : }
1217 :
1218 : template<unsigned N, bool RESIZABLE>
1219 430358065 : int_range<N, RESIZABLE>::int_range (const irange &other)
1220 2774376705 : : irange (m_ranges, N, RESIZABLE)
1221 : {
1222 430358065 : irange::operator= (other);
1223 430358065 : }
1224 :
1225 : template<unsigned N, bool RESIZABLE>
1226 : int_range<N, RESIZABLE>&
1227 70576633 : int_range<N, RESIZABLE>::operator= (const int_range &src)
1228 : {
1229 70569097 : irange::operator= (src);
1230 0 : return *this;
1231 : }
1232 :
1233 : inline void
1234 6394303151 : irange::set_undefined ()
1235 : {
1236 6394303151 : m_kind = VR_UNDEFINED;
1237 6295924972 : m_num_ranges = 0;
1238 405688378 : }
1239 :
1240 : inline void
1241 1296377725 : irange::set_varying (tree type)
1242 : {
1243 1296377725 : m_kind = VR_VARYING;
1244 1296377725 : m_num_ranges = 1;
1245 1296377725 : m_bitmask.set_unknown (TYPE_PRECISION (type));
1246 :
1247 1296377725 : if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
1248 : {
1249 1296377725 : m_type = type;
1250 : // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
1251 : // min_value and max_value.
1252 1296377725 : m_base[0] = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1253 1296393472 : m_base[1] = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1254 : }
1255 : else
1256 0 : m_type = error_mark_node;
1257 1296377725 : }
1258 :
1259 : // Return the lower bound of a sub-range. PAIR is the sub-range in
1260 : // question.
1261 :
1262 : inline wide_int
1263 13080850365 : irange::lower_bound (unsigned pair) const
1264 : {
1265 13080850365 : gcc_checking_assert (m_num_ranges > 0);
1266 13080850365 : gcc_checking_assert (pair + 1 <= num_pairs ());
1267 13080850365 : return m_base[pair * 2];
1268 : }
1269 :
1270 : // Return the upper bound of a sub-range. PAIR is the sub-range in
1271 : // question.
1272 :
1273 : inline wide_int
1274 15050384435 : irange::upper_bound (unsigned pair) const
1275 : {
1276 15050384435 : gcc_checking_assert (m_num_ranges > 0);
1277 15050384435 : gcc_checking_assert (pair + 1 <= num_pairs ());
1278 15050384435 : return m_base[pair * 2 + 1];
1279 : }
1280 :
1281 : // Return the highest bound of a range.
1282 :
1283 : inline wide_int
1284 3988152795 : irange::upper_bound () const
1285 : {
1286 3988152795 : unsigned pairs = num_pairs ();
1287 3988152795 : gcc_checking_assert (pairs > 0);
1288 3988152795 : return upper_bound (pairs - 1);
1289 : }
1290 :
1291 : // Set value range VR to a nonzero range of type TYPE.
1292 :
1293 : inline void
1294 3825023 : irange::set_nonzero (tree type)
1295 : {
1296 3825023 : unsigned prec = TYPE_PRECISION (type);
1297 :
1298 3825023 : if (TYPE_UNSIGNED (type))
1299 : {
1300 3375898 : m_type = type;
1301 3375898 : m_kind = VR_RANGE;
1302 3375898 : m_base[0] = wi::one (prec);
1303 3375898 : m_base[1] = wi::minus_one (prec);
1304 3375898 : m_bitmask.set_unknown (prec);
1305 3375898 : m_num_ranges = 1;
1306 :
1307 3375898 : if (flag_checking)
1308 3375898 : verify_range ();
1309 : }
1310 : else
1311 : {
1312 449125 : wide_int zero = wi::zero (prec);
1313 449125 : set (type, zero, zero, VR_ANTI_RANGE);
1314 449125 : }
1315 3825023 : }
1316 :
1317 : // Set value range VR to a ZERO range of type TYPE.
1318 :
1319 : inline void
1320 3597448 : irange::set_zero (tree type)
1321 : {
1322 3597448 : wide_int zero = wi::zero (TYPE_PRECISION (type));
1323 3597448 : set (type, zero, zero);
1324 3597448 : }
1325 :
1326 : // Normalize a range to VARYING or UNDEFINED if possible.
1327 :
1328 : inline void
1329 638410559 : irange::normalize_kind ()
1330 : {
1331 638410559 : if (m_num_ranges == 0)
1332 35137 : set_undefined ();
1333 638375422 : else if (varying_compatible_p ())
1334 : {
1335 28606602 : if (m_kind == VR_RANGE)
1336 7418863 : m_kind = VR_VARYING;
1337 21187739 : else if (m_kind == VR_ANTI_RANGE)
1338 0 : set_undefined ();
1339 : }
1340 638410559 : if (flag_checking)
1341 638409714 : verify_range ();
1342 638410559 : }
1343 :
1344 : inline wide_int
1345 106744948 : irange_val_min (const_tree type)
1346 : {
1347 106744948 : gcc_checking_assert (irange::supports_p (type));
1348 106744948 : return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1349 : }
1350 :
1351 : inline wide_int
1352 105415857 : irange_val_max (const_tree type)
1353 : {
1354 105415857 : gcc_checking_assert (irange::supports_p (type));
1355 105415857 : return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
1356 : }
1357 :
1358 : inline
1359 884852526 : prange::prange ()
1360 884852526 : : vrange (VR_PRANGE)
1361 : {
1362 884852526 : set_undefined ();
1363 : }
1364 :
1365 : inline
1366 128954136 : prange::prange (const prange &r)
1367 128954136 : : vrange (VR_PRANGE)
1368 : {
1369 128954136 : *this = r;
1370 : }
1371 :
1372 : inline
1373 163436839 : prange::prange (tree type)
1374 163436839 : : vrange (VR_PRANGE)
1375 : {
1376 163436839 : set_varying (type);
1377 : }
1378 :
1379 : inline
1380 3817190 : prange::prange (tree type, const wide_int &lb, const wide_int &ub,
1381 : value_range_kind kind)
1382 3817190 : : vrange (VR_PRANGE)
1383 : {
1384 3817190 : set (type, lb, ub, kind);
1385 : }
1386 :
1387 : inline bool
1388 4272822126 : prange::supports_p (const_tree type)
1389 : {
1390 4272822126 : return POINTER_TYPE_P (type);
1391 : }
1392 :
1393 : inline bool
1394 495579123 : prange::supports_type_p (const_tree type) const
1395 : {
1396 495579123 : return POINTER_TYPE_P (type);
1397 : }
1398 :
1399 : inline void
1400 1029432141 : prange::set_undefined ()
1401 : {
1402 1029432141 : m_kind = VR_UNDEFINED;
1403 1029432141 : set_pt_unknown ();
1404 143169920 : }
1405 :
1406 : inline void
1407 620518334 : prange::set_varying (tree type)
1408 : {
1409 620518334 : m_kind = VR_VARYING;
1410 620518334 : m_type = type;
1411 620518334 : m_min = wi::zero (TYPE_PRECISION (type));
1412 620518334 : m_max = wi::max_value (TYPE_PRECISION (type), UNSIGNED);
1413 620518334 : m_bitmask.set_unknown (TYPE_PRECISION (type));
1414 620518334 : set_pt_unknown ();
1415 :
1416 620518334 : if (flag_checking)
1417 620518205 : verify_range ();
1418 620518334 : }
1419 :
1420 : inline void
1421 384171029 : prange::set_nonzero (tree type)
1422 : {
1423 384171029 : m_kind = VR_RANGE;
1424 384171029 : m_type = type;
1425 384171029 : m_min = wi::one (TYPE_PRECISION (type));
1426 384171029 : m_max = wi::max_value (TYPE_PRECISION (type), UNSIGNED);
1427 384171029 : m_bitmask.set_unknown (TYPE_PRECISION (type));
1428 384171029 : set_pt_unknown ();
1429 :
1430 384171029 : if (flag_checking)
1431 384170681 : verify_range ();
1432 384171029 : }
1433 :
1434 : inline void
1435 643725 : prange::set_zero (tree type)
1436 : {
1437 643725 : m_kind = VR_RANGE;
1438 643725 : m_type = type;
1439 643725 : wide_int zero = wi::zero (TYPE_PRECISION (type));
1440 643725 : m_min = m_max = zero;
1441 643725 : m_bitmask = irange_bitmask (zero, zero);
1442 643725 : set_pt_unknown ();
1443 :
1444 643725 : if (flag_checking)
1445 643725 : verify_range ();
1446 643725 : }
1447 :
1448 : inline bool
1449 675538 : prange::contains_p (tree cst) const
1450 : {
1451 675538 : return contains_p (wi::to_wide (cst));
1452 : }
1453 :
1454 : inline bool
1455 273113783 : prange::zero_p () const
1456 : {
1457 273113783 : bool ret = m_kind == VR_RANGE && m_min == 0 && m_max == 0;
1458 273113783 : return ret;
1459 : }
1460 :
1461 : inline bool
1462 36737455 : prange::contains_zero_p () const
1463 : {
1464 36737455 : if (undefined_p ())
1465 : return false;
1466 :
1467 35832589 : wide_int zero = wi::zero (TYPE_PRECISION (type ()));
1468 35832589 : return contains_p (zero);
1469 35832589 : }
1470 :
1471 : inline tree
1472 2724875192 : prange::type () const
1473 : {
1474 2724875192 : gcc_checking_assert (!undefined_p ());
1475 2724875192 : return m_type;
1476 : }
1477 :
1478 : inline wide_int
1479 660062914 : prange::lower_bound () const
1480 : {
1481 660062914 : gcc_checking_assert (!undefined_p ());
1482 660062914 : return m_min;
1483 : }
1484 :
1485 : inline wide_int
1486 627331271 : prange::upper_bound () const
1487 : {
1488 627331271 : gcc_checking_assert (!undefined_p ());
1489 627331271 : return m_max;
1490 : }
1491 :
1492 : inline bool
1493 1837004076 : prange::varying_compatible_p () const
1494 : {
1495 1837004060 : return (!undefined_p () && m_min == 0 && m_max == -1
1496 3237798080 : && get_bitmask ().unknown_p () && pt_unknown_p ());
1497 : }
1498 :
1499 : inline irange_bitmask
1500 949776657 : prange::get_bitmask () const
1501 : {
1502 949776657 : return m_bitmask;
1503 : }
1504 :
1505 : inline bool
1506 0 : prange::fits_p (const vrange &) const
1507 : {
1508 0 : return true;
1509 : }
1510 :
1511 : // Set this range's point-to object to PTR, and POINTS_TO_P is TRUE if it
1512 : // does point to it, and FALSE if it does not point to it.
1513 :
1514 : inline void
1515 214276204 : prange::set_pt (const prange &r)
1516 : {
1517 : // Do not set points-to info if this is zero or undefined.
1518 15533211 : if (!r.pt_unknown_p () && (undefined_p () || zero_p()))
1519 : return;
1520 :
1521 214276202 : m_pt = r.m_pt;
1522 214276202 : m_points_to_p = r.m_points_to_p;
1523 :
1524 214276202 : if (r.undefined_p ())
1525 : return;
1526 : // Check whether this is now VARYING or not.
1527 214210113 : if (varying_compatible_p ())
1528 28337032 : set_varying (type ());
1529 : else
1530 185873081 : m_kind = VR_RANGE;
1531 : }
1532 :
1533 : // prange_pt methods.
1534 : // ------------------------------------------------------------------
1535 :
1536 : inline void
1537 2080856085 : prange::set_pt_unknown ()
1538 : {
1539 2080856085 : m_pt = NULL_TREE;
1540 1937686165 : m_points_to_p = false;
1541 : }
1542 :
1543 : inline bool
1544 1911981754 : prange::pt_unknown_p () const
1545 : {
1546 1852199202 : return (m_pt == NULL_TREE);
1547 : }
1548 :
1549 : inline bool
1550 71045809 : prange::pt_equal_p (const prange &p) const
1551 : {
1552 : // A prange object invokes vrp_operand_equal_p as we want ranges to compare
1553 : // equal to each other if they refer to the same object, even if the
1554 : // tree has become unshared.
1555 71045809 : return (m_points_to_p == p.m_points_to_p
1556 71045809 : && vrp_operand_equal_p (m_pt, p.m_pt));
1557 : }
1558 :
1559 : inline bool
1560 76282097 : prange::pt_inverted_p (const prange &r) const
1561 : {
1562 569842 : return m_pt && vrp_operand_equal_p (m_pt, r.m_pt)
1563 76474332 : && m_points_to_p != r.m_points_to_p;
1564 : }
1565 :
1566 : inline bool
1567 2824850 : prange::pt_invert ()
1568 : {
1569 2824850 : if (m_pt)
1570 : {
1571 0 : m_points_to_p = !m_points_to_p;
1572 0 : return true;
1573 : }
1574 : return false;
1575 : }
1576 :
1577 : inline tree
1578 85904318 : prange::pt_invariant () const
1579 : {
1580 85904318 : if (m_pt && m_points_to_p)
1581 7367 : return m_pt;
1582 : return NULL_TREE;
1583 : }
1584 :
1585 : inline tree
1586 1797235 : prange::pt_invariant_away () const
1587 : {
1588 1797235 : if (m_pt && !m_points_to_p)
1589 0 : return m_pt;
1590 : return NULL_TREE;
1591 : }
1592 :
1593 : inline bool
1594 18883201 : prange::pt_invariant_p (const prange &r) const
1595 : {
1596 213417 : if (m_pt && m_points_to_p && vrp_operand_equal_p (r.m_pt, m_pt)
1597 18901869 : && m_points_to_p == r.m_points_to_p)
1598 18668 : return true;
1599 : return false;
1600 : }
1601 :
1602 : inline bool
1603 : prange::pt_invariant_away_p (const prange &r) const
1604 : {
1605 : if (m_pt && !m_points_to_p && vrp_operand_equal_p (r.m_pt, m_pt)
1606 : && m_points_to_p == r.m_points_to_p)
1607 : return true;
1608 : return false;
1609 : }
1610 :
1611 :
1612 : // -----------------------------------------------------------------------
1613 :
1614 : inline
1615 121008398 : frange::frange ()
1616 121008398 : : vrange (VR_FRANGE)
1617 : {
1618 121008334 : set_undefined ();
1619 : }
1620 :
1621 : inline
1622 13759058 : frange::frange (const frange &src)
1623 13759058 : : vrange (VR_FRANGE)
1624 : {
1625 13331175 : *this = src;
1626 : }
1627 :
1628 : inline
1629 794875 : frange::frange (tree type)
1630 794875 : : vrange (VR_FRANGE)
1631 : {
1632 794875 : set_varying (type);
1633 : }
1634 :
1635 : // frange constructor from REAL_VALUE_TYPE endpoints.
1636 :
1637 : inline
1638 18079703 : frange::frange (tree type,
1639 : const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
1640 : value_range_kind kind)
1641 18079703 : : vrange (VR_FRANGE)
1642 : {
1643 18079703 : set (type, min, max, kind);
1644 : }
1645 :
1646 : // frange constructor from trees.
1647 :
1648 : inline
1649 : frange::frange (tree min, tree max, value_range_kind kind)
1650 : : vrange (VR_FRANGE)
1651 : {
1652 : set (min, max, kind);
1653 : }
1654 :
1655 : inline tree
1656 72688593 : frange::type () const
1657 : {
1658 72688593 : gcc_checking_assert (!undefined_p ());
1659 72688593 : return m_type;
1660 : }
1661 :
1662 : inline void
1663 73256962 : frange::set_varying (tree type)
1664 : {
1665 73256962 : m_kind = VR_VARYING;
1666 73256962 : m_type = type;
1667 73256962 : m_num_ranges = 1;
1668 73256962 : m_pairs[0].min = frange_val_min (type);
1669 73256962 : m_pairs[0].max = frange_val_max (type);
1670 73256962 : if (HONOR_NANS (m_type))
1671 : {
1672 : m_pos_nan = true;
1673 : m_neg_nan = true;
1674 : }
1675 : else
1676 : {
1677 4295679 : m_pos_nan = false;
1678 4295679 : m_neg_nan = false;
1679 : }
1680 73256962 : }
1681 :
1682 : inline void
1683 162111804 : frange::set_undefined ()
1684 : {
1685 162111804 : m_kind = VR_UNDEFINED;
1686 162111804 : m_type = NULL;
1687 162111804 : m_num_ranges = 1;
1688 162111804 : m_pos_nan = false;
1689 162111804 : m_neg_nan = false;
1690 : // Leave the rest undefined; as it speeds up initializing undefined ranges.
1691 162111804 : if (flag_checking)
1692 162111804 : verify_range ();
1693 162111804 : }
1694 :
1695 : // Set the NAN bits to NAN and adjust the range.
1696 :
1697 : inline void
1698 6330767 : frange::update_nan (const nan_state &nan)
1699 : {
1700 6330767 : gcc_checking_assert (!undefined_p ());
1701 6330767 : if (HONOR_NANS (m_type))
1702 : {
1703 6329709 : m_pos_nan = nan.pos_p ();
1704 6329709 : m_neg_nan = nan.neg_p ();
1705 6329709 : normalize_kind ();
1706 6329709 : if (flag_checking)
1707 6329709 : verify_range ();
1708 : }
1709 6330767 : }
1710 :
1711 : // Set the NAN bit to +-NAN.
1712 :
1713 : inline void
1714 4195655 : frange::update_nan ()
1715 : {
1716 4195655 : gcc_checking_assert (!undefined_p ());
1717 4195655 : nan_state nan (true);
1718 4195655 : update_nan (nan);
1719 4195655 : }
1720 :
1721 : // Like above, but set the sign of the NAN.
1722 :
1723 : inline void
1724 2135112 : frange::update_nan (bool sign)
1725 : {
1726 2135112 : gcc_checking_assert (!undefined_p ());
1727 2135112 : nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1728 2135112 : update_nan (nan);
1729 2135112 : }
1730 :
1731 : inline bool
1732 0 : frange::contains_p (tree cst) const
1733 : {
1734 0 : return contains_p (*TREE_REAL_CST_PTR (cst));
1735 : }
1736 :
1737 : // Clear the NAN bit and adjust the range.
1738 :
1739 : inline void
1740 13761543 : frange::clear_nan ()
1741 : {
1742 13761543 : gcc_checking_assert (!undefined_p ());
1743 13761543 : m_pos_nan = false;
1744 13761543 : m_neg_nan = false;
1745 13761543 : normalize_kind ();
1746 13761543 : if (flag_checking)
1747 13761543 : verify_range ();
1748 13761543 : }
1749 :
1750 : // Set R to maximum representable value for TYPE.
1751 :
1752 : inline REAL_VALUE_TYPE
1753 15524207 : real_max_representable (const_tree type)
1754 : {
1755 15524207 : REAL_VALUE_TYPE r;
1756 15524207 : char buf[128];
1757 15524207 : get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type)),
1758 : buf, sizeof (buf), false);
1759 15524207 : int res = real_from_string (&r, buf);
1760 15524207 : gcc_checking_assert (!res);
1761 15524207 : return r;
1762 : }
1763 :
1764 : // Return the minimum representable value for TYPE.
1765 :
1766 : inline REAL_VALUE_TYPE
1767 8195613 : real_min_representable (const_tree type)
1768 : {
1769 8195613 : REAL_VALUE_TYPE r = real_max_representable (type);
1770 8195613 : r = real_value_negate (&r);
1771 8195613 : return r;
1772 : }
1773 :
1774 : // Return the minimum value for TYPE.
1775 :
1776 : inline REAL_VALUE_TYPE
1777 173387089 : frange_val_min (const_tree type)
1778 : {
1779 173387089 : if (HONOR_INFINITIES (type))
1780 165834196 : return dconstninf;
1781 : else
1782 7552893 : return real_min_representable (type);
1783 : }
1784 :
1785 : // Return the maximum value for TYPE.
1786 :
1787 : inline REAL_VALUE_TYPE
1788 112752946 : frange_val_max (const_tree type)
1789 : {
1790 112752946 : if (HONOR_INFINITIES (type))
1791 106162323 : return dconstinf;
1792 : else
1793 6590623 : return real_max_representable (type);
1794 : }
1795 :
1796 : // Return TRUE if R is the minimum value for TYPE.
1797 :
1798 : inline bool
1799 96544202 : frange_val_is_min (const REAL_VALUE_TYPE &r, const_tree type)
1800 : {
1801 96544202 : REAL_VALUE_TYPE min = frange_val_min (type);
1802 96544202 : return real_identical (&min, &r);
1803 : }
1804 :
1805 : // Return TRUE if R is the max value for TYPE.
1806 :
1807 : inline bool
1808 35510549 : frange_val_is_max (const REAL_VALUE_TYPE &r, const_tree type)
1809 : {
1810 35510549 : REAL_VALUE_TYPE max = frange_val_max (type);
1811 35510549 : return real_identical (&max, &r);
1812 : }
1813 :
1814 : // Build a NAN with a state of NAN.
1815 :
1816 : inline void
1817 423663 : frange::set_nan (tree type, const nan_state &nan)
1818 : {
1819 423663 : gcc_checking_assert (nan.pos_p () || nan.neg_p ());
1820 423663 : if (HONOR_NANS (type))
1821 : {
1822 423662 : m_kind = VR_NAN;
1823 423662 : m_type = type;
1824 423662 : m_num_ranges = 1;
1825 423662 : m_neg_nan = nan.neg_p ();
1826 423662 : m_pos_nan = nan.pos_p ();
1827 423662 : if (flag_checking)
1828 423662 : verify_range ();
1829 : }
1830 : else
1831 1 : set_undefined ();
1832 423663 : }
1833 :
1834 : // Build a signless NAN of type TYPE.
1835 :
1836 : inline void
1837 152960 : frange::set_nan (tree type)
1838 : {
1839 152960 : nan_state nan (true);
1840 152948 : set_nan (type, nan);
1841 : }
1842 :
1843 : // Build a NAN of type TYPE with SIGN.
1844 :
1845 : inline void
1846 189570 : frange::set_nan (tree type, bool sign)
1847 : {
1848 189570 : nan_state nan (/*pos=*/!sign, /*neg=*/sign);
1849 189566 : set_nan (type, nan);
1850 : }
1851 :
1852 : // Return TRUE if range is known to be finite.
1853 :
1854 : inline bool
1855 0 : frange::known_isfinite () const
1856 : {
1857 0 : if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
1858 : return false;
1859 0 : return (!maybe_isnan ()
1860 0 : && !real_isinf (&lower_bound ())
1861 0 : && !real_isinf (&upper_bound ()));
1862 : }
1863 :
1864 : // Return TRUE if range is known to be normal.
1865 :
1866 : inline bool
1867 0 : frange::known_isnormal () const
1868 : {
1869 0 : if (!known_isfinite ())
1870 : return false;
1871 :
1872 0 : machine_mode mode = TYPE_MODE (type ());
1873 0 : const REAL_VALUE_TYPE &min = lower_bound ();
1874 0 : const REAL_VALUE_TYPE &max = upper_bound ();
1875 0 : return (!real_isdenormal (&min, mode) && !real_isdenormal (&max, mode)
1876 0 : && !real_iszero (&min) && !real_iszero (&max)
1877 0 : && (!real_isneg (&min) || real_isneg (&max)));
1878 : }
1879 :
1880 : // Return TRUE if range is known to be denormal.
1881 :
1882 : inline bool
1883 0 : frange::known_isdenormal_or_zero () const
1884 : {
1885 0 : if (!known_isfinite ())
1886 : return false;
1887 :
1888 0 : machine_mode mode = TYPE_MODE (type ());
1889 0 : const REAL_VALUE_TYPE &min = lower_bound ();
1890 0 : const REAL_VALUE_TYPE &max = upper_bound ();
1891 0 : return ((real_isdenormal (&min, mode) || real_iszero (&min))
1892 0 : && (real_isdenormal (&max, mode) || real_iszero (&max)));
1893 : }
1894 :
1895 : // Return TRUE if range may be infinite.
1896 :
1897 : inline bool
1898 41617 : frange::maybe_isinf () const
1899 : {
1900 41617 : if (undefined_p () || m_kind == VR_ANTI_RANGE || m_kind == VR_NAN)
1901 : return false;
1902 41617 : if (varying_p ())
1903 : return true;
1904 39096 : return real_isinf (&lower_bound ()) || real_isinf (&upper_bound ());
1905 : }
1906 :
1907 : // Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
1908 :
1909 : inline bool
1910 6029153 : frange::known_isinf () const
1911 : {
1912 6029153 : return (m_kind == VR_RANGE
1913 1666939 : && m_num_ranges == 1
1914 8660361 : && !maybe_isnan ()
1915 1315598 : && real_identical (&m_pairs[0].min, &m_pairs[0].max)
1916 6066594 : && real_isinf (&m_pairs[0].min));
1917 : }
1918 :
1919 : // Return TRUE if range is possibly a NAN.
1920 :
1921 : inline bool
1922 20515991 : frange::maybe_isnan () const
1923 : {
1924 18706205 : if (undefined_p ())
1925 : return false;
1926 20511452 : return m_pos_nan || m_neg_nan;
1927 : }
1928 :
1929 : // Return TRUE if range is possibly a NAN with SIGN.
1930 :
1931 : inline bool
1932 157962 : frange::maybe_isnan (bool sign) const
1933 : {
1934 157962 : if (undefined_p ())
1935 : return false;
1936 157962 : if (sign)
1937 157962 : return m_neg_nan;
1938 : return m_pos_nan;
1939 : }
1940 :
1941 : // Return TRUE if range is a +NAN or -NAN.
1942 :
1943 : inline bool
1944 29527341 : frange::known_isnan () const
1945 : {
1946 25236902 : return m_kind == VR_NAN;
1947 : }
1948 :
1949 : // If the signbit for the range is known, set it in SIGNBIT and return
1950 : // TRUE.
1951 :
1952 : inline bool
1953 1709415 : frange::signbit_p (bool &signbit) const
1954 : {
1955 1709415 : if (undefined_p ())
1956 : return false;
1957 :
1958 : // NAN with unknown sign.
1959 1709401 : if (m_pos_nan && m_neg_nan)
1960 : return false;
1961 : // No NAN.
1962 116828 : if (!m_pos_nan && !m_neg_nan)
1963 : {
1964 95304 : if (lower_bound ().sign == upper_bound ().sign)
1965 : {
1966 19576 : signbit = lower_bound ().sign;
1967 19576 : return true;
1968 : }
1969 : return false;
1970 : }
1971 : // NAN with known sign.
1972 21524 : bool nan_sign = m_neg_nan;
1973 21524 : if (known_isnan ()
1974 21524 : || (nan_sign == lower_bound ().sign
1975 20203 : && nan_sign == upper_bound ().sign))
1976 : {
1977 20324 : signbit = nan_sign;
1978 20324 : return true;
1979 : }
1980 : return false;
1981 : }
1982 :
1983 : // If range has a NAN with a known sign, set it in SIGNBIT and return
1984 : // TRUE.
1985 :
1986 : inline bool
1987 51595 : frange::nan_signbit_p (bool &signbit) const
1988 : {
1989 51595 : if (undefined_p ())
1990 : return false;
1991 :
1992 51595 : if (m_pos_nan == m_neg_nan)
1993 : return false;
1994 :
1995 2245 : signbit = m_neg_nan;
1996 2245 : return true;
1997 : }
1998 :
1999 : void frange_nextafter (enum machine_mode, REAL_VALUE_TYPE &,
2000 : const REAL_VALUE_TYPE &);
2001 : void frange_arithmetic (enum tree_code, tree, REAL_VALUE_TYPE &,
2002 : const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
2003 : const REAL_VALUE_TYPE &);
2004 :
2005 : // Return true if TYPE1 and TYPE2 are compatible range types.
2006 :
2007 : inline bool
2008 1753319428 : range_compatible_p (tree type1, tree type2)
2009 : {
2010 : // types_compatible_p requires conversion in both directions to be useless.
2011 : // GIMPLE only requires a cast one way in order to be compatible.
2012 : // Ranges really only need the sign and precision to be the same.
2013 1753319428 : return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
2014 1753319428 : && TYPE_SIGN (type1) == TYPE_SIGN (type2));
2015 : }
2016 : #endif // GCC_VALUE_RANGE_H
|