Branch data Line data Source code
1 : : /* Routines for restoring various data types from a file stream. This deals
2 : : with various data types like strings, integers, enums, etc.
3 : :
4 : : Copyright (C) 2011-2024 Free Software Foundation, Inc.
5 : : Contributed by Diego Novillo <dnovillo@google.com>
6 : :
7 : : This file is part of GCC.
8 : :
9 : : GCC is free software; you can redistribute it and/or modify it under
10 : : the terms of the GNU General Public License as published by the Free
11 : : Software Foundation; either version 3, or (at your option) any later
12 : : version.
13 : :
14 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 : : for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GCC; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "coretypes.h"
26 : : #include "backend.h"
27 : : #include "tree.h"
28 : : #include "gimple.h"
29 : : #include "cgraph.h"
30 : : #include "data-streamer.h"
31 : : #include "value-range.h"
32 : : #include "streamer-hooks.h"
33 : :
34 : : /* Read a string from the string table in DATA_IN using input block
35 : : IB. Write the length to RLEN. */
36 : :
37 : : static const char *
38 : 2323806 : string_for_index (class data_in *data_in, unsigned int loc, unsigned int *rlen)
39 : : {
40 : 2323806 : unsigned int len;
41 : 2323806 : const char *result;
42 : :
43 : 2323806 : if (!loc)
44 : : {
45 : 1064517 : *rlen = 0;
46 : 1064517 : return NULL;
47 : : }
48 : :
49 : : /* Get the string stored at location LOC in DATA_IN->STRINGS. */
50 : 1259289 : lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len, NULL);
51 : 1259289 : len = streamer_read_uhwi (&str_tab);
52 : 1259289 : *rlen = len;
53 : :
54 : 1259289 : if (str_tab.p + len > data_in->strings_len)
55 : 0 : internal_error ("bytecode stream: string too long for the string table");
56 : :
57 : 1259289 : result = (const char *)(data_in->strings + str_tab.p);
58 : :
59 : 1259289 : return result;
60 : : }
61 : :
62 : :
63 : : /* Read a string from the string table in DATA_IN using input block
64 : : IB. Write the length to RLEN. */
65 : :
66 : : const char *
67 : 1737641 : streamer_read_indexed_string (class data_in *data_in,
68 : : class lto_input_block *ib, unsigned int *rlen)
69 : : {
70 : 1737641 : return string_for_index (data_in, streamer_read_uhwi (ib), rlen);
71 : : }
72 : :
73 : :
74 : : /* Read a NULL terminated string from the string table in DATA_IN. */
75 : :
76 : : const char *
77 : 898251 : streamer_read_string (class data_in *data_in, class lto_input_block *ib)
78 : : {
79 : 898251 : unsigned int len;
80 : 898251 : const char *ptr;
81 : :
82 : 898251 : ptr = streamer_read_indexed_string (data_in, ib, &len);
83 : 898251 : if (!ptr)
84 : : return NULL;
85 : 43688 : if (ptr[len - 1] != '\0')
86 : 0 : internal_error ("bytecode stream: found non-null terminated string");
87 : :
88 : : return ptr;
89 : : }
90 : :
91 : :
92 : : /* Read a string from the string table in DATA_IN using the bitpack BP.
93 : : Write the length to RLEN. */
94 : :
95 : : const char *
96 : 586165 : bp_unpack_indexed_string (class data_in *data_in,
97 : : struct bitpack_d *bp, unsigned int *rlen)
98 : : {
99 : 586165 : return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
100 : : }
101 : :
102 : :
103 : : /* Read a NULL terminated string from the string table in DATA_IN. */
104 : :
105 : : const char *
106 : 586165 : bp_unpack_string (class data_in *data_in, struct bitpack_d *bp)
107 : : {
108 : 586165 : unsigned int len;
109 : 586165 : const char *ptr;
110 : :
111 : 586165 : ptr = bp_unpack_indexed_string (data_in, bp, &len);
112 : 586165 : if (!ptr)
113 : : return NULL;
114 : 376275 : if (ptr[len - 1] != '\0')
115 : 0 : internal_error ("bytecode stream: found non-null terminated string");
116 : :
117 : : return ptr;
118 : : }
119 : :
120 : :
121 : : /* Read an unsigned HOST_WIDE_INT number from IB. */
122 : :
123 : : unsigned HOST_WIDE_INT
124 : 66737996 : streamer_read_uhwi (class lto_input_block *ib)
125 : : {
126 : 66737996 : unsigned HOST_WIDE_INT result;
127 : 66737996 : int shift;
128 : 66737996 : unsigned HOST_WIDE_INT byte;
129 : 66737996 : unsigned int p = ib->p;
130 : 66737996 : unsigned int len = ib->len;
131 : :
132 : 66737996 : const char *data = ib->data;
133 : 66737996 : result = data[p++];
134 : 66737996 : if ((result & 0x80) != 0)
135 : : {
136 : 15629453 : result &= 0x7f;
137 : 15629453 : shift = 7;
138 : 42583415 : do
139 : : {
140 : 42583415 : byte = data[p++];
141 : 42583415 : result |= (byte & 0x7f) << shift;
142 : 42583415 : shift += 7;
143 : : }
144 : 42583415 : while ((byte & 0x80) != 0);
145 : : }
146 : :
147 : : /* We check for section overrun after the fact for performance reason. */
148 : 66737996 : if (p > len)
149 : 0 : lto_section_overrun (ib);
150 : :
151 : 66737996 : ib->p = p;
152 : 66737996 : return result;
153 : : }
154 : :
155 : :
156 : : /* Read a HOST_WIDE_INT number from IB. */
157 : :
158 : : HOST_WIDE_INT
159 : 30021608 : streamer_read_hwi (class lto_input_block *ib)
160 : : {
161 : 30021608 : HOST_WIDE_INT result = 0;
162 : 30021608 : int shift = 0;
163 : 47320269 : unsigned HOST_WIDE_INT byte;
164 : :
165 : 47320269 : while (true)
166 : : {
167 : 47320269 : byte = streamer_read_uchar (ib);
168 : 47320269 : result |= (byte & 0x7f) << shift;
169 : 47320269 : shift += 7;
170 : 47320269 : if ((byte & 0x80) == 0)
171 : : {
172 : 30021608 : if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40))
173 : 4264239 : result |= - (HOST_WIDE_INT_1U << shift);
174 : :
175 : 30021608 : return result;
176 : : }
177 : : }
178 : : }
179 : :
180 : : /* Read a poly_uint64 from IB. */
181 : :
182 : : poly_uint64
183 : 0 : streamer_read_poly_uint64 (class lto_input_block *ib)
184 : : {
185 : 0 : poly_uint64 res;
186 : 0 : for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
187 : 0 : res.coeffs[i] = streamer_read_uhwi (ib);
188 : 0 : return res;
189 : : }
190 : :
191 : : /* Read a poly_int64 from IB. */
192 : :
193 : : poly_int64
194 : 48904 : streamer_read_poly_int64 (class lto_input_block *ib)
195 : : {
196 : 48904 : poly_int64 res;
197 : 97808 : for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
198 : 48904 : res.coeffs[i] = streamer_read_hwi (ib);
199 : 48904 : return res;
200 : : }
201 : :
202 : : /* Read gcov_type value from IB. */
203 : :
204 : : gcov_type
205 : 1507379 : streamer_read_gcov_count (class lto_input_block *ib)
206 : : {
207 : 1507379 : gcov_type ret = streamer_read_hwi (ib);
208 : 1507379 : return ret;
209 : : }
210 : :
211 : : /* Read REAL_VALUE_TYPE from IB. */
212 : :
213 : : void
214 : 0 : streamer_read_real_value (class lto_input_block *ib, REAL_VALUE_TYPE *r)
215 : : {
216 : 0 : struct bitpack_d bp = streamer_read_bitpack (ib);
217 : 0 : bp_unpack_real_value (&bp, r);
218 : 0 : }
219 : :
220 : : void
221 : 409472 : streamer_read_value_range (class lto_input_block *ib, data_in *data_in,
222 : : Value_Range &vr)
223 : : {
224 : : // Read the common fields to all vranges.
225 : 409472 : value_range_kind kind = streamer_read_enum (ib, value_range_kind, VR_LAST);
226 : 409472 : gcc_checking_assert (kind != VR_UNDEFINED);
227 : 409472 : tree type = stream_read_tree (ib, data_in);
228 : :
229 : : // Initialize the Value_Range to the correct type.
230 : 409472 : vr.set_type (type);
231 : :
232 : 409472 : if (is_a <irange> (vr))
233 : : {
234 : 409472 : irange &r = as_a <irange> (vr);
235 : 409472 : r.set_undefined ();
236 : 409472 : unsigned HOST_WIDE_INT num_pairs = streamer_read_uhwi (ib);
237 : 825980 : for (unsigned i = 0; i < num_pairs; ++i)
238 : : {
239 : 416508 : wide_int lb = streamer_read_wide_int (ib);
240 : 416508 : wide_int ub = streamer_read_wide_int (ib);
241 : 416508 : int_range<2> tmp (type, lb, ub);
242 : 416508 : r.union_ (tmp);
243 : 416512 : }
244 : 409472 : wide_int value = streamer_read_wide_int (ib);
245 : 409472 : wide_int mask = streamer_read_wide_int (ib);
246 : 409472 : irange_bitmask bm (value, mask);
247 : 409472 : r.update_bitmask (bm);
248 : 409472 : return;
249 : 409476 : }
250 : 0 : if (is_a <frange> (vr))
251 : : {
252 : 0 : frange &r = as_a <frange> (vr);
253 : :
254 : : // Stream in NAN bits.
255 : 0 : struct bitpack_d bp = streamer_read_bitpack (ib);
256 : 0 : bool pos_nan = (bool) bp_unpack_value (&bp, 1);
257 : 0 : bool neg_nan = (bool) bp_unpack_value (&bp, 1);
258 : 0 : nan_state nan (pos_nan, neg_nan);
259 : :
260 : 0 : if (kind == VR_NAN)
261 : 0 : r.set_nan (type, nan);
262 : : else
263 : : {
264 : 0 : REAL_VALUE_TYPE lb, ub;
265 : 0 : streamer_read_real_value (ib, &lb);
266 : 0 : streamer_read_real_value (ib, &ub);
267 : 0 : r.set (type, lb, ub, nan);
268 : : }
269 : 0 : return;
270 : : }
271 : 0 : gcc_unreachable ();
272 : : }
273 : :
274 : : /* Read the physical representation of a wide_int val from
275 : : input block IB. */
276 : :
277 : : wide_int
278 : 1653592 : streamer_read_wide_int (class lto_input_block *ib)
279 : : {
280 : 1653592 : HOST_WIDE_INT abuf[WIDE_INT_MAX_INL_ELTS], *a = abuf;
281 : 1653592 : int i;
282 : 1653592 : int prec = streamer_read_uhwi (ib);
283 : 1653592 : int len = streamer_read_uhwi (ib);
284 : 1653592 : if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
285 : 0 : a = XALLOCAVEC (HOST_WIDE_INT, len);
286 : 3314299 : for (i = 0; i < len; i++)
287 : 1660707 : a[i] = streamer_read_hwi (ib);
288 : 1653592 : return wide_int::from_array (a, len, prec);
289 : : }
290 : :
291 : : /* Read the physical representation of a widest_int val from
292 : : input block IB. */
293 : :
294 : : widest_int
295 : 89689 : streamer_read_widest_int (class lto_input_block *ib)
296 : : {
297 : 89689 : HOST_WIDE_INT abuf[WIDE_INT_MAX_INL_ELTS], *a = abuf;
298 : 89689 : int i;
299 : 89689 : int prec ATTRIBUTE_UNUSED = streamer_read_uhwi (ib);
300 : 89689 : int len = streamer_read_uhwi (ib);
301 : 89689 : if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
302 : 0 : a = XALLOCAVEC (HOST_WIDE_INT, len);
303 : 180384 : for (i = 0; i < len; i++)
304 : 90695 : a[i] = streamer_read_hwi (ib);
305 : 89689 : return widest_int::from_array (a, len);
306 : : }
307 : :
|