Home | History | Annotate | Line # | Download | only in gcc
data-streamer-in.cc revision 1.1.1.1
      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-2022 Free Software Foundation, Inc.
      5    Contributed by Diego Novillo <dnovillo (at) 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 
     32 /* Read a string from the string table in DATA_IN using input block
     33    IB.  Write the length to RLEN.  */
     34 
     35 static const char *
     36 string_for_index (class data_in *data_in, unsigned int loc, unsigned int *rlen)
     37 {
     38   unsigned int len;
     39   const char *result;
     40 
     41   if (!loc)
     42     {
     43       *rlen = 0;
     44       return NULL;
     45     }
     46 
     47   /* Get the string stored at location LOC in DATA_IN->STRINGS.  */
     48   lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len, NULL);
     49   len = streamer_read_uhwi (&str_tab);
     50   *rlen = len;
     51 
     52   if (str_tab.p + len > data_in->strings_len)
     53     internal_error ("bytecode stream: string too long for the string table");
     54 
     55   result = (const char *)(data_in->strings + str_tab.p);
     56 
     57   return result;
     58 }
     59 
     60 
     61 /* Read a string from the string table in DATA_IN using input block
     62    IB.  Write the length to RLEN.  */
     63 
     64 const char *
     65 streamer_read_indexed_string (class data_in *data_in,
     66 			      class lto_input_block *ib, unsigned int *rlen)
     67 {
     68   return string_for_index (data_in, streamer_read_uhwi (ib), rlen);
     69 }
     70 
     71 
     72 /* Read a NULL terminated string from the string table in DATA_IN.  */
     73 
     74 const char *
     75 streamer_read_string (class data_in *data_in, class lto_input_block *ib)
     76 {
     77   unsigned int len;
     78   const char *ptr;
     79 
     80   ptr = streamer_read_indexed_string (data_in, ib, &len);
     81   if (!ptr)
     82     return NULL;
     83   if (ptr[len - 1] != '\0')
     84     internal_error ("bytecode stream: found non-null terminated string");
     85 
     86   return ptr;
     87 }
     88 
     89 
     90 /* Read a string from the string table in DATA_IN using the bitpack BP.
     91    Write the length to RLEN.  */
     92 
     93 const char *
     94 bp_unpack_indexed_string (class data_in *data_in,
     95 			  struct bitpack_d *bp, unsigned int *rlen)
     96 {
     97   return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
     98 }
     99 
    100 
    101 /* Read a NULL terminated string from the string table in DATA_IN.  */
    102 
    103 const char *
    104 bp_unpack_string (class data_in *data_in, struct bitpack_d *bp)
    105 {
    106   unsigned int len;
    107   const char *ptr;
    108 
    109   ptr = bp_unpack_indexed_string (data_in, bp, &len);
    110   if (!ptr)
    111     return NULL;
    112   if (ptr[len - 1] != '\0')
    113     internal_error ("bytecode stream: found non-null terminated string");
    114 
    115   return ptr;
    116 }
    117 
    118 
    119 /* Read an unsigned HOST_WIDE_INT number from IB.  */
    120 
    121 unsigned HOST_WIDE_INT
    122 streamer_read_uhwi (class lto_input_block *ib)
    123 {
    124   unsigned HOST_WIDE_INT result;
    125   int shift;
    126   unsigned HOST_WIDE_INT byte;
    127   unsigned int p = ib->p;
    128   unsigned int len = ib->len;
    129 
    130   const char *data = ib->data;
    131   result = data[p++];
    132   if ((result & 0x80) != 0)
    133     {
    134       result &= 0x7f;
    135       shift = 7;
    136       do
    137 	{
    138 	  byte = data[p++];
    139 	  result |= (byte & 0x7f) << shift;
    140 	  shift += 7;
    141 	}
    142       while ((byte & 0x80) != 0);
    143     }
    144 
    145   /* We check for section overrun after the fact for performance reason.  */
    146   if (p > len)
    147     lto_section_overrun (ib);
    148 
    149   ib->p = p;
    150   return result;
    151 }
    152 
    153 
    154 /* Read a HOST_WIDE_INT number from IB.  */
    155 
    156 HOST_WIDE_INT
    157 streamer_read_hwi (class lto_input_block *ib)
    158 {
    159   HOST_WIDE_INT result = 0;
    160   int shift = 0;
    161   unsigned HOST_WIDE_INT byte;
    162 
    163   while (true)
    164     {
    165       byte = streamer_read_uchar (ib);
    166       result |= (byte & 0x7f) << shift;
    167       shift += 7;
    168       if ((byte & 0x80) == 0)
    169 	{
    170 	  if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40))
    171 	    result |= - (HOST_WIDE_INT_1U << shift);
    172 
    173 	  return result;
    174 	}
    175     }
    176 }
    177 
    178 /* Read a poly_uint64 from IB.  */
    179 
    180 poly_uint64
    181 streamer_read_poly_uint64 (class lto_input_block *ib)
    182 {
    183   poly_uint64 res;
    184   for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    185     res.coeffs[i] = streamer_read_uhwi (ib);
    186   return res;
    187 }
    188 
    189 /* Read a poly_int64 from IB.  */
    190 
    191 poly_int64
    192 streamer_read_poly_int64 (class lto_input_block *ib)
    193 {
    194   poly_int64 res;
    195   for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    196     res.coeffs[i] = streamer_read_hwi (ib);
    197   return res;
    198 }
    199 
    200 /* Read gcov_type value from IB.  */
    201 
    202 gcov_type
    203 streamer_read_gcov_count (class lto_input_block *ib)
    204 {
    205   gcov_type ret = streamer_read_hwi (ib);
    206   return ret;
    207 }
    208 
    209 /* Read the physical representation of a wide_int val from
    210    input block IB.  */
    211 
    212 wide_int
    213 streamer_read_wide_int (class lto_input_block *ib)
    214 {
    215   HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
    216   int i;
    217   int prec = streamer_read_uhwi (ib);
    218   int len = streamer_read_uhwi (ib);
    219   for (i = 0; i < len; i++)
    220     a[i] = streamer_read_hwi (ib);
    221   return wide_int::from_array (a, len, prec);
    222 }
    223 
    224 /* Read the physical representation of a widest_int val from
    225    input block IB.  */
    226 
    227 widest_int
    228 streamer_read_widest_int (class lto_input_block *ib)
    229 {
    230   HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
    231   int i;
    232   int prec ATTRIBUTE_UNUSED = streamer_read_uhwi (ib);
    233   int len = streamer_read_uhwi (ib);
    234   for (i = 0; i < len; i++)
    235     a[i] = streamer_read_hwi (ib);
    236   return widest_int::from_array (a, len);
    237 }
    238 
    239