1 /* Routines for restoring various data types from a file stream. This deals
2 with various data types like strings, integers, enums, etc.
4 Copyright (C) 2011-2023 Free Software Foundation, Inc.
5 Contributed by Diego Novillo <dnovillo@google.com>
7 This file is part of GCC.
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
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
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/>. */
25 #include "coretypes.h"
30 #include "data-streamer.h"
31 #include "value-range.h"
32 #include "streamer-hooks.h"
34 /* Read a string from the string table in DATA_IN using input block
35 IB. Write the length to RLEN. */
38 string_for_index (class data_in
*data_in
, unsigned int loc
, unsigned int *rlen
)
49 /* Get the string stored at location LOC in DATA_IN->STRINGS. */
50 lto_input_block
str_tab (data_in
->strings
, loc
- 1, data_in
->strings_len
, NULL
);
51 len
= streamer_read_uhwi (&str_tab
);
54 if (str_tab
.p
+ len
> data_in
->strings_len
)
55 internal_error ("bytecode stream: string too long for the string table");
57 result
= (const char *)(data_in
->strings
+ str_tab
.p
);
63 /* Read a string from the string table in DATA_IN using input block
64 IB. Write the length to RLEN. */
67 streamer_read_indexed_string (class data_in
*data_in
,
68 class lto_input_block
*ib
, unsigned int *rlen
)
70 return string_for_index (data_in
, streamer_read_uhwi (ib
), rlen
);
74 /* Read a NULL terminated string from the string table in DATA_IN. */
77 streamer_read_string (class data_in
*data_in
, class lto_input_block
*ib
)
82 ptr
= streamer_read_indexed_string (data_in
, ib
, &len
);
85 if (ptr
[len
- 1] != '\0')
86 internal_error ("bytecode stream: found non-null terminated string");
92 /* Read a string from the string table in DATA_IN using the bitpack BP.
93 Write the length to RLEN. */
96 bp_unpack_indexed_string (class data_in
*data_in
,
97 struct bitpack_d
*bp
, unsigned int *rlen
)
99 return string_for_index (data_in
, bp_unpack_var_len_unsigned (bp
), rlen
);
103 /* Read a NULL terminated string from the string table in DATA_IN. */
106 bp_unpack_string (class data_in
*data_in
, struct bitpack_d
*bp
)
111 ptr
= bp_unpack_indexed_string (data_in
, bp
, &len
);
114 if (ptr
[len
- 1] != '\0')
115 internal_error ("bytecode stream: found non-null terminated string");
121 /* Read an unsigned HOST_WIDE_INT number from IB. */
123 unsigned HOST_WIDE_INT
124 streamer_read_uhwi (class lto_input_block
*ib
)
126 unsigned HOST_WIDE_INT result
;
128 unsigned HOST_WIDE_INT byte
;
129 unsigned int p
= ib
->p
;
130 unsigned int len
= ib
->len
;
132 const char *data
= ib
->data
;
134 if ((result
& 0x80) != 0)
141 result
|= (byte
& 0x7f) << shift
;
144 while ((byte
& 0x80) != 0);
147 /* We check for section overrun after the fact for performance reason. */
149 lto_section_overrun (ib
);
156 /* Read a HOST_WIDE_INT number from IB. */
159 streamer_read_hwi (class lto_input_block
*ib
)
161 HOST_WIDE_INT result
= 0;
163 unsigned HOST_WIDE_INT byte
;
167 byte
= streamer_read_uchar (ib
);
168 result
|= (byte
& 0x7f) << shift
;
170 if ((byte
& 0x80) == 0)
172 if ((shift
< HOST_BITS_PER_WIDE_INT
) && (byte
& 0x40))
173 result
|= - (HOST_WIDE_INT_1U
<< shift
);
180 /* Read a poly_uint64 from IB. */
183 streamer_read_poly_uint64 (class lto_input_block
*ib
)
186 for (unsigned int i
= 0; i
< NUM_POLY_INT_COEFFS
; ++i
)
187 res
.coeffs
[i
] = streamer_read_uhwi (ib
);
191 /* Read a poly_int64 from IB. */
194 streamer_read_poly_int64 (class lto_input_block
*ib
)
197 for (unsigned int i
= 0; i
< NUM_POLY_INT_COEFFS
; ++i
)
198 res
.coeffs
[i
] = streamer_read_hwi (ib
);
202 /* Read gcov_type value from IB. */
205 streamer_read_gcov_count (class lto_input_block
*ib
)
207 gcov_type ret
= streamer_read_hwi (ib
);
211 /* Read REAL_VALUE_TYPE from IB. */
214 streamer_read_real_value (class lto_input_block
*ib
, REAL_VALUE_TYPE
*r
)
216 struct bitpack_d bp
= streamer_read_bitpack (ib
);
217 bp_unpack_real_value (&bp
, r
);
221 streamer_read_value_range (class lto_input_block
*ib
, data_in
*data_in
,
224 // Read the common fields to all vranges.
225 value_range_kind kind
= streamer_read_enum (ib
, value_range_kind
, VR_LAST
);
226 gcc_checking_assert (kind
!= VR_UNDEFINED
);
227 tree type
= stream_read_tree (ib
, data_in
);
229 // Initialize the Value_Range to the correct type.
232 if (is_a
<irange
> (vr
))
234 irange
&r
= as_a
<irange
> (vr
);
236 unsigned HOST_WIDE_INT num_pairs
= streamer_read_uhwi (ib
);
237 for (unsigned i
= 0; i
< num_pairs
; ++i
)
239 wide_int lb
= streamer_read_wide_int (ib
);
240 wide_int ub
= streamer_read_wide_int (ib
);
241 int_range
<2> tmp (type
, lb
, ub
);
244 wide_int value
= streamer_read_wide_int (ib
);
245 wide_int mask
= streamer_read_wide_int (ib
);
246 irange_bitmask
bm (value
, mask
);
247 r
.update_bitmask (bm
);
250 if (is_a
<frange
> (vr
))
252 frange
&r
= as_a
<frange
> (vr
);
254 // Stream in NAN bits.
255 struct bitpack_d bp
= streamer_read_bitpack (ib
);
256 bool pos_nan
= (bool) bp_unpack_value (&bp
, 1);
257 bool neg_nan
= (bool) bp_unpack_value (&bp
, 1);
258 nan_state
nan (pos_nan
, neg_nan
);
261 r
.set_nan (type
, nan
);
264 REAL_VALUE_TYPE lb
, ub
;
265 streamer_read_real_value (ib
, &lb
);
266 streamer_read_real_value (ib
, &ub
);
267 r
.set (type
, lb
, ub
, nan
);
274 /* Read the physical representation of a wide_int val from
278 streamer_read_wide_int (class lto_input_block
*ib
)
280 HOST_WIDE_INT abuf
[WIDE_INT_MAX_INL_ELTS
], *a
= abuf
;
282 int prec
= streamer_read_uhwi (ib
);
283 int len
= streamer_read_uhwi (ib
);
284 if (UNLIKELY (len
> WIDE_INT_MAX_INL_ELTS
))
285 a
= XALLOCAVEC (HOST_WIDE_INT
, len
);
286 for (i
= 0; i
< len
; i
++)
287 a
[i
] = streamer_read_hwi (ib
);
288 return wide_int::from_array (a
, len
, prec
);
291 /* Read the physical representation of a widest_int val from
295 streamer_read_widest_int (class lto_input_block
*ib
)
297 HOST_WIDE_INT abuf
[WIDE_INT_MAX_INL_ELTS
], *a
= abuf
;
299 int prec ATTRIBUTE_UNUSED
= streamer_read_uhwi (ib
);
300 int len
= streamer_read_uhwi (ib
);
301 if (UNLIKELY (len
> WIDE_INT_MAX_INL_ELTS
))
302 a
= XALLOCAVEC (HOST_WIDE_INT
, len
);
303 for (i
= 0; i
< len
; i
++)
304 a
[i
] = streamer_read_hwi (ib
);
305 return widest_int::from_array (a
, len
);