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, bool shared_p = true);
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((desc ("%h.m_discriminator"), tag("VR_UNKNOWN"))) vrange_storage
50 : {
51 : public:
52 : static vrange_storage *alloc (vrange_internal_alloc &, const vrange &,
53 : bool shared_p = true);
54 : void get_vrange (vrange &r, tree type) const;
55 : void set_vrange (const vrange &r);
56 : bool fits_p (const vrange &r) const;
57 : bool equal_p (const vrange &r) const;
58 :
59 : // Stack initialization disallowed.
60 333416718 : vrange_storage (enum value_range_discriminator d) : m_discriminator (d) { }
61 : const ENUM_BITFIELD(value_range_discriminator) m_discriminator : 4;
62 : };
63 :
64 : // Efficient memory storage for an irange.
65 :
66 : class GTY((tag ("VR_IRANGE"))) irange_storage: public vrange_storage
67 : {
68 : public:
69 : static irange_storage *alloc (vrange_internal_alloc &, const irange &);
70 : void set_irange (const irange &r);
71 : void get_irange (irange &r, tree type) const;
72 : bool equal_p (const irange &r) const;
73 : bool fits_p (const irange &r) const;
74 : void dump () const;
75 : private:
76 : DISABLE_COPY_AND_ASSIGN (irange_storage);
77 : static size_t size (const irange &r);
78 : const unsigned short *lengths_address () const;
79 : unsigned short *write_lengths_address ();
80 :
81 : // The shared precision of each number.
82 : unsigned short m_precision;
83 :
84 : // The max number of sub-ranges that fit in this storage.
85 : const unsigned char m_max_ranges;
86 :
87 : // The number of stored sub-ranges.
88 : unsigned char m_num_ranges;
89 :
90 : enum value_range_kind m_kind : 3;
91 :
92 : // The length of this is m_num_ranges * 2 + 2 to accommodate the bitmask.
93 : HOST_WIDE_INT m_val[1];
94 :
95 : // Another variable-length part of the structure following the HWIs.
96 : // This is the length of each wide_int in m_val.
97 : //
98 : // unsigned short m_len[];
99 :
100 : irange_storage (const irange &r);
101 : };
102 :
103 :
104 : // A prange_kind summarizes some common variations for a prange, and is used
105 : // in a prange_storage clas for efficiency.
106 :
107 : enum prange_kind { PR_UNDEFINED, // VR_UNDEFINED
108 : PR_VARYING, // VR_VARYING
109 : PR_ZERO, // [0, 0]
110 : PR_NONZERO, // [1, +INF] (May have bitmask)
111 : PR_FULL, // [0, +INF] (Must have bitmask)
112 : PR_OTHER }; // [x, y] (MAy have bitmask)
113 :
114 : // Maximum number of words that may be allocated by a prange_storage class.
115 : const unsigned int PRANGE_STORAGE_NINTS = 4;
116 :
117 : // Efficient memory storage for a prange.
118 : class GTY((tag ("VR_PRANGE"))) prange_storage : public vrange_storage
119 : {
120 : public:
121 : friend void gt_ggc_mx_vrange_storage(void *);
122 : friend void gt_pch_nx_vrange_storage(void *);
123 : friend void gt_pch_p_14vrange_storage(void *, void *, gt_pointer_operator,
124 : void *);
125 : static prange_storage *alloc (vrange_internal_alloc &, const prange &,
126 : bool shared_p = true);
127 : void set_prange (const prange &r);
128 : void get_prange (prange &r, tree type) const;
129 : bool equal_p (const prange &r) const;
130 : bool fits_p (const prange &r) const;
131 : void dump () const;
132 :
133 : private:
134 : DISABLE_COPY_AND_ASSIGN (prange_storage);
135 : prange_storage (const prange &r);
136 : static enum prange_kind prange_format (const prange &r, unsigned &num_words);
137 :
138 : enum prange_kind m_kind;
139 : bool m_has_bitmask;
140 : bool m_points_to_p;
141 : tree m_pt;
142 :
143 : // We don't use TRAILING_WIDE_INT_ACCESSOR because the getters here
144 : // must be const. Perhaps TRAILING_WIDE_INT_ACCESSOR could be made
145 : // const and return wide_int instead of trailing_wide_int.
146 23768403 : wide_int get_word (unsigned i, tree) const
147 29590777 : { return m_trailing_ints[i]; }
148 4876940 : template <typename T> void set_word (unsigned i, const T &x, tree)
149 4876940 : { m_trailing_ints[i] = x; }
150 :
151 : trailing_wide_ints<PRANGE_STORAGE_NINTS> m_trailing_ints;
152 : };
153 :
154 : // Efficient memory storage for an frange.
155 :
156 : class GTY((tag ("VR_FRANGE"))) frange_storage : public vrange_storage
157 : {
158 : public:
159 : static frange_storage *alloc (vrange_internal_alloc &, const frange &r);
160 : void set_frange (const frange &r);
161 : void get_frange (frange &r, tree type) const;
162 : bool equal_p (const frange &r) const;
163 : bool fits_p (const frange &) const;
164 : private:
165 12194898 : frange_storage (const frange &r) : vrange_storage (VR_FRANGE)
166 12194898 : { set_frange (r); }
167 : DISABLE_COPY_AND_ASSIGN (frange_storage);
168 :
169 : enum value_range_kind m_kind;
170 : REAL_VALUE_TYPE m_min;
171 : REAL_VALUE_TYPE m_max;
172 : bool m_pos_nan;
173 : bool m_neg_nan;
174 : };
175 :
176 : extern vrange_storage *ggc_alloc_vrange_storage (tree type);
177 : extern vrange_storage *ggc_alloc_vrange_storage (const vrange &,
178 : bool shared_p = true);
179 :
180 : #endif // GCC_VALUE_RANGE_STORAGE_H
|