LCOV - code coverage report
Current view: top level - gcc - lto-streamer.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 41.2 % 114 47
Test Date: 2026-08-01 15:33:25 Functions: 57.1 % 7 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Miscellaneous utilities for GIMPLE streaming.  Things that are used
       2              :    in both input and output are here.
       3              : 
       4              :    Copyright (C) 2009-2026 Free Software Foundation, Inc.
       5              :    Contributed by Doug Kwan <dougkwan@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 "tree-streamer.h"
      30              : #include "cgraph.h"
      31              : #include "lto-streamer.h"
      32              : #include "toplev.h"
      33              : #include "lto-section-names.h"
      34              : 
      35              : /* Statistics gathered during LTO, WPA and LTRANS.  */
      36              : struct lto_stats_d lto_stats;
      37              : 
      38              : const char *section_name_prefix = LTO_SECTION_NAME_PREFIX;
      39              : /* Set when streaming LTO for offloading compiler.  */
      40              : bool lto_stream_offload_p;
      41              : 
      42              : FILE *streamer_dump_file;
      43              : 
      44              : /* Return a string representing LTO tag TAG.  */
      45              : 
      46              : const char *
      47            0 : lto_tag_name (enum LTO_tags tag)
      48              : {
      49            0 :   if (lto_tag_is_tree_code_p (tag))
      50              :     {
      51              :       /* For tags representing tree nodes, return the name of the
      52              :          associated tree code.  */
      53            0 :       return get_tree_code_name (lto_tag_to_tree_code (tag));
      54              :     }
      55              : 
      56            0 :   if (lto_tag_is_gimple_code_p (tag))
      57              :     {
      58              :       /* For tags representing gimple statements, return the name of
      59              :          the associated gimple code.  */
      60            0 :       return gimple_code_name[lto_tag_to_gimple_code (tag)];
      61              :     }
      62              : 
      63            0 :   switch (tag)
      64              :     {
      65              :     case LTO_null:
      66              :       return "LTO_null";
      67            0 :     case LTO_bb0:
      68            0 :       return "LTO_bb0";
      69            0 :     case LTO_bb1:
      70            0 :       return "LTO_bb1";
      71            0 :     case LTO_eh_region:
      72            0 :       return "LTO_eh_region";
      73            0 :     case LTO_function:
      74            0 :       return "LTO_function";
      75            0 :     case LTO_eh_table:
      76            0 :       return "LTO_eh_table";
      77            0 :     case LTO_ert_cleanup:
      78            0 :       return "LTO_ert_cleanup";
      79            0 :     case LTO_ert_try:
      80            0 :       return "LTO_ert_try";
      81            0 :     case LTO_ert_allowed_exceptions:
      82            0 :       return "LTO_ert_allowed_exceptions";
      83            0 :     case LTO_ert_must_not_throw:
      84            0 :       return "LTO_ert_must_not_throw";
      85            0 :     case LTO_tree_pickle_reference:
      86            0 :       return "LTO_tree_pickle_reference";
      87            0 :     case LTO_global_stream_ref:
      88            0 :       return "LTO_global_sream_ref";
      89            0 :     case LTO_ssa_name_ref:
      90            0 :       return "LTO_ssa_name_ref";
      91            0 :     default:
      92            0 :       return "LTO_UNKNOWN";
      93              :     }
      94              : }
      95              : 
      96              : 
      97              : /* Get a section name for a particular type or name.  The NAME and NODE_ORDER
      98              :    fields are only used if SECTION_TYPE is LTO_section_function_body or
      99              :    LTO_section_linemap.  The callee of this function is responsible for freeing
     100              :    the returned name.  */
     101              : 
     102              : char *
     103      1041254 : lto_get_section_name (int section_type, const char *name,
     104              :                       int node_order, struct lto_file_decl_data *f)
     105              : {
     106      1041254 :   const char *add;
     107      1041254 :   char post[32];
     108      1041254 :   const char *sep = ".";
     109      1041254 :   char *buffer = NULL;
     110              : 
     111      1041254 :   if (section_type == LTO_section_function_body)
     112              :     {
     113       281177 :       gcc_assert (name != NULL);
     114       281177 :       if (name[0] == '*')
     115         8648 :         name++;
     116              : 
     117       281177 :       buffer = (char *)xmalloc (strlen (name) + 32);
     118       281177 :       sprintf (buffer, "%s.%d", name, node_order);
     119              : 
     120       281177 :       add = buffer;
     121       281177 :       sep = "";
     122              :     }
     123       760077 :   else if (section_type == LTO_section_linemap)
     124              :     {
     125        73455 :       gcc_checking_assert (!name);
     126        73455 :       const auto section_name = lto_section_name[section_type];
     127        73455 :       buffer = XNEWVEC (char, strlen (section_name) + 32);
     128        73455 :       sprintf (buffer, "%s.%d", section_name, node_order);
     129        73455 :       add = buffer;
     130              :     }
     131       686622 :   else if (section_type < LTO_N_SECTION_TYPES)
     132       686622 :     add = lto_section_name[section_type];
     133              :   else
     134            0 :     internal_error ("bytecode stream: unexpected LTO section %s", name);
     135              : 
     136              :   /* Make the section name unique so that ld -r combining sections
     137              :      doesn't confuse the reader with merged sections.
     138              : 
     139              :      For options don't add a ID, the option reader cannot deal with them
     140              :      and merging should be ok here.
     141              : 
     142              :      LTRANS files (output of wpa, input and output of ltrans) are handled
     143              :      directly inside of linker/lto-wrapper, so name uniqueness for external
     144              :      tools is not needed.
     145              :      Randomness would inhibit incremental LTO.  */
     146      1041254 :   if (section_type == LTO_section_opts || flag_ltrans)
     147       175454 :     strcpy (post, "");
     148       865800 :   else if (f != NULL)
     149       307759 :     sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
     150       558041 :   else if (flag_wpa)
     151       125534 :     strcpy (post, "");
     152              :   else
     153       432507 :     sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false));
     154      1041254 :   char *res = concat (section_name_prefix, sep, add, post, NULL);
     155      1041254 :   if (buffer)
     156       354632 :     free (buffer);
     157      1041254 :   return res;
     158              : }
     159              : 
     160              : 
     161              : /* Show various memory usage statistics related to LTO.  */
     162              : 
     163              : void
     164            0 : print_lto_report (const char *s)
     165              : {
     166            0 :   unsigned i;
     167              : 
     168            0 :   fprintf (stderr, "[%s] # of input files: "
     169              :            HOST_WIDE_INT_PRINT_UNSIGNED "\n", s, lto_stats.num_input_files);
     170              : 
     171            0 :   fprintf (stderr, "[%s] # of input cgraph nodes: "
     172              :            HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     173              :            lto_stats.num_input_cgraph_nodes);
     174              : 
     175            0 :   fprintf (stderr, "[%s] # of function bodies: "
     176              :            HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     177              :            lto_stats.num_function_bodies);
     178              : 
     179            0 :   for (i = 0; i < NUM_TREE_CODES; i++)
     180            0 :     if (lto_stats.num_trees[i])
     181            0 :       fprintf (stderr, "[%s] # of '%s' objects read: "
     182              :                HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     183              :                get_tree_code_name ((enum tree_code) i), lto_stats.num_trees[i]);
     184              : 
     185            0 :   if (flag_lto)
     186              :     {
     187            0 :       fprintf (stderr, "[%s] Compression: "
     188              :                HOST_WIDE_INT_PRINT_UNSIGNED " output bytes, "
     189              :                HOST_WIDE_INT_PRINT_UNSIGNED " compressed bytes", s,
     190              :                lto_stats.num_output_il_bytes,
     191              :                lto_stats.num_compressed_il_bytes);
     192            0 :       if (lto_stats.num_output_il_bytes > 0)
     193              :         {
     194            0 :           const float dividend = (float) lto_stats.num_compressed_il_bytes;
     195            0 :           const float divisor = (float) lto_stats.num_output_il_bytes;
     196            0 :           fprintf (stderr, " (ratio: %f)", dividend / divisor);
     197              :         }
     198            0 :       fprintf (stderr, "\n");
     199              :     }
     200              : 
     201            0 :   if (flag_wpa)
     202              :     {
     203            0 :       fprintf (stderr, "[%s] # of output files: "
     204              :                HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     205              :                lto_stats.num_output_files);
     206              : 
     207            0 :       fprintf (stderr, "[%s] # of output symtab nodes: "
     208              :                HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     209              :                lto_stats.num_output_symtab_nodes);
     210              : 
     211            0 :       fprintf (stderr, "[%s] # of output tree pickle references: "
     212              :                HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     213              :                lto_stats.num_pickle_refs_output);
     214            0 :       fprintf (stderr, "[%s] # of output tree bodies: "
     215              :                HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     216              :                lto_stats.num_tree_bodies_output);
     217              : 
     218            0 :       fprintf (stderr, "[%s] # callgraph partitions: "
     219              :                HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
     220              :                lto_stats.num_cgraph_partitions);
     221              : 
     222            0 :       fprintf (stderr, "[%s] Compression: "
     223              :                HOST_WIDE_INT_PRINT_UNSIGNED " input bytes, "
     224              :                HOST_WIDE_INT_PRINT_UNSIGNED " uncompressed bytes", s,
     225              :                lto_stats.num_input_il_bytes,
     226              :                lto_stats.num_uncompressed_il_bytes);
     227            0 :       if (lto_stats.num_input_il_bytes > 0)
     228              :         {
     229            0 :           const float dividend = (float) lto_stats.num_uncompressed_il_bytes;
     230            0 :           const float divisor = (float) lto_stats.num_input_il_bytes;
     231            0 :           fprintf (stderr, " (ratio: %f)", dividend / divisor);
     232              :         }
     233            0 :       fprintf (stderr, "\n");
     234              :     }
     235              : 
     236            0 :   for (i = 0; i < LTO_N_SECTION_TYPES; i++)
     237            0 :     fprintf (stderr, "[%s] Size of mmap'd section %s: "
     238              :              HOST_WIDE_INT_PRINT_UNSIGNED " bytes\n", s,
     239              :              lto_section_name[i], lto_stats.section_size[i]);
     240            0 : }
     241              : 
     242              : /* Initialization common to the LTO reader and writer.  */
     243              : 
     244              : void
     245        61611 : lto_streamer_init (void)
     246              : {
     247              :   /* Check that all the TS_* handled by the reader and writer routines
     248              :      match exactly the structures defined in treestruct.def.  When a
     249              :      new TS_* astructure is added, the streamer should be updated to
     250              :      handle it.  */
     251        61611 :   if (flag_checking)
     252        61605 :     streamer_check_handled_ts_structures ();
     253        61611 : }
     254              : 
     255              : 
     256              : /* Gate function for all LTO streaming passes.  */
     257              : 
     258              : bool
     259            0 : gate_lto_out (void)
     260              : {
     261            0 :   return ((flag_generate_lto || flag_generate_offload || in_lto_p)
     262              :           /* Don't bother doing anything if the program has errors.  */
     263            0 :           && !seen_error ());
     264              : }
     265              : 
     266              : /* Check that the version MAJOR.MINOR is the correct version number.  */
     267              : 
     268              : void
     269        30803 : lto_check_version (int major, int minor, const char *file_name)
     270              : {
     271        30803 :   if (major != LTO_major_version || minor != LTO_minor_version)
     272            0 :     fatal_error (input_location,
     273              :                  "bytecode stream in file %qs generated with LTO version "
     274              :                  "%d.%d instead of the expected %d.%d",
     275              :                  file_name,
     276              :                  major, minor,
     277              :                  LTO_major_version, LTO_minor_version);
     278        30803 : }
     279              : 
     280              : 
     281              : /* Initialize all the streamer hooks used for streaming GIMPLE.  */
     282              : 
     283              : void
     284        44887 : lto_streamer_hooks_init (void)
     285              : {
     286        44887 :   streamer_hooks_init ();
     287        44887 :   streamer_hooks.write_tree = lto_output_tree;
     288        44887 :   streamer_hooks.read_tree = lto_input_tree;
     289        44887 :   streamer_hooks.input_location = lto_input_location;
     290        44887 :   streamer_hooks.output_location = lto_output_location;
     291        44887 :   streamer_hooks.output_location_and_block = lto_output_location_and_block;
     292        44887 : }
        

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.