Line data Source code
1 : /* Support routines for vrange storage.
2 : Copyright (C) 2022-2026 Free Software Foundation, Inc.
3 : Contributed by Aldy Hernandez <aldyh@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef GCC_VALUE_RANGE_STORAGE_H
22 : #define GCC_VALUE_RANGE_STORAGE_H
23 :
24 : // This class is used to allocate chunks of memory that can store
25 : // ranges as memory efficiently as possible.
26 :
27 : class vrange_allocator
28 : {
29 : public:
30 : // Use GC memory when GC is true, otherwise use obstacks.
31 : vrange_allocator (bool gc = false);
32 : ~vrange_allocator ();
33 : class vrange_storage *clone (const vrange &r);
34 : vrange_storage *clone_varying (tree type);
35 : vrange_storage *clone_undefined (tree type);
36 : void *alloc (size_t size);
37 : void free (void *);
38 : private:
39 : DISABLE_COPY_AND_ASSIGN (vrange_allocator);
40 : class vrange_internal_alloc *m_alloc;
41 : };
42 :
43 : // Efficient memory storage for a vrange.
44 : //
45 : // The GTY marker here does nothing but get gengtype to generate the
46 : // ggc_test_and_set_mark calls. We ignore the derived classes, since
47 : // they don't contain any pointers.
48 :
49 : class GTY(()) vrange_storage
50 : {
51 : public:
52 : static vrange_storage *alloc (vrange_internal_alloc &, const vrange &);
53 : void get_vrange (vrange &r, tree type) const;
54 : void set_vrange (const vrange &r);
55 : bool fits_p (const vrange &r) const;
56 : bool equal_p (const vrange &r) const;
57 : protected:
58 : // Stack initialization disallowed.
59 329849921 : vrange_storage () { }
60 : };
61 :
62 : // Efficient memory storage for an irange.
63 :
64 : class irange_storage : public vrange_storage
65 : {
66 : public:
67 : static irange_storage *alloc (vrange_internal_alloc &, const irange &);
68 : void set_irange (const irange &r);
69 : void get_irange (irange &r, tree type) const;
70 : bool equal_p (const irange &r) const;
71 : bool fits_p (const irange &r) const;
72 : void dump () const;
73 : private:
74 : DISABLE_COPY_AND_ASSIGN (irange_storage);
75 : static size_t size (const irange &r);
76 : const unsigned short *lengths_address () const;
77 : unsigned short *write_lengths_address ();
78 :
79 : // The shared precision of each number.
80 : unsigned short m_precision;
81 :
82 : // The max number of sub-ranges that fit in this storage.
83 : const unsigned char m_max_ranges;
84 :
85 : // The number of stored sub-ranges.
86 : unsigned char m_num_ranges;
87 :
88 : enum value_range_kind m_kind : 3;
89 :
90 : // The length of this is m_num_ranges * 2 + 2 to accommodate the bitmask.
91 : HOST_WIDE_INT m_val[1];
92 :
93 : // Another variable-length part of the structure following the HWIs.
94 : // This is the length of each wide_int in m_val.
95 : //
96 : // unsigned short m_len[];
97 :
98 : irange_storage (const irange &r);
99 : };
100 :
101 : // Efficient memory storage for a prange.
102 :
103 : class prange_storage : public vrange_storage
104 : {
105 : public:
106 : static prange_storage *alloc (vrange_internal_alloc &, const prange &);
107 : void set_prange (const prange &r);
108 : void get_prange (prange &r, tree type) const;
109 : bool equal_p (const prange &r) const;
110 : bool fits_p (const prange &r) const;
111 : void dump () const;
112 : private:
113 : DISABLE_COPY_AND_ASSIGN (prange_storage);
114 : prange_storage (const prange &r);
115 :
116 : // A prange_format class summarizes the storage requirements for a prange
117 : // which are then used to initialize the prange_storage fields.
118 : enum prange_kind { PR_UNDEFINED, // VR_UNDEFINED
119 : PR_VARYING, // VR_VARYING
120 : PR_ZERO, // [0, 0]
121 : PR_NONZERO, // [1, +INF]
122 : PR_FULL, // [0, +INF] (Must have bitmask)
123 : PR_OTHER }; // [x, y]
124 : class prange_format
125 : {
126 : public:
127 : prange_format (const prange &r);
128 : enum prange_kind kind;
129 : bool has_bitmask;
130 : size_t extra_size;
131 : unsigned short precision;
132 : unsigned num_words;
133 : };
134 :
135 : enum prange_kind m_kind;
136 : bool m_has_bitmask;
137 :
138 : // We don't use TRAILING_WIDE_INT_ACCESSOR because the getters here
139 : // must be const. Perhaps TRAILING_WIDE_INT_ACCESSOR could be made
140 : // const and return wide_int instead of trailing_wide_int.
141 10876361 : wide_int get_word (unsigned i, tree) const
142 16050615 : { return m_trailing_ints[i]; }
143 2487248 : template <typename T> void set_word (unsigned i, const T &x, tree)
144 2487248 : { m_trailing_ints[i] = x; }
145 :
146 : static const unsigned int NINTS = 4;
147 : trailing_wide_ints<NINTS> m_trailing_ints;
148 : };
149 :
150 : // Efficient memory storage for an frange.
151 :
152 : class frange_storage : public vrange_storage
153 : {
154 : public:
155 : static frange_storage *alloc (vrange_internal_alloc &, const frange &r);
156 : void set_frange (const frange &r);
157 : void get_frange (frange &r, tree type) const;
158 : bool equal_p (const frange &r) const;
159 : bool fits_p (const frange &) const;
160 : private:
161 12162009 : frange_storage (const frange &r) { set_frange (r); }
162 : DISABLE_COPY_AND_ASSIGN (frange_storage);
163 :
164 : enum value_range_kind m_kind;
165 : REAL_VALUE_TYPE m_min;
166 : REAL_VALUE_TYPE m_max;
167 : bool m_pos_nan;
168 : bool m_neg_nan;
169 : };
170 :
171 : extern vrange_storage *ggc_alloc_vrange_storage (tree type);
172 : extern vrange_storage *ggc_alloc_vrange_storage (const vrange &);
173 :
174 : #endif // GCC_VALUE_RANGE_STORAGE_H
|