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