xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/data-streamer-in.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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