]> gcc.gnu.org Git - gcc.git/blame - gcc/value-range.h
OpenACC: Fix reduction tree-sharing issue [PR106982]
[gcc.git] / gcc / value-range.h
CommitLineData
cca78449 1/* Support routines for value ranges.
7adcbafe 2 Copyright (C) 2019-2022 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
4ba9fb0a 25// Types of value ranges.
cca78449
AH
26enum value_range_kind
27{
28 /* Empty range. */
29 VR_UNDEFINED,
30 /* Range spans the entire domain. */
31 VR_VARYING,
32 /* Range is [MIN, MAX]. */
33 VR_RANGE,
34 /* Range is ~[MIN, MAX]. */
35 VR_ANTI_RANGE,
36 /* Range is a nice guy. */
37 VR_LAST
38};
39
40// Range of values that can be associated with an SSA_NAME.
4ba9fb0a
AH
41//
42// This is the base class without any storage.
cca78449 43
3c658587 44class GTY((user)) irange
cca78449 45{
77a23a82 46 friend class irange_allocator;
cca78449 47public:
4ba9fb0a 48 // In-place setters.
cca78449 49 void set (tree, tree, value_range_kind = VR_RANGE);
cca78449
AH
50 void set_nonzero (tree);
51 void set_zero (tree);
cca78449
AH
52 void set_varying (tree type);
53 void set_undefined ();
54
4ba9fb0a 55 // Range types.
cca78449 56 static bool supports_type_p (tree);
4ba9fb0a 57 tree type () const;
cca78449 58
4ba9fb0a 59 // Iteration over sub-ranges.
cca78449
AH
60 unsigned num_pairs () const;
61 wide_int lower_bound (unsigned = 0) const;
62 wide_int upper_bound (unsigned) const;
63 wide_int upper_bound () const;
4ba9fb0a
AH
64
65 // Predicates.
66 bool zero_p () const;
67 bool nonzero_p () const;
68 bool undefined_p () const;
69 bool varying_p () const;
70 bool singleton_p (tree *result = NULL) const;
71 bool contains_p (tree) const;
72
73 // In-place operators.
74 void union_ (const irange &);
75 void intersect (const irange &);
ad451b02 76 void intersect (const wide_int& lb, const wide_int& ub);
cca78449
AH
77 void invert ();
78
4ba9fb0a
AH
79 // Operator overloads.
80 irange& operator= (const irange &);
81 bool operator== (const irange &) const;
82 bool operator!= (const irange &r) const { return !(*this == r); }
83
84 // Misc methods.
6a0423c5 85 bool fits_p (const irange &r) { return m_max_ranges >= r.num_pairs (); }
4ba9fb0a 86 void dump (FILE * = stderr) const;
4d907031 87 void debug () const;
4ba9fb0a
AH
88
89 // Deprecated legacy public methods.
90 enum value_range_kind kind () const; // DEPRECATED
91 tree min () const; // DEPRECATED
92 tree max () const; // DEPRECATED
93 bool symbolic_p () const; // DEPRECATED
94 bool constant_p () const; // DEPRECATED
95 void normalize_symbolics (); // DEPRECATED
96 void normalize_addresses (); // DEPRECATED
97 bool may_contain_p (tree) const; // DEPRECATED
98 void set (tree); // DEPRECATED
99 bool equal_p (const irange &) const; // DEPRECATED
100 void union_ (const class irange *); // DEPRECATED
101 void intersect (const irange *); // DEPRECATED
102
cca78449 103protected:
4ba9fb0a
AH
104 irange (tree *, unsigned);
105 // potential promotion to public?
106 tree tree_lower_bound (unsigned = 0) const;
107 tree tree_upper_bound (unsigned) const;
108 tree tree_upper_bound () const;
109
110 // In-place operators.
111 void irange_union (const irange &);
112 void irange_intersect (const irange &);
113 void irange_set (tree, tree);
114 void irange_set_anti_range (tree, tree);
115
dc80d5e8 116 void normalize_kind ();
4ba9fb0a
AH
117
118 bool legacy_mode_p () const;
119 bool legacy_equal_p (const irange &) const;
120 void legacy_union (irange *, const irange *);
121 void legacy_intersect (irange *, const irange *);
122 void verify_range ();
4ba9fb0a
AH
123 wide_int legacy_lower_bound (unsigned = 0) const;
124 wide_int legacy_upper_bound (unsigned) const;
125 int value_inside_range (tree) const;
126 bool maybe_anti_range () const;
5bcd7de6
AH
127 void copy_to_legacy (const irange &);
128 void copy_legacy_to_multi_range (const irange &);
cca78449
AH
129
130private:
3c658587
AH
131 friend void gt_ggc_mx (irange *);
132 friend void gt_pch_nx (irange *);
133 friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
134
88081d38 135 void irange_set_1bit_anti_range (tree, tree);
dc80d5e8 136 bool varying_compatible_p () const;
88081d38 137
4ba9fb0a
AH
138 unsigned char m_num_ranges;
139 unsigned char m_max_ranges;
140 ENUM_BITFIELD(value_range_kind) m_kind : 8;
141 tree *m_base;
cca78449
AH
142};
143
4ba9fb0a
AH
144// Here we describe an irange with N pairs of ranges. The storage for
145// the pairs is embedded in the class as an array.
146
147template<unsigned N>
148class GTY((user)) int_range : public irange
149{
150public:
151 int_range ();
152 int_range (tree, tree, value_range_kind = VR_RANGE);
153 int_range (tree type, const wide_int &, const wide_int &,
154 value_range_kind = VR_RANGE);
155 int_range (tree type);
156 int_range (const int_range &);
157 int_range (const irange &);
158 int_range& operator= (const int_range &);
159private:
160 template <unsigned X> friend void gt_ggc_mx (int_range<X> *);
161 template <unsigned X> friend void gt_pch_nx (int_range<X> *);
162 template <unsigned X> friend void gt_pch_nx (int_range<X> *,
163 gt_pointer_operator, void *);
3c658587 164
e53b6e56 165 // ?? These stubs are for ipa-prop.cc which use a value_range in a
3c658587
AH
166 // hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
167 // instead of picking up the gt_ggc_mx (T *) version.
4ba9fb0a
AH
168 friend void gt_ggc_mx (int_range<1> *&);
169 friend void gt_pch_nx (int_range<1> *&);
170
171 tree m_ranges[N*2];
172};
173
174// This is a special int_range<1> with only one pair, plus
175// VR_ANTI_RANGE magic to describe slightly more than can be described
176// in one pair. It is described in the code as a "legacy range" (as
177// opposed to multi-ranges which have multiple sub-ranges). It is
178// provided for backward compatibility with code that has not been
179// converted to multi-range irange's.
180//
181// There are copy operators to seamlessly copy to/fro multi-ranges.
182typedef int_range<1> value_range;
183
184// This is an "infinite" precision irange for use in temporary
185// calculations.
c5a6c223 186typedef int_range<255> int_range_max;
4ba9fb0a
AH
187
188// Returns true for an old-school value_range as described above.
189inline bool
190irange::legacy_mode_p () const
191{
192 return m_max_ranges == 1;
193}
194
195extern bool range_has_numeric_bounds_p (const irange *);
cca78449
AH
196extern bool ranges_from_anti_range (const value_range *,
197 value_range *, value_range *);
4ba9fb0a 198extern void dump_value_range (FILE *, const irange *);
cca78449
AH
199extern bool vrp_val_is_min (const_tree);
200extern bool vrp_val_is_max (const_tree);
cca78449
AH
201extern bool vrp_operand_equal_p (const_tree, const_tree);
202
4ba9fb0a
AH
203inline value_range_kind
204irange::kind () const
205{
dc80d5e8 206 return m_kind;
4ba9fb0a
AH
207}
208
209// Number of sub-ranges in a range.
210
211inline unsigned
212irange::num_pairs () const
cca78449 213{
db3581c4
AH
214 if (m_kind == VR_ANTI_RANGE)
215 return constant_p () ? 2 : 1;
4ba9fb0a 216 else
db3581c4 217 return m_num_ranges;
cca78449
AH
218}
219
4ba9fb0a
AH
220inline tree
221irange::type () const
222{
77803216 223 gcc_checking_assert (m_num_ranges > 0);
4ba9fb0a
AH
224 return TREE_TYPE (m_base[0]);
225}
226
227// Return the lower bound of a sub-range expressed as a tree. PAIR is
228// the sub-range in question.
229
230inline tree
231irange::tree_lower_bound (unsigned pair) const
232{
233 return m_base[pair * 2];
234}
235
236// Return the upper bound of a sub-range expressed as a tree. PAIR is
237// the sub-range in question.
238
239inline tree
240irange::tree_upper_bound (unsigned pair) const
cca78449 241{
4ba9fb0a 242 return m_base[pair * 2 + 1];
cca78449
AH
243}
244
4ba9fb0a
AH
245// Return the highest bound of a range expressed as a tree.
246
cca78449 247inline tree
4ba9fb0a 248irange::tree_upper_bound () const
cca78449 249{
4ba9fb0a
AH
250 gcc_checking_assert (m_num_ranges);
251 return tree_upper_bound (m_num_ranges - 1);
cca78449
AH
252}
253
254inline tree
4ba9fb0a 255irange::min () const
cca78449 256{
4ba9fb0a 257 return tree_lower_bound (0);
cca78449
AH
258}
259
260inline tree
4ba9fb0a 261irange::max () const
cca78449 262{
4ba9fb0a
AH
263 if (m_num_ranges)
264 return tree_upper_bound ();
265 else
266 return NULL;
cca78449
AH
267}
268
269inline bool
dc80d5e8 270irange::varying_compatible_p () const
cca78449 271{
4ba9fb0a
AH
272 if (m_num_ranges != 1)
273 return false;
274
275 tree l = m_base[0];
276 tree u = m_base[1];
277 tree t = TREE_TYPE (l);
dc80d5e8
AH
278
279 if (m_kind == VR_VARYING && t == error_mark_node)
280 return true;
281
3d3470e2
AH
282 unsigned prec = TYPE_PRECISION (t);
283 signop sign = TYPE_SIGN (t);
4ba9fb0a 284 if (INTEGRAL_TYPE_P (t))
3d3470e2
AH
285 return (wi::to_wide (l) == wi::min_value (prec, sign)
286 && wi::to_wide (u) == wi::max_value (prec, sign));
4ba9fb0a 287 if (POINTER_TYPE_P (t))
3d3470e2
AH
288 return (wi::to_wide (l) == 0
289 && wi::to_wide (u) == wi::max_value (prec, sign));
4ba9fb0a 290 return true;
dc80d5e8 291}
4ba9fb0a 292
dc80d5e8
AH
293inline bool
294irange::varying_p () const
295{
296 return m_kind == VR_VARYING;
cca78449
AH
297}
298
299inline bool
4ba9fb0a 300irange::undefined_p () const
cca78449
AH
301{
302 return m_kind == VR_UNDEFINED;
303}
304
305inline bool
4ba9fb0a 306irange::zero_p () const
cca78449 307{
4ba9fb0a
AH
308 return (m_kind == VR_RANGE && m_num_ranges == 1
309 && integer_zerop (tree_lower_bound (0))
310 && integer_zerop (tree_upper_bound (0)));
cca78449
AH
311}
312
313inline bool
4ba9fb0a 314irange::nonzero_p () const
cca78449 315{
4ba9fb0a
AH
316 if (undefined_p ())
317 return false;
cca78449 318
4ba9fb0a
AH
319 tree zero = build_zero_cst (type ());
320 return *this == int_range<1> (zero, zero, VR_ANTI_RANGE);
cca78449
AH
321}
322
323inline bool
4ba9fb0a 324irange::supports_type_p (tree type)
cca78449
AH
325{
326 if (type && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)))
327 return type;
328 return false;
329}
330
331inline bool
4ba9fb0a 332range_includes_zero_p (const irange *vr)
cca78449
AH
333{
334 if (vr->undefined_p ())
335 return false;
336
337 if (vr->varying_p ())
338 return true;
339
340 return vr->may_contain_p (build_zero_cst (vr->type ()));
341}
342
7b7bbbcf 343inline void
3c658587 344gt_ggc_mx (irange *x)
4ba9fb0a 345{
3c658587 346 for (unsigned i = 0; i < x->m_num_ranges; ++i)
4ba9fb0a 347 {
3c658587
AH
348 gt_ggc_mx (x->m_base[i * 2]);
349 gt_ggc_mx (x->m_base[i * 2 + 1]);
4ba9fb0a
AH
350 }
351}
352
7b7bbbcf 353inline void
3c658587 354gt_pch_nx (irange *x)
4ba9fb0a 355{
3c658587 356 for (unsigned i = 0; i < x->m_num_ranges; ++i)
4ba9fb0a 357 {
3c658587
AH
358 gt_pch_nx (x->m_base[i * 2]);
359 gt_pch_nx (x->m_base[i * 2 + 1]);
4ba9fb0a
AH
360 }
361}
362
7b7bbbcf 363inline void
3c658587 364gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie)
4ba9fb0a 365{
3c658587 366 for (unsigned i = 0; i < x->m_num_ranges; ++i)
4ba9fb0a 367 {
747380f4
JJ
368 op (&x->m_base[i * 2], NULL, cookie);
369 op (&x->m_base[i * 2 + 1], NULL, cookie);
4ba9fb0a
AH
370 }
371}
372
3c658587
AH
373template<unsigned N>
374inline void
375gt_ggc_mx (int_range<N> *x)
376{
377 gt_ggc_mx ((irange *) x);
378}
379
380template<unsigned N>
381inline void
382gt_pch_nx (int_range<N> *x)
383{
384 gt_pch_nx ((irange *) x);
385}
386
387template<unsigned N>
388inline void
389gt_pch_nx (int_range<N> *x, gt_pointer_operator op, void *cookie)
390{
391 gt_pch_nx ((irange *) x, op, cookie);
392}
393
4ba9fb0a
AH
394// Constructors for irange
395
396inline
397irange::irange (tree *base, unsigned nranges)
398{
399 m_base = base;
400 m_num_ranges = 0;
401 m_max_ranges = nranges;
dc80d5e8 402 m_kind = VR_UNDEFINED;
4ba9fb0a
AH
403}
404
405// Constructors for int_range<>.
406
407template<unsigned N>
408inline
409int_range<N>::int_range ()
410 : irange (m_ranges, N)
411{
412}
413
414template<unsigned N>
415int_range<N>::int_range (const int_range &other)
416 : irange (m_ranges, N)
417{
418 irange::operator= (other);
419}
420
421template<unsigned N>
422int_range<N>::int_range (tree min, tree max, value_range_kind kind)
423 : irange (m_ranges, N)
424{
425 irange::set (min, max, kind);
426}
427
428template<unsigned N>
429int_range<N>::int_range (tree type)
430 : irange (m_ranges, N)
431{
432 set_varying (type);
433}
434
435template<unsigned N>
436int_range<N>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
437 value_range_kind kind)
438 : irange (m_ranges, N)
439{
440 tree min = wide_int_to_tree (type, wmin);
441 tree max = wide_int_to_tree (type, wmax);
442 set (min, max, kind);
443}
444
445template<unsigned N>
446int_range<N>::int_range (const irange &other)
447 : irange (m_ranges, N)
448{
449 irange::operator= (other);
450}
451
452template<unsigned N>
453int_range<N>&
454int_range<N>::operator= (const int_range &src)
455{
456 irange::operator= (src);
457 return *this;
458}
459
460inline void
461irange::set (tree val)
462{
463 set (val, val);
464}
465
466inline void
467irange::set_undefined ()
468{
dc80d5e8 469 m_kind = VR_UNDEFINED;
4ba9fb0a 470 m_num_ranges = 0;
4ba9fb0a
AH
471}
472
473inline void
474irange::set_varying (tree type)
475{
dc80d5e8 476 m_kind = VR_VARYING;
4ba9fb0a 477 m_num_ranges = 1;
dc80d5e8 478
4ba9fb0a
AH
479 if (INTEGRAL_TYPE_P (type))
480 {
e828f4b5
AM
481 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
482 // min_value and max_value.
3d3470e2
AH
483 wide_int min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
484 wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
e828f4b5
AM
485 if (wi::eq_p (max, wi::to_wide (TYPE_MAX_VALUE (type)))
486 && wi::eq_p (min, wi::to_wide (TYPE_MIN_VALUE (type))))
487 {
488 m_base[0] = TYPE_MIN_VALUE (type);
489 m_base[1] = TYPE_MAX_VALUE (type);
490 }
491 else
492 {
493 m_base[0] = wide_int_to_tree (type, min);
494 m_base[1] = wide_int_to_tree (type, max);
495 }
4ba9fb0a
AH
496 }
497 else if (POINTER_TYPE_P (type))
498 {
499 m_base[0] = build_int_cst (type, 0);
500 m_base[1] = build_int_cst (type, -1);
501 }
502 else
503 m_base[0] = m_base[1] = error_mark_node;
504}
505
506inline bool
507irange::operator== (const irange &r) const
508{
509 return equal_p (r);
510}
511
512// Return the lower bound of a sub-range. PAIR is the sub-range in
513// question.
514
515inline wide_int
516irange::lower_bound (unsigned pair) const
517{
518 if (legacy_mode_p ())
519 return legacy_lower_bound (pair);
77803216 520 gcc_checking_assert (m_num_ranges > 0);
4ba9fb0a
AH
521 gcc_checking_assert (pair + 1 <= num_pairs ());
522 return wi::to_wide (tree_lower_bound (pair));
523}
524
525// Return the upper bound of a sub-range. PAIR is the sub-range in
526// question.
527
528inline wide_int
529irange::upper_bound (unsigned pair) const
530{
531 if (legacy_mode_p ())
532 return legacy_upper_bound (pair);
77803216 533 gcc_checking_assert (m_num_ranges > 0);
4ba9fb0a
AH
534 gcc_checking_assert (pair + 1 <= num_pairs ());
535 return wi::to_wide (tree_upper_bound (pair));
536}
537
538// Return the highest bound of a range.
539
540inline wide_int
541irange::upper_bound () const
542{
543 unsigned pairs = num_pairs ();
544 gcc_checking_assert (pairs > 0);
545 return upper_bound (pairs - 1);
546}
547
548inline void
549irange::union_ (const irange &r)
550{
551 dump_flags_t m_flags = dump_flags;
552 dump_flags &= ~TDF_DETAILS;
553 irange::union_ (&r);
554 dump_flags = m_flags;
555}
556
557inline void
558irange::intersect (const irange &r)
559{
560 dump_flags_t m_flags = dump_flags;
561 dump_flags &= ~TDF_DETAILS;
562 irange::intersect (&r);
563 dump_flags = m_flags;
564}
565
566// Set value range VR to a nonzero range of type TYPE.
567
568inline void
569irange::set_nonzero (tree type)
570{
571 tree zero = build_int_cst (type, 0);
572 if (legacy_mode_p ())
573 set (zero, zero, VR_ANTI_RANGE);
574 else
575 irange_set_anti_range (zero, zero);
576}
577
578// Set value range VR to a ZERO range of type TYPE.
579
580inline void
581irange::set_zero (tree type)
582{
583 tree z = build_int_cst (type, 0);
584 if (legacy_mode_p ())
585 set (z);
586 else
587 irange_set (z, z);
588}
589
4e85ad79 590// Normalize a range to VARYING or UNDEFINED if possible.
4ba9fb0a 591
4e85ad79 592inline void
dc80d5e8
AH
593irange::normalize_kind ()
594{
595 if (m_num_ranges == 0)
596 m_kind = VR_UNDEFINED;
597 else if (varying_compatible_p ())
4ba9fb0a 598 {
4e85ad79 599 if (m_kind == VR_RANGE)
dc80d5e8 600 m_kind = VR_VARYING;
4e85ad79 601 else if (m_kind == VR_ANTI_RANGE)
4ba9fb0a
AH
602 set_undefined ();
603 else
604 gcc_unreachable ();
4ba9fb0a 605 }
4ba9fb0a
AH
606}
607
608// Return the maximum value for TYPE.
609
610inline tree
611vrp_val_max (const_tree type)
612{
613 if (INTEGRAL_TYPE_P (type))
614 return TYPE_MAX_VALUE (type);
615 if (POINTER_TYPE_P (type))
616 {
617 wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
618 return wide_int_to_tree (const_cast<tree> (type), max);
619 }
620 return NULL_TREE;
621}
622
623// Return the minimum value for TYPE.
624
625inline tree
626vrp_val_min (const_tree type)
627{
628 if (INTEGRAL_TYPE_P (type))
629 return TYPE_MIN_VALUE (type);
630 if (POINTER_TYPE_P (type))
631 return build_zero_cst (const_cast<tree> (type));
632 return NULL_TREE;
633}
634
77a23a82
AH
635// This is the irange storage class. It is used to allocate the
636// minimum amount of storage needed for a given irange. Storage is
637// automatically freed at destruction of the storage class.
638//
639// It is meant for long term storage, as opposed to int_range_max
640// which is meant for intermediate temporary results on the stack.
641//
642// The newly allocated irange is initialized to the empty set
643// (undefined_p() is true).
644
645class irange_allocator
646{
647public:
648 irange_allocator ();
649 ~irange_allocator ();
650 // Return a new range with NUM_PAIRS.
651 irange *allocate (unsigned num_pairs);
652 // Return a copy of SRC with the minimum amount of sub-ranges needed
653 // to represent it.
654 irange *allocate (const irange &src);
14b0f37a 655 void *get_memory (unsigned num_bytes);
77a23a82
AH
656private:
657 DISABLE_COPY_AND_ASSIGN (irange_allocator);
658 struct obstack m_obstack;
659};
660
661inline
662irange_allocator::irange_allocator ()
663{
664 obstack_init (&m_obstack);
665}
666
667inline
668irange_allocator::~irange_allocator ()
669{
670 obstack_free (&m_obstack, NULL);
671}
672
8cbaa093 673// Provide a hunk of memory from the obstack.
14b0f37a
AM
674inline void *
675irange_allocator::get_memory (unsigned num_bytes)
676{
677 void *r = obstack_alloc (&m_obstack, num_bytes);
678 return r;
679}
680
77a23a82
AH
681// Return a new range with NUM_PAIRS.
682
683inline irange *
684irange_allocator::allocate (unsigned num_pairs)
685{
686 // Never allocate 0 pairs.
687 // Don't allocate 1 either, or we get legacy value_range's.
688 if (num_pairs < 2)
689 num_pairs = 2;
690
4e921302
AM
691 size_t nbytes = sizeof (tree) * 2 * num_pairs;
692
693 // Allocate the irange and required memory for the vector.
694 void *r = obstack_alloc (&m_obstack, sizeof (irange));
695 tree *mem = (tree *) obstack_alloc (&m_obstack, nbytes);
696 return new (r) irange (mem, num_pairs);
77a23a82
AH
697}
698
699inline irange *
700irange_allocator::allocate (const irange &src)
701{
702 irange *r = allocate (src.num_pairs ());
703 *r = src;
704 return r;
705}
706
cca78449 707#endif // GCC_VALUE_RANGE_H
This page took 2.316436 seconds and 5 git commands to generate.