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

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.