LCOV - code coverage report
Current view: top level - gcc - data-streamer.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.1 % 102 95
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 8 8
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Generic streaming support for various data types.
       2              : 
       3              :    Copyright (C) 2011-2026 Free Software Foundation, Inc.
       4              :    Contributed by Diego Novillo <dnovillo@google.com>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #ifndef GCC_DATA_STREAMER_H
      23              : #define GCC_DATA_STREAMER_H
      24              : 
      25              : #include "lto-streamer.h"
      26              : 
      27              : /* Data structures used to pack values and bitflags into a vector of
      28              :    words.  Used to stream values of a fixed number of bits in a space
      29              :    efficient way.  */
      30              : static unsigned const BITS_PER_BITPACK_WORD = HOST_BITS_PER_WIDE_INT;
      31              : 
      32              : typedef unsigned HOST_WIDE_INT bitpack_word_t;
      33              : 
      34              : struct bitpack_d
      35              : {
      36              :   /* The position of the first unused or unconsumed bit in the word.  */
      37              :   unsigned pos;
      38              : 
      39              :   /* The current word we are (un)packing.  */
      40              :   bitpack_word_t word;
      41              : 
      42              :   /* The lto_output_stream or the lto_input_block we are streaming to/from.  */
      43              :   void *stream;
      44              : };
      45              : 
      46              : /* In data-streamer.cc  */
      47              : void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT);
      48              : void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT);
      49              : void bp_pack_real_value (struct bitpack_d *, const REAL_VALUE_TYPE *);
      50              : void bp_unpack_real_value (struct bitpack_d *, REAL_VALUE_TYPE *);
      51              : unsigned HOST_WIDE_INT bp_unpack_var_len_unsigned (struct bitpack_d *);
      52              : HOST_WIDE_INT bp_unpack_var_len_int (struct bitpack_d *);
      53              : extern unsigned host_num_poly_int_coeffs;
      54              : 
      55              : /* In data-streamer-out.cc  */
      56              : void streamer_write_zero (struct output_block *);
      57              : void streamer_write_uhwi (struct output_block *, unsigned HOST_WIDE_INT);
      58              : void streamer_write_hwi (struct output_block *, HOST_WIDE_INT);
      59              : void streamer_write_poly_uint64 (struct output_block *, poly_uint64);
      60              : void streamer_write_poly_int64 (struct output_block *, poly_int64);
      61              : void streamer_write_gcov_count (struct output_block *, gcov_type);
      62              : void streamer_write_string (struct output_block *, struct lto_output_stream *,
      63              :                             const char *, bool);
      64              : void streamer_write_string_with_length (struct output_block *,
      65              :                                         struct lto_output_stream *,
      66              :                                         const char *, unsigned int, bool);
      67              : void bp_pack_string_with_length (struct output_block *, struct bitpack_d *,
      68              :                                  const char *, unsigned int, bool);
      69              : void bp_pack_string (struct output_block *, struct bitpack_d *,
      70              :                      const char *, bool);
      71              : void streamer_write_uhwi_stream (struct lto_output_stream *,
      72              :                                  unsigned HOST_WIDE_INT);
      73              : void streamer_write_hwi_stream (struct lto_output_stream *, HOST_WIDE_INT);
      74              : void streamer_write_gcov_count_stream (struct lto_output_stream *, gcov_type);
      75              : void streamer_write_data_stream (struct lto_output_stream *, const void *,
      76              :                                  size_t);
      77              : void streamer_write_wide_int (struct output_block *, const wide_int &);
      78              : void streamer_write_widest_int (struct output_block *, const widest_int &);
      79              : void streamer_write_vrange (struct output_block *, const class vrange &);
      80              : 
      81              : /* In data-streamer-in.cc  */
      82              : const char *streamer_read_string (class data_in *, class lto_input_block *);
      83              : const char *streamer_read_indexed_string (class data_in *,
      84              :                                           class lto_input_block *,
      85              :                                           unsigned int *);
      86              : const char *bp_unpack_indexed_string (class data_in *, struct bitpack_d *,
      87              :                                       unsigned int *);
      88              : const char *bp_unpack_string (class data_in *, struct bitpack_d *);
      89              : unsigned HOST_WIDE_INT streamer_read_uhwi (class lto_input_block *);
      90              : HOST_WIDE_INT streamer_read_hwi (class lto_input_block *);
      91              : poly_uint64 streamer_read_poly_uint64 (class lto_input_block *);
      92              : poly_int64 streamer_read_poly_int64 (class lto_input_block *);
      93              : gcov_type streamer_read_gcov_count (class lto_input_block *);
      94              : wide_int streamer_read_wide_int (class lto_input_block *);
      95              : widest_int streamer_read_widest_int (class lto_input_block *);
      96              : void streamer_read_value_range (class lto_input_block *, class data_in *,
      97              :                                 class value_range &);
      98              : 
      99              : /* Returns a new bit-packing context for bit-packing into S.  */
     100              : inline struct bitpack_d
     101     15941439 : bitpack_create (struct lto_output_stream *s)
     102              : {
     103     15941439 :   struct bitpack_d bp;
     104     15941439 :   bp.pos = 0;
     105     15941439 :   bp.word = 0;
     106     15941439 :   bp.stream = (void *)s;
     107     15941439 :   return bp;
     108              : }
     109              : 
     110              : /* Pack the NBITS bit sized value VAL into the bit-packing context BP.  */
     111              : inline void
     112    273116328 : bp_pack_value (struct bitpack_d *bp, bitpack_word_t val, unsigned nbits)
     113              : {
     114    273116328 :   bitpack_word_t word = bp->word;
     115    273116328 :   int pos = bp->pos;
     116              : 
     117              :   /* Verify that VAL fits in the NBITS.  */
     118    273116328 :   gcc_checking_assert (nbits == BITS_PER_BITPACK_WORD
     119              :                        || !(val & ~(((bitpack_word_t)1<<nbits)-1)));
     120              : 
     121              :   /* If val does not fit into the current bitpack word switch to the
     122              :      next one.  */
     123    273116328 :   if (pos + nbits > BITS_PER_BITPACK_WORD)
     124              :     {
     125      4617093 :       streamer_write_uhwi_stream ((struct lto_output_stream *) bp->stream,
     126              :                                   word);
     127      4617093 :       word = val;
     128      4617093 :       pos = nbits;
     129              :     }
     130              :   else
     131              :     {
     132    268499235 :       word |= val << pos;
     133    268499235 :       pos += nbits;
     134              :     }
     135    273116328 :   bp->word = word;
     136    273116328 :   bp->pos = pos;
     137    273116328 : }
     138              : 
     139              : /* Pack VAL into the bit-packing context BP, using NBITS for each
     140              :    coefficient.  */
     141              : inline void
     142              : bp_pack_poly_value (struct bitpack_d *bp,
     143              :                     const poly_int<NUM_POLY_INT_COEFFS, bitpack_word_t> &val,
     144              :                     unsigned nbits)
     145              : {
     146            0 :   for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
     147            0 :     bp_pack_value (bp, val.coeffs[i], nbits);
     148              : }
     149              : 
     150              : /* Finishes bit-packing of BP.  */
     151              : inline void
     152     15969863 : streamer_write_bitpack (struct bitpack_d *bp)
     153              : {
     154     15969863 :   streamer_write_uhwi_stream ((struct lto_output_stream *) bp->stream,
     155     15141162 :                               bp->word);
     156     15969863 :   bp->word = 0;
     157      7892515 :   bp->pos = 0;
     158       716546 : }
     159              : 
     160              : /* Returns a new bit-packing context for bit-unpacking from IB.  */
     161              : inline struct bitpack_d
     162     11468078 : streamer_read_bitpack (class lto_input_block *ib)
     163              : {
     164     11468078 :   struct bitpack_d bp;
     165     11468078 :   bp.word = streamer_read_uhwi (ib);
     166     11468078 :   bp.pos = 0;
     167     11468078 :   bp.stream = (void *)ib;
     168     11468078 :   return bp;
     169              : }
     170              : 
     171              : /* Unpacks NBITS bits from the bit-packing context BP and returns them.  */
     172              : inline bitpack_word_t
     173    172659255 : bp_unpack_value (struct bitpack_d *bp, unsigned nbits)
     174              : {
     175    172659255 :   bitpack_word_t mask, val;
     176    172659255 :   int pos = bp->pos;
     177              : 
     178    343790208 :   mask = (nbits == BITS_PER_BITPACK_WORD
     179    172659255 :           ? (bitpack_word_t) -1
     180    171130953 :           : ((bitpack_word_t) 1 << nbits) - 1);
     181              : 
     182              :   /* If there are not continuous nbits in the current bitpack word
     183              :      switch to the next one.  */
     184    172659255 :   if (pos + nbits > BITS_PER_BITPACK_WORD)
     185              :     {
     186      6179502 :       bp->word = val
     187      3089751 :         = streamer_read_uhwi ((class lto_input_block *)bp->stream);
     188      3089751 :       bp->pos = nbits;
     189      3089751 :       return val & mask;
     190              :     }
     191    169569504 :   val = bp->word;
     192    169569504 :   val >>= pos;
     193    169569504 :   bp->pos = pos + nbits;
     194              : 
     195    169569504 :   return val & mask;
     196              : }
     197              : 
     198              : /* Common code for reading poly_int.  */
     199              : 
     200              : template<typename C, typename F, typename ...Args>
     201              : poly_int<NUM_POLY_INT_COEFFS, C>
     202        55632 : poly_int_read_common (F read_coeff, Args ...args)
     203              : {
     204              :   poly_int<NUM_POLY_INT_COEFFS, C> x;
     205              :   unsigned i;
     206              : 
     207              : #ifdef ACCEL_COMPILER
     208              :   /* Ensure that we have streamed-in host_num_poly_int_coeffs.  */
     209              :   const unsigned num_poly_int_coeffs = host_num_poly_int_coeffs;
     210              :   gcc_assert (host_num_poly_int_coeffs > 0);
     211              : #else
     212        55632 :   const unsigned num_poly_int_coeffs = NUM_POLY_INT_COEFFS;
     213              : #endif
     214              : 
     215              :   if (num_poly_int_coeffs <= NUM_POLY_INT_COEFFS)
     216              :     {
     217       111264 :       for (i = 0; i < num_poly_int_coeffs; i++)
     218        55632 :         x.coeffs[i] = read_coeff (args...);
     219        55632 :       for (; i < NUM_POLY_INT_COEFFS; i++)
     220              :         x.coeffs[i] = 0;
     221              :     }
     222              :   else
     223              :     {
     224              :       for (i = 0; i < NUM_POLY_INT_COEFFS; i++)
     225              :         x.coeffs[i] = read_coeff (args...);
     226              : 
     227              :       /* Ensure that degree of poly_int <= accel NUM_POLY_INT_COEFFS.  */
     228              :       for (; i < num_poly_int_coeffs; i++)
     229              :         {
     230              :           C val = read_coeff (args...);
     231              :           if (val != 0)
     232              :             fatal_error (input_location,
     233              :                          "degree of %<poly_int%> exceeds "
     234              :                          "%<NUM_POLY_INT_COEFFS%> (%d)",
     235              :                          NUM_POLY_INT_COEFFS);
     236              :         }
     237              :     }
     238              :   return x;
     239              : }
     240              : 
     241              : /* Unpacks a polynomial value from the bit-packing context BP in which each
     242              :    coefficient has NBITS bits.  */
     243              : inline poly_int<NUM_POLY_INT_COEFFS, bitpack_word_t>
     244            0 : bp_unpack_poly_value (struct bitpack_d *bp, unsigned nbits)
     245              : {
     246            0 :   return poly_int_read_common<bitpack_word_t> (bp_unpack_value, bp, nbits);
     247              : }
     248              : 
     249              : 
     250              : /* Write a character to the output block.  */
     251              : 
     252              : inline void
     253     15274010 : streamer_write_char_stream (struct lto_output_stream *obs, char c)
     254              : {
     255              :   /* No space left.  */
     256     15274010 :   if (obs->left_in_block == 0)
     257       152783 :     lto_append_block (obs);
     258              : 
     259              :   /* Write the actual character.  */
     260     15274010 :   char *current_pointer = obs->current_pointer;
     261     15274010 :   *(current_pointer++) = c;
     262     15274010 :   obs->current_pointer = current_pointer;
     263     15274010 :   obs->total_size++;
     264     15274010 :   obs->left_in_block--;
     265     15274010 : }
     266              : 
     267              : 
     268              : /* Read byte from the input block.  */
     269              : 
     270              : inline unsigned char
     271     50114318 : streamer_read_uchar (class lto_input_block *ib)
     272              : {
     273     50114318 :   if (ib->p >= ib->len)
     274            0 :     lto_section_overrun (ib);
     275     50114318 :   return (ib->data[ib->p++]);
     276              : }
     277              : 
     278              : /* Output VAL into OBS and verify it is in range MIN...MAX that is supposed
     279              :    to be compile time constant.
     280              :    Be host independent, limit range to 31bits.  */
     281              : 
     282              : inline void
     283     30271339 : streamer_write_hwi_in_range (struct lto_output_stream *obs,
     284              :                                   HOST_WIDE_INT min,
     285              :                                   HOST_WIDE_INT max,
     286              :                                   HOST_WIDE_INT val)
     287              : {
     288     30271339 :   HOST_WIDE_INT range = max - min;
     289              : 
     290     29354919 :   gcc_checking_assert (val >= min && val <= max && range > 0
     291              :                        && range < 0x7fffffff);
     292              : 
     293     30271339 :   val -= min;
     294     30271339 :   streamer_write_uhwi_stream (obs, (unsigned HOST_WIDE_INT) val);
     295     29280402 : }
     296              : 
     297              : /* Input VAL into OBS and verify it is in range MIN...MAX that is supposed
     298              :    to be compile time constant.  PURPOSE is used for error reporting.  */
     299              : 
     300              : inline HOST_WIDE_INT
     301     21502604 : streamer_read_hwi_in_range (class lto_input_block *ib,
     302              :                                  const char *purpose,
     303              :                                  HOST_WIDE_INT min,
     304              :                                  HOST_WIDE_INT max)
     305              : {
     306     21502604 :   HOST_WIDE_INT range = max - min;
     307     21502604 :   unsigned HOST_WIDE_INT uval = streamer_read_uhwi (ib);
     308              : 
     309     21502604 :   gcc_checking_assert (range > 0 && range < 0x7fffffff);
     310              : 
     311     21502604 :   HOST_WIDE_INT val = (HOST_WIDE_INT) (uval + (unsigned HOST_WIDE_INT) min);
     312     21502604 :   if (val < min || val > max)
     313            0 :     lto_value_range_error (purpose, val, min, max);
     314     21502604 :   return val;
     315              : }
     316              : 
     317              : /* Output VAL into BP and verify it is in range MIN...MAX that is supposed
     318              :    to be compile time constant.
     319              :    Be host independent, limit range to 31bits.  */
     320              : 
     321              : inline void
     322     10685412 : bp_pack_int_in_range (struct bitpack_d *bp,
     323              :                       HOST_WIDE_INT min,
     324              :                       HOST_WIDE_INT max,
     325              :                       HOST_WIDE_INT val)
     326              : {
     327     10685412 :   HOST_WIDE_INT range = max - min;
     328     10685412 :   int nbits = floor_log2 (range) + 1;
     329              : 
     330     10685412 :   gcc_checking_assert (val >= min && val <= max && range > 0
     331              :                        && range < 0x7fffffff);
     332              : 
     333     10685412 :   val -= min;
     334     10685412 :   bp_pack_value (bp, val, nbits);
     335     10685412 : }
     336              : 
     337              : /* Input VAL into BP and verify it is in range MIN...MAX that is supposed
     338              :    to be compile time constant.  PURPOSE is used for error reporting.  */
     339              : 
     340              : inline HOST_WIDE_INT
     341      7189304 : bp_unpack_int_in_range (struct bitpack_d *bp,
     342              :                         const char *purpose,
     343              :                         HOST_WIDE_INT min,
     344              :                         HOST_WIDE_INT max)
     345              : {
     346      7189304 :   HOST_WIDE_INT range = max - min;
     347      7189304 :   int nbits = floor_log2 (range) + 1;
     348      7189304 :   HOST_WIDE_INT val = bp_unpack_value (bp, nbits);
     349              : 
     350      7189304 :   gcc_checking_assert (range > 0 && range < 0x7fffffff);
     351              : 
     352      7189304 :   if (val < min || val > max)
     353            0 :     lto_value_range_error (purpose, val, min, max);
     354      7189304 :   return val;
     355              : }
     356              : 
     357              : /* Output VAL of type "enum enum_name" into OBS.
     358              :    Assume range 0...ENUM_LAST - 1.  */
     359              : #define streamer_write_enum(obs,enum_name,enum_last,val) \
     360              :   streamer_write_hwi_in_range ((obs), 0, (int)(enum_last) - 1, (int)(val))
     361              : 
     362              : /* Input enum of type "enum enum_name" from IB.
     363              :    Assume range 0...ENUM_LAST - 1.  */
     364              : #define streamer_read_enum(ib,enum_name,enum_last) \
     365              :   (enum enum_name)streamer_read_hwi_in_range ((ib), #enum_name, 0, \
     366              :                                               (int)(enum_last) - 1)
     367              : 
     368              : /* Output VAL of type "enum enum_name" into BP.
     369              :    Assume range 0...ENUM_LAST - 1.  */
     370              : #define bp_pack_enum(bp,enum_name,enum_last,val) \
     371              :   bp_pack_int_in_range ((bp), 0, (int)(enum_last) - 1, (int)(val))
     372              : 
     373              : /* Input enum of type "enum enum_name" from BP.
     374              :    Assume range 0...ENUM_LAST - 1.  */
     375              : #define bp_unpack_enum(bp,enum_name,enum_last) \
     376              :   (enum enum_name)bp_unpack_int_in_range ((bp), #enum_name, 0, \
     377              :                                         (int)(enum_last) - 1)
     378              : 
     379              : /* Output the start of a record with TAG to output block OB.  */
     380              : 
     381              : inline void
     382     27991756 : streamer_write_record_start (struct output_block *ob, enum LTO_tags tag)
     383              : {
     384     27991756 :   streamer_write_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS, tag);
     385      2436044 : }
     386              : 
     387              : /* Return the next tag in the input block IB.  */
     388              : 
     389              : inline enum LTO_tags
     390     19954292 : streamer_read_record_start (class lto_input_block *ib)
     391              : {
     392     19954292 :   return streamer_read_enum (ib, LTO_tags, LTO_NUM_TAGS);
     393              : }
     394              : 
     395              : #endif  /* GCC_DATA_STREAMER_H  */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.