11debfc3dSmrg /* Routines for restoring various data types from a file stream. This deals
21debfc3dSmrg with various data types like strings, integers, enums, etc.
31debfc3dSmrg
4*8feb0f0bSmrg Copyright (C) 2011-2020 Free Software Foundation, Inc.
51debfc3dSmrg Contributed by Diego Novillo <dnovillo@google.com>
61debfc3dSmrg
71debfc3dSmrg This file is part of GCC.
81debfc3dSmrg
91debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
101debfc3dSmrg the terms of the GNU General Public License as published by the Free
111debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
121debfc3dSmrg version.
131debfc3dSmrg
141debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
151debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
161debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
171debfc3dSmrg for more details.
181debfc3dSmrg
191debfc3dSmrg You should have received a copy of the GNU General Public License
201debfc3dSmrg along with GCC; see the file COPYING3. If not see
211debfc3dSmrg <http://www.gnu.org/licenses/>. */
221debfc3dSmrg
231debfc3dSmrg #include "config.h"
241debfc3dSmrg #include "system.h"
251debfc3dSmrg #include "coretypes.h"
261debfc3dSmrg #include "backend.h"
271debfc3dSmrg #include "tree.h"
281debfc3dSmrg #include "gimple.h"
291debfc3dSmrg #include "cgraph.h"
301debfc3dSmrg #include "data-streamer.h"
311debfc3dSmrg
321debfc3dSmrg /* Read a string from the string table in DATA_IN using input block
331debfc3dSmrg IB. Write the length to RLEN. */
341debfc3dSmrg
351debfc3dSmrg static const char *
string_for_index(class data_in * data_in,unsigned int loc,unsigned int * rlen)36*8feb0f0bSmrg string_for_index (class data_in *data_in, unsigned int loc, unsigned int *rlen)
371debfc3dSmrg {
381debfc3dSmrg unsigned int len;
391debfc3dSmrg const char *result;
401debfc3dSmrg
411debfc3dSmrg if (!loc)
421debfc3dSmrg {
431debfc3dSmrg *rlen = 0;
441debfc3dSmrg return NULL;
451debfc3dSmrg }
461debfc3dSmrg
471debfc3dSmrg /* Get the string stored at location LOC in DATA_IN->STRINGS. */
481debfc3dSmrg lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len, NULL);
491debfc3dSmrg len = streamer_read_uhwi (&str_tab);
501debfc3dSmrg *rlen = len;
511debfc3dSmrg
521debfc3dSmrg if (str_tab.p + len > data_in->strings_len)
531debfc3dSmrg internal_error ("bytecode stream: string too long for the string table");
541debfc3dSmrg
551debfc3dSmrg result = (const char *)(data_in->strings + str_tab.p);
561debfc3dSmrg
571debfc3dSmrg return result;
581debfc3dSmrg }
591debfc3dSmrg
601debfc3dSmrg
611debfc3dSmrg /* Read a string from the string table in DATA_IN using input block
621debfc3dSmrg IB. Write the length to RLEN. */
631debfc3dSmrg
641debfc3dSmrg const char *
streamer_read_indexed_string(class data_in * data_in,class lto_input_block * ib,unsigned int * rlen)65*8feb0f0bSmrg streamer_read_indexed_string (class data_in *data_in,
66*8feb0f0bSmrg class lto_input_block *ib, unsigned int *rlen)
671debfc3dSmrg {
681debfc3dSmrg return string_for_index (data_in, streamer_read_uhwi (ib), rlen);
691debfc3dSmrg }
701debfc3dSmrg
711debfc3dSmrg
721debfc3dSmrg /* Read a NULL terminated string from the string table in DATA_IN. */
731debfc3dSmrg
741debfc3dSmrg const char *
streamer_read_string(class data_in * data_in,class lto_input_block * ib)75*8feb0f0bSmrg streamer_read_string (class data_in *data_in, class lto_input_block *ib)
761debfc3dSmrg {
771debfc3dSmrg unsigned int len;
781debfc3dSmrg const char *ptr;
791debfc3dSmrg
801debfc3dSmrg ptr = streamer_read_indexed_string (data_in, ib, &len);
811debfc3dSmrg if (!ptr)
821debfc3dSmrg return NULL;
831debfc3dSmrg if (ptr[len - 1] != '\0')
841debfc3dSmrg internal_error ("bytecode stream: found non-null terminated string");
851debfc3dSmrg
861debfc3dSmrg return ptr;
871debfc3dSmrg }
881debfc3dSmrg
891debfc3dSmrg
901debfc3dSmrg /* Read a string from the string table in DATA_IN using the bitpack BP.
911debfc3dSmrg Write the length to RLEN. */
921debfc3dSmrg
931debfc3dSmrg const char *
bp_unpack_indexed_string(class data_in * data_in,struct bitpack_d * bp,unsigned int * rlen)94*8feb0f0bSmrg bp_unpack_indexed_string (class data_in *data_in,
951debfc3dSmrg struct bitpack_d *bp, unsigned int *rlen)
961debfc3dSmrg {
971debfc3dSmrg return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
981debfc3dSmrg }
991debfc3dSmrg
1001debfc3dSmrg
1011debfc3dSmrg /* Read a NULL terminated string from the string table in DATA_IN. */
1021debfc3dSmrg
1031debfc3dSmrg const char *
bp_unpack_string(class data_in * data_in,struct bitpack_d * bp)104*8feb0f0bSmrg bp_unpack_string (class data_in *data_in, struct bitpack_d *bp)
1051debfc3dSmrg {
1061debfc3dSmrg unsigned int len;
1071debfc3dSmrg const char *ptr;
1081debfc3dSmrg
1091debfc3dSmrg ptr = bp_unpack_indexed_string (data_in, bp, &len);
1101debfc3dSmrg if (!ptr)
1111debfc3dSmrg return NULL;
1121debfc3dSmrg if (ptr[len - 1] != '\0')
1131debfc3dSmrg internal_error ("bytecode stream: found non-null terminated string");
1141debfc3dSmrg
1151debfc3dSmrg return ptr;
1161debfc3dSmrg }
1171debfc3dSmrg
1181debfc3dSmrg
1191debfc3dSmrg /* Read an unsigned HOST_WIDE_INT number from IB. */
1201debfc3dSmrg
1211debfc3dSmrg unsigned HOST_WIDE_INT
streamer_read_uhwi(class lto_input_block * ib)122*8feb0f0bSmrg streamer_read_uhwi (class lto_input_block *ib)
1231debfc3dSmrg {
1241debfc3dSmrg unsigned HOST_WIDE_INT result;
1251debfc3dSmrg int shift;
1261debfc3dSmrg unsigned HOST_WIDE_INT byte;
1271debfc3dSmrg unsigned int p = ib->p;
1281debfc3dSmrg unsigned int len = ib->len;
1291debfc3dSmrg
1301debfc3dSmrg const char *data = ib->data;
1311debfc3dSmrg result = data[p++];
1321debfc3dSmrg if ((result & 0x80) != 0)
1331debfc3dSmrg {
1341debfc3dSmrg result &= 0x7f;
1351debfc3dSmrg shift = 7;
1361debfc3dSmrg do
1371debfc3dSmrg {
1381debfc3dSmrg byte = data[p++];
1391debfc3dSmrg result |= (byte & 0x7f) << shift;
1401debfc3dSmrg shift += 7;
1411debfc3dSmrg }
1421debfc3dSmrg while ((byte & 0x80) != 0);
1431debfc3dSmrg }
1441debfc3dSmrg
1451debfc3dSmrg /* We check for section overrun after the fact for performance reason. */
1461debfc3dSmrg if (p > len)
1471debfc3dSmrg lto_section_overrun (ib);
1481debfc3dSmrg
1491debfc3dSmrg ib->p = p;
1501debfc3dSmrg return result;
1511debfc3dSmrg }
1521debfc3dSmrg
1531debfc3dSmrg
1541debfc3dSmrg /* Read a HOST_WIDE_INT number from IB. */
1551debfc3dSmrg
1561debfc3dSmrg HOST_WIDE_INT
streamer_read_hwi(class lto_input_block * ib)157*8feb0f0bSmrg streamer_read_hwi (class lto_input_block *ib)
1581debfc3dSmrg {
1591debfc3dSmrg HOST_WIDE_INT result = 0;
1601debfc3dSmrg int shift = 0;
1611debfc3dSmrg unsigned HOST_WIDE_INT byte;
1621debfc3dSmrg
1631debfc3dSmrg while (true)
1641debfc3dSmrg {
1651debfc3dSmrg byte = streamer_read_uchar (ib);
1661debfc3dSmrg result |= (byte & 0x7f) << shift;
1671debfc3dSmrg shift += 7;
1681debfc3dSmrg if ((byte & 0x80) == 0)
1691debfc3dSmrg {
1701debfc3dSmrg if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40))
1711debfc3dSmrg result |= - (HOST_WIDE_INT_1U << shift);
1721debfc3dSmrg
1731debfc3dSmrg return result;
1741debfc3dSmrg }
1751debfc3dSmrg }
1761debfc3dSmrg }
1771debfc3dSmrg
178*8feb0f0bSmrg /* Read a poly_uint64 from IB. */
179*8feb0f0bSmrg
180*8feb0f0bSmrg poly_uint64
streamer_read_poly_uint64(class lto_input_block * ib)181*8feb0f0bSmrg streamer_read_poly_uint64 (class lto_input_block *ib)
182*8feb0f0bSmrg {
183*8feb0f0bSmrg poly_uint64 res;
184*8feb0f0bSmrg for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
185*8feb0f0bSmrg res.coeffs[i] = streamer_read_uhwi (ib);
186*8feb0f0bSmrg return res;
187*8feb0f0bSmrg }
188*8feb0f0bSmrg
1891debfc3dSmrg /* Read gcov_type value from IB. */
1901debfc3dSmrg
1911debfc3dSmrg gcov_type
streamer_read_gcov_count(class lto_input_block * ib)192*8feb0f0bSmrg streamer_read_gcov_count (class lto_input_block *ib)
1931debfc3dSmrg {
1941debfc3dSmrg gcov_type ret = streamer_read_hwi (ib);
1951debfc3dSmrg return ret;
1961debfc3dSmrg }
1971debfc3dSmrg
1981debfc3dSmrg /* Read the physical representation of a wide_int val from
1991debfc3dSmrg input block IB. */
2001debfc3dSmrg
2011debfc3dSmrg wide_int
streamer_read_wide_int(class lto_input_block * ib)202*8feb0f0bSmrg streamer_read_wide_int (class lto_input_block *ib)
2031debfc3dSmrg {
2041debfc3dSmrg HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
2051debfc3dSmrg int i;
2061debfc3dSmrg int prec = streamer_read_uhwi (ib);
2071debfc3dSmrg int len = streamer_read_uhwi (ib);
2081debfc3dSmrg for (i = 0; i < len; i++)
2091debfc3dSmrg a[i] = streamer_read_hwi (ib);
2101debfc3dSmrg return wide_int::from_array (a, len, prec);
2111debfc3dSmrg }
2121debfc3dSmrg
2131debfc3dSmrg /* Read the physical representation of a widest_int val from
2141debfc3dSmrg input block IB. */
2151debfc3dSmrg
2161debfc3dSmrg widest_int
streamer_read_widest_int(class lto_input_block * ib)217*8feb0f0bSmrg streamer_read_widest_int (class lto_input_block *ib)
2181debfc3dSmrg {
2191debfc3dSmrg HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
2201debfc3dSmrg int i;
2211debfc3dSmrg int prec ATTRIBUTE_UNUSED = streamer_read_uhwi (ib);
2221debfc3dSmrg int len = streamer_read_uhwi (ib);
2231debfc3dSmrg for (i = 0; i < len; i++)
2241debfc3dSmrg a[i] = streamer_read_hwi (ib);
2251debfc3dSmrg return widest_int::from_array (a, len);
2261debfc3dSmrg }
2271debfc3dSmrg
228