1/* Support routines for value ranges.
2   Copyright (C) 2019-2020 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.  */
19
20#ifndef GCC_VALUE_RANGE_H
21#define GCC_VALUE_RANGE_H
22
23/* Types of value ranges.  */
24enum value_range_kind
25{
26  /* Empty range.  */
27  VR_UNDEFINED,
28  /* Range spans the entire domain.  */
29  VR_VARYING,
30  /* Range is [MIN, MAX].  */
31  VR_RANGE,
32  /* Range is ~[MIN, MAX].  */
33  VR_ANTI_RANGE,
34  /* Range is a nice guy.  */
35  VR_LAST
36};
37
38// Range of values that can be associated with an SSA_NAME.
39
40class GTY((for_user)) value_range
41{
42public:
43  value_range ();
44  value_range (tree, tree, value_range_kind = VR_RANGE);
45  value_range (tree type, const wide_int &, const wide_int &,
46	       value_range_kind = VR_RANGE);
47  value_range (tree type);
48
49  void set (tree, tree, value_range_kind = VR_RANGE);
50  void set (tree);
51  void set_nonzero (tree);
52  void set_zero (tree);
53
54  enum value_range_kind kind () const;
55  tree min () const;
56  tree max () const;
57
58  /* Types of value ranges.  */
59  bool symbolic_p () const;
60  bool constant_p () const;
61  bool undefined_p () const;
62  bool varying_p () const;
63  void set_varying (tree type);
64  void set_undefined ();
65
66  void union_ (const value_range *);
67  void intersect (const value_range *);
68  void union_ (const value_range &);
69  void intersect (const value_range &);
70
71  bool operator== (const value_range &) const;
72  bool operator!= (const value_range &) const /* = delete */;
73  bool equal_p (const value_range &) const;
74
75  /* Misc methods.  */
76  tree type () const;
77  bool may_contain_p (tree) const;
78  bool zero_p () const;
79  bool nonzero_p () const;
80  bool singleton_p (tree *result = NULL) const;
81  void dump (FILE *) const;
82  void dump () const;
83
84  static bool supports_type_p (tree);
85  void normalize_symbolics ();
86  void normalize_addresses ();
87
88  static const unsigned int m_max_pairs = 2;
89  bool contains_p (tree) const;
90  unsigned num_pairs () const;
91  wide_int lower_bound (unsigned = 0) const;
92  wide_int upper_bound (unsigned) const;
93  wide_int upper_bound () const;
94  void invert ();
95
96protected:
97  void check ();
98  static value_range union_helper (const value_range *, const value_range *);
99  static value_range intersect_helper (const value_range *,
100				       const value_range *);
101
102  friend void gt_ggc_mx_value_range (void *);
103  friend void gt_pch_p_11value_range (void *, void *,
104				      gt_pointer_operator, void *);
105  friend void gt_pch_nx_value_range (void *);
106  friend void gt_ggc_mx (value_range &);
107  friend void gt_ggc_mx (value_range *&);
108  friend void gt_pch_nx (value_range &);
109  friend void gt_pch_nx (value_range *, gt_pointer_operator, void *);
110
111  enum value_range_kind m_kind;
112  tree m_min;
113  tree m_max;
114
115private:
116  int value_inside_range (tree) const;
117};
118
119extern bool range_has_numeric_bounds_p (const value_range *);
120extern bool ranges_from_anti_range (const value_range *,
121				    value_range *, value_range *);
122extern void dump_value_range (FILE *, const value_range *);
123extern bool vrp_val_is_min (const_tree);
124extern bool vrp_val_is_max (const_tree);
125extern tree vrp_val_min (const_tree);
126extern tree vrp_val_max (const_tree);
127extern bool vrp_operand_equal_p (const_tree, const_tree);
128
129inline
130value_range::value_range ()
131{
132  m_kind = VR_UNDEFINED;
133  m_min = m_max = NULL;
134}
135
136inline value_range_kind
137value_range::kind () const
138{
139  return m_kind;
140}
141
142inline tree
143value_range::type () const
144{
145  return TREE_TYPE (min ());
146}
147
148inline tree
149value_range::min () const
150{
151  return m_min;
152}
153
154inline tree
155value_range::max () const
156{
157  return m_max;
158}
159
160inline bool
161value_range::varying_p () const
162{
163  return m_kind == VR_VARYING;
164}
165
166inline bool
167value_range::undefined_p () const
168{
169  return m_kind == VR_UNDEFINED;
170}
171
172inline bool
173value_range::zero_p () const
174{
175  return (m_kind == VR_RANGE
176	  && integer_zerop (m_min)
177	  && integer_zerop (m_max));
178}
179
180inline bool
181value_range::nonzero_p () const
182{
183  if (m_kind == VR_ANTI_RANGE
184      && !TYPE_UNSIGNED (type ())
185      && integer_zerop (m_min)
186      && integer_zerop (m_max))
187    return true;
188
189  return (m_kind == VR_RANGE
190	  && TYPE_UNSIGNED (type ())
191	  && integer_onep (m_min)
192	  && vrp_val_is_max (m_max));
193}
194
195inline bool
196value_range::supports_type_p (tree type)
197{
198  if (type && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)))
199    return type;
200  return false;
201}
202
203inline bool
204range_includes_zero_p (const value_range *vr)
205{
206  if (vr->undefined_p ())
207    return false;
208
209  if (vr->varying_p ())
210    return true;
211
212  return vr->may_contain_p (build_zero_cst (vr->type ()));
213}
214
215#endif // GCC_VALUE_RANGE_H
216