LCOV - code coverage report
Current view: top level - gcc - lto-section-in.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.5 % 133 115
Test Date: 2026-08-01 15:33:25 Functions: 82.6 % 23 19
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Input functions for reading LTO sections.
       2              : 
       3              :    Copyright (C) 2009-2026 Free Software Foundation, Inc.
       4              :    Contributed by Kenneth Zadeck <zadeck@naturalbridge.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              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "backend.h"
      26              : #include "rtl.h"
      27              : #include "tree.h"
      28              : #include "gimple.h"
      29              : #include "cgraph.h"
      30              : #include "lto-streamer.h"
      31              : #include "lto-compress.h"
      32              : 
      33              : /* Section names.  These must correspond to the values of
      34              :    enum lto_section_type.  */
      35              : const char *lto_section_name[LTO_N_SECTION_TYPES] =
      36              : {
      37              :   "decls",
      38              :   "function_body",
      39              :   "statics",
      40              :   "symtab",
      41              :   "ext_symtab",
      42              :   "refs",
      43              :   "asm",
      44              :   "jmpfuncs",
      45              :   "pureconst",
      46              :   "reference",
      47              :   "profile",
      48              :   "symbol_nodes",
      49              :   "opts",
      50              :   "cgraphopt",
      51              :   "inline",
      52              :   "ipcp_trans",
      53              :   "icf",
      54              :   "offload_table",
      55              :   "mode_table",
      56              :   "lto",
      57              :   "ipa_sra",
      58              :   "odr_types",
      59              :   "ipa_modref",
      60              :   "linemap",
      61              : };
      62              : 
      63              : /* Hooks so that the ipa passes can call into the lto front end to get
      64              :    sections.  */
      65              : 
      66              : static struct lto_file_decl_data ** file_decl_data;
      67              : static lto_get_section_data_f* get_section_f;
      68              : static lto_free_section_data_f* free_section_f;
      69              : 
      70              : 
      71              : /* This is called from the lto front end to set up the hooks that are
      72              :    used by the ipa passes to get the data that they will
      73              :    deserialize.  */
      74              : 
      75              : void
      76        63525 : lto_set_in_hooks (struct lto_file_decl_data ** data,
      77              :                   lto_get_section_data_f* get_f,
      78              :                   lto_free_section_data_f* free_f)
      79              : {
      80        63525 :   file_decl_data = data;
      81        63525 :   get_section_f = get_f;
      82        63525 :   free_section_f = free_f;
      83        63525 : }
      84              : 
      85              : 
      86              : /* Return an array of file decl datas for all of the files passed to
      87              :    this compilation.  */
      88              : 
      89              : struct lto_file_decl_data **
      90       204634 : lto_get_file_decl_data (void)
      91              : {
      92       204634 :   gcc_assert (file_decl_data);
      93       204634 :   return file_decl_data;
      94              : }
      95              : 
      96              : /* Buffer structure for accumulating data from compression callbacks.  */
      97              : 
      98              : struct lto_buffer
      99              : {
     100              :   char *data;
     101              :   size_t length;
     102              : };
     103              : 
     104              : /* Compression callback, append LENGTH bytes from DATA to the buffer pointed
     105              :    to by OPAQUE.  */
     106              : 
     107              : static void
     108       236230 : lto_append_data (const char *data, unsigned length, void *opaque)
     109              : {
     110       236230 :   struct lto_buffer *buffer = (struct lto_buffer *) opaque;
     111              : 
     112       236230 :   buffer->data = (char *) xrealloc (buffer->data, buffer->length + length);
     113       236230 :   memcpy (buffer->data + buffer->length, data, length);
     114       236230 :   buffer->length += length;
     115       236230 : }
     116              : 
     117              : /* Header placed in returned uncompressed data streams.  Allows the
     118              :    uncompressed allocated data to be mapped back to the underlying
     119              :    compressed data for use with free_section_f.  */
     120              : 
     121              : struct lto_data_header
     122              : {
     123              :   const char *data;
     124              :   size_t len;
     125              : };
     126              : 
     127              : /* Return a char pointer to the start of a data stream for an LTO pass
     128              :    or function.  FILE_DATA indicates where to obtain the data.
     129              :    SECTION_TYPE is the type of information to be obtained.  NAME is
     130              :    the name of the function and is only used when finding a function
     131              :    body; otherwise it is NULL.  LEN is the size of the data
     132              :    returned.  */
     133              : 
     134              : const char *
     135       398371 : lto_get_section_data (struct lto_file_decl_data *file_data,
     136              :                       enum lto_section_type section_type,
     137              :                       const char *name, int order,
     138              :                       size_t *len, bool decompress)
     139              : {
     140       398371 :   const char *data = (get_section_f) (file_data, section_type, name, order,
     141              :                                       len);
     142       398371 :   const size_t header_length = sizeof (struct lto_data_header);
     143       398371 :   struct lto_data_header *header;
     144       398371 :   struct lto_buffer buffer;
     145       398371 :   struct lto_compression_stream *stream;
     146       398371 :   lto_stats.section_size[section_type] += *len;
     147              : 
     148       398371 :   if (data == NULL)
     149              :     return NULL;
     150              : 
     151              :   /* WPA->ltrans streams are not compressed with exception of function bodies
     152              :      and variable initializers that has been verbatim copied from earlier
     153              :      compilations.  */
     154       332469 :   if ((!flag_ltrans || decompress) && section_type != LTO_section_lto)
     155              :     {
     156              :       /* Create a mapping header containing the underlying data and length,
     157              :          and prepend this to the uncompression buffer.  The uncompressed data
     158              :          then follows, and a pointer to the start of the uncompressed data is
     159              :          returned.  */
     160       236230 :       header = (struct lto_data_header *) xmalloc (header_length);
     161       236230 :       header->data = data;
     162       236230 :       header->len = *len;
     163              : 
     164       236230 :       buffer.data = (char *) header;
     165       236230 :       buffer.length = header_length;
     166              : 
     167       236230 :       stream = lto_start_uncompression (lto_append_data, &buffer);
     168       236230 :       lto_uncompress_block (stream, data, *len);
     169       236230 :       lto_end_uncompression (stream,
     170              :                              file_data->lto_section_header.get_compression ());
     171              : 
     172       236230 :       *len = buffer.length - header_length;
     173       236230 :       data = buffer.data + header_length;
     174              :     }
     175              : 
     176              :   return data;
     177              : }
     178              : 
     179              : /* Return a char pointer to the start of a data stream for an LTO pass.
     180              :    FILE_DATA indicates where to obtain the data.
     181              :    SECTION_TYPE is the type of information to be obtained.
     182              :    LEN is the size of the data returned.  */
     183              : 
     184              : const char *
     185       180573 : lto_get_summary_section_data (struct lto_file_decl_data *file_data,
     186              :                               enum lto_section_type section_type, size_t *len)
     187              : {
     188       180573 :   return lto_get_section_data (file_data, section_type, NULL, 0, len);
     189              : }
     190              : 
     191              : /* Get the section data without any header parsing or uncompression.  */
     192              : 
     193              : const char *
     194        43640 : lto_get_raw_section_data (struct lto_file_decl_data *file_data,
     195              :                           enum lto_section_type section_type,
     196              :                           const char *name, int order,
     197              :                           size_t *len)
     198              : {
     199        43640 :   return (get_section_f) (file_data, section_type, name, order, len);
     200              : }
     201              : 
     202              : /* Free the data found from the above call.  The first three
     203              :    parameters are the same as above.  DATA is the data to be freed and
     204              :    LEN is the length of that data.  */
     205              : 
     206              : void
     207       294042 : lto_free_section_data (struct lto_file_decl_data *file_data,
     208              :                        enum lto_section_type section_type,
     209              :                        const char *name,
     210              :                        const char *data,
     211              :                        size_t len, bool decompress)
     212              : {
     213       294042 :   const size_t header_length = sizeof (struct lto_data_header);
     214       294042 :   const char *real_data = data - header_length;
     215       294042 :   const struct lto_data_header *header
     216              :     = (const struct lto_data_header *) real_data;
     217              : 
     218       294042 :   gcc_assert (free_section_f);
     219              : 
     220       294042 :   if (flag_ltrans && !decompress)
     221              :     {
     222        57812 :       (free_section_f) (file_data, section_type, name, data, len);
     223        57812 :       return;
     224              :     }
     225              : 
     226              :   /* The underlying data address has been extracted from the mapping header.
     227              :      Free that, then free the allocated uncompression buffer.  */
     228       236230 :   (free_section_f) (file_data, section_type, name, header->data, header->len);
     229       236230 :   free (const_cast<char *> (real_data));
     230              : }
     231              : 
     232              : /* Free data allocated by lto_get_raw_section_data.  */
     233              : 
     234              : void
     235        43640 : lto_free_raw_section_data (struct lto_file_decl_data *file_data,
     236              :                            enum lto_section_type section_type,
     237              :                            const char *name,
     238              :                            const char *data,
     239              :                            size_t len)
     240              : {
     241        43640 :   (free_section_f) (file_data, section_type, name, data, len);
     242        43640 : }
     243              : 
     244              : /* Load a section of type SECTION_TYPE from FILE_DATA, parse the
     245              :    header and then return an input block pointing to the section.  The
     246              :    raw pointer to the section is returned in DATAR and LEN.  These are
     247              :    used to free the section.  Return NULL if the section is not present.  */
     248              : 
     249              : class lto_input_block *
     250       102763 : lto_create_simple_input_block (struct lto_file_decl_data *file_data,
     251              :                                enum lto_section_type section_type,
     252              :                                const char **datar, size_t *len)
     253              : {
     254       102763 :   const char *data = lto_get_section_data (file_data, section_type, NULL, 0,
     255              :                                            len);
     256       102763 :   const struct lto_simple_header * header
     257              :     = (const struct lto_simple_header *) data;
     258              : 
     259       102763 :   int main_offset = sizeof (struct lto_simple_header);
     260              : 
     261       102763 :   if (!data)
     262              :     return NULL;
     263              : 
     264        75350 :   *datar = data;
     265       150700 :   return new lto_input_block (data + main_offset, header->main_size,
     266        75350 :                               file_data);
     267              : }
     268              : 
     269              : 
     270              : /* Close the section returned from a call to
     271              :    LTO_CREATE_SIMPLE_INPUT_BLOCK.  IB is the input block returned from
     272              :    that call.  The FILE_DATA and SECTION_TYPE are the same as what was
     273              :    passed to that call and the DATA and LEN are what was returned from
     274              :    that call.  */
     275              : 
     276              : void
     277        67726 : lto_destroy_simple_input_block (struct lto_file_decl_data *file_data,
     278              :                                 enum lto_section_type section_type,
     279              :                                 class lto_input_block *ib,
     280              :                                 const char *data, size_t len)
     281              : {
     282        67726 :   delete ib;
     283        67726 :   lto_free_section_data (file_data, section_type, NULL, data, len);
     284        67726 : }
     285              : 
     286              : /*****************************************************************************/
     287              : /* Record renamings of static declarations                                   */
     288              : /*****************************************************************************/
     289              : 
     290              : struct lto_renaming_slot
     291              : {
     292              :   const char *old_name;
     293              :   const char *new_name;
     294              : };
     295              : 
     296              : /* Returns a hash code for P.  */
     297              : 
     298              : static hashval_t
     299       295901 : hash_name (const void *p)
     300              : {
     301       295901 :   const struct lto_renaming_slot *ds = (const struct lto_renaming_slot *) p;
     302       295901 :   return (hashval_t) htab_hash_string (ds->new_name);
     303              : }
     304              : 
     305              : /* Returns nonzero if P1 and P2 are equal.  */
     306              : 
     307              : static int
     308          909 : eq_name (const void *p1, const void *p2)
     309              : {
     310          909 :   const struct lto_renaming_slot *s1 =
     311              :     (const struct lto_renaming_slot *) p1;
     312          909 :   const struct lto_renaming_slot *s2 =
     313              :     (const struct lto_renaming_slot *) p2;
     314              : 
     315          909 :   return strcmp (s1->new_name, s2->new_name) == 0;
     316              : }
     317              : 
     318              : /* Free a renaming table entry.  */
     319              : 
     320              : static void
     321            0 : renaming_slot_free (void *slot)
     322              : {
     323            0 :   struct lto_renaming_slot *s = (struct lto_renaming_slot *) slot;
     324              : 
     325            0 :   free (const_cast<void *> ((const void *) s->old_name));
     326            0 :   free (const_cast<void *> ((const void *) s->new_name));
     327            0 :   free ((void *) s);
     328            0 : }
     329              : 
     330              : /* Create an empty hash table for recording declaration renamings.  */
     331              : 
     332              : htab_t
     333        22261 : lto_create_renaming_table (void)
     334              : {
     335        22261 :   return htab_create (37, hash_name, eq_name, renaming_slot_free);
     336              : }
     337              : 
     338              : /* Record a declaration name mapping OLD_NAME -> NEW_NAME.  DECL_DATA
     339              :    holds the renaming hash table to use.  */
     340              : 
     341              : void
     342          329 : lto_record_renamed_decl (struct lto_file_decl_data *decl_data,
     343              :                          const char *old_name, const char *new_name)
     344              : {
     345          329 :   void **slot;
     346          329 :   struct lto_renaming_slot r_slot;
     347              : 
     348          329 :   r_slot.new_name = new_name;
     349          329 :   slot = htab_find_slot (decl_data->renaming_hash_table, &r_slot, INSERT);
     350          329 :   if (*slot == NULL)
     351              :     {
     352          329 :       struct lto_renaming_slot *new_slot = XNEW (struct lto_renaming_slot);
     353          329 :       new_slot->old_name = xstrdup (old_name);
     354          329 :       new_slot->new_name = xstrdup (new_name);
     355          329 :       *slot = new_slot;
     356              :     }
     357              :   else
     358            0 :     gcc_unreachable ();
     359          329 : }
     360              : 
     361              : 
     362              : /* Given a string NAME, return the string that it has been mapped to
     363              :    by lto_record_renamed_decl.  If NAME was not renamed, it is
     364              :    returned unchanged.  DECL_DATA holds the renaming hash table to use.  */
     365              : 
     366              : const char *
     367       295572 : lto_get_decl_name_mapping (struct lto_file_decl_data *decl_data,
     368              :                            const char *name)
     369              : {
     370       295572 :   htab_t renaming_hash_table = decl_data->renaming_hash_table;
     371       295572 :   struct lto_renaming_slot *slot;
     372       295572 :   struct lto_renaming_slot r_slot;
     373              : 
     374       295572 :   r_slot.new_name = name;
     375       295572 :   slot = (struct lto_renaming_slot *) htab_find (renaming_hash_table, &r_slot);
     376       295572 :   if (slot)
     377          485 :     return slot->old_name;
     378              :   else
     379              :     return name;
     380              : }
     381              : 
     382              : /*****************************************************************************/
     383              : /* Input decl state object.                                                  */
     384              : /*****************************************************************************/
     385              : 
     386              : /* Return a newly created in-decl state object. */
     387              : 
     388              : struct lto_in_decl_state *
     389       158107 : lto_new_in_decl_state (void)
     390              : {
     391       158107 :   return ggc_cleared_alloc<lto_in_decl_state> ();
     392              : }
     393              : 
     394              : /* Delete STATE and its components. */
     395              : 
     396              : void
     397            0 : lto_delete_in_decl_state (struct lto_in_decl_state *state)
     398              : {
     399            0 :   int i;
     400              : 
     401            0 :   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
     402            0 :     vec_free (state->streams[i]);
     403            0 :   ggc_free (state);
     404            0 : }
     405              : 
     406              : /* Search the in-decl state of a function FUNC contained in the file
     407              :    associated with FILE_DATA.  Return NULL if not found.  */
     408              : 
     409              : struct lto_in_decl_state*
     410       218926 : lto_get_function_in_decl_state (struct lto_file_decl_data *file_data,
     411              :                                 tree func)
     412              : {
     413       218926 :   struct lto_in_decl_state temp;
     414       218926 :   lto_in_decl_state **slot;
     415              : 
     416       218926 :   temp.fn_decl = func;
     417       218926 :   slot = file_data->function_decl_states->find_slot (&temp, NO_INSERT);
     418       218926 :   return slot? *slot : NULL;
     419              : }
     420              : 
     421              : /* Free decl_states.  */
     422              : 
     423              : void
     424       123505 : lto_free_function_in_decl_state (struct lto_in_decl_state *state)
     425              : {
     426       123505 :   int i;
     427       247010 :   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
     428       246595 :     vec_free (state->streams[i]);
     429       123505 :   ggc_free (state);
     430       123505 : }
     431              : 
     432              : /* Free decl_states associated with NODE.  This makes it possible to further
     433              :    release trees needed by the NODE's body.  */
     434              : 
     435              : void
     436    151326803 : lto_free_function_in_decl_state_for_node (symtab_node *node)
     437              : {
     438    151326803 :   struct lto_in_decl_state temp;
     439    151326803 :   lto_in_decl_state **slot;
     440              : 
     441    151326803 :   if (!node->lto_file_data)
     442    150976467 :     return;
     443              : 
     444       350336 :   temp.fn_decl = node->decl;
     445       350336 :   slot
     446       350336 :     = node->lto_file_data->function_decl_states->find_slot (&temp, NO_INSERT);
     447       350336 :   if (slot && *slot)
     448              :     {
     449       101244 :       lto_free_function_in_decl_state (*slot);
     450       101244 :       node->lto_file_data->function_decl_states->clear_slot (slot);
     451              :     }
     452              : }
     453              : 
     454              : 
     455              : /* Report read pass end of the section.  */
     456              : 
     457              : void
     458            0 : lto_section_overrun (class lto_input_block *ib)
     459              : {
     460            0 :   fatal_error (input_location, "bytecode stream: trying to read %d bytes "
     461            0 :                "after the end of the input buffer", ib->p - ib->len);
     462              : }
     463              : 
     464              : /* Report out of range value.  */
     465              : 
     466              : void
     467            0 : lto_value_range_error (const char *purpose, HOST_WIDE_INT val,
     468              :                        HOST_WIDE_INT min, HOST_WIDE_INT max)
     469              : {
     470            0 :   fatal_error (input_location,
     471              :                "%s out of range: Range is %i to %i, value is %i",
     472              :                purpose, (int)min, (int)max, (int)val);
     473              : }
        

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.