LCOV - code coverage report
Current view: top level - gcc - lto-section-out.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 98.9 % 95 94
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 14 14
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Functions for writing 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 "data-streamer.h"
      31              : #include "langhooks.h"
      32              : #include "lto-compress.h"
      33              : #include "print-tree.h"
      34              : 
      35              : static vec<lto_out_decl_state_ptr> decl_state_stack;
      36              : 
      37              : /* List of out decl states used by functions.  We use this to
      38              :    generate the decl directory later. */
      39              : 
      40              : vec<lto_out_decl_state_ptr> lto_function_decl_states;
      41              : 
      42              : 
      43              : /*****************************************************************************
      44              :    Output routines shared by all of the serialization passes.
      45              : *****************************************************************************/
      46              : 
      47              : 
      48              : /* Flush compressed stream data function, sends NUM_CHARS from CHARS
      49              :    to the append lang hook, OPAQUE is currently always NULL.  */
      50              : 
      51              : static void
      52       330801 : lto_append_data (const char *chars, unsigned int num_chars, void *opaque)
      53              : {
      54       330801 :   gcc_assert (opaque == NULL);
      55       330801 :   lang_hooks.lto.append_data (chars, num_chars, opaque);
      56       330801 : }
      57              : 
      58              : /* Pointer to the current compression stream.  */
      59              : 
      60              : static struct lto_compression_stream *compression_stream = NULL;
      61              : 
      62              : /* Begin a new output section named NAME. If COMPRESS is true, zlib compress
      63              :    the section. */
      64              : 
      65              : void
      66       536323 : lto_begin_section (const char *name, bool compress)
      67              : {
      68       536323 :   lang_hooks.lto.begin_section (name);
      69              : 
      70       536323 :   if (streamer_dump_file)
      71              :     {
      72           68 :       if (flag_dump_unnumbered || flag_dump_noaddr)
      73           84 :           fprintf (streamer_dump_file, "Creating %ssection\n",
      74              :                    compress ? "compressed " : "");
      75              :         else
      76            0 :           fprintf (streamer_dump_file, "Creating %ssection %s\n",
      77              :                    compress ? "compressed " : "", name);
      78              :     }
      79       536323 :   gcc_assert (compression_stream == NULL);
      80       536323 :   if (compress)
      81       330801 :     compression_stream = lto_start_compression (lto_append_data, NULL);
      82       536323 : }
      83              : 
      84              : 
      85              : /* End the current output section.  */
      86              : 
      87              : void
      88       536323 : lto_end_section (void)
      89              : {
      90       536323 :   if (compression_stream)
      91              :     {
      92       330801 :       lto_end_compression (compression_stream);
      93       330801 :       compression_stream = NULL;
      94              :     }
      95       536323 :   lang_hooks.lto.end_section ();
      96       536323 : }
      97              : 
      98              : /* Write SIZE bytes starting at DATA to the assembler.  */
      99              : 
     100              : void
     101      5215243 : lto_write_data (const void *data, unsigned int size)
     102              : {
     103      5215243 :   if (compression_stream)
     104       625899 :     lto_compress_block (compression_stream, (const char *)data, size);
     105              :   else
     106      4589344 :     lang_hooks.lto.append_data ((const char *)data, size, NULL);
     107      5215243 : }
     108              : 
     109              : /* Write SIZE bytes starting at DATA to the assembler.  */
     110              : 
     111              : void
     112        34034 : lto_write_raw_data (const void *data, unsigned int size)
     113              : {
     114        34034 :   lang_hooks.lto.append_data ((const char *)data, size, NULL);
     115        34034 : }
     116              : 
     117              : /* Write all of the chars in OBS to the assembler.  Recycle the blocks
     118              :    in obs as this is being done.  */
     119              : 
     120              : void
     121       795288 : lto_write_stream (struct lto_output_stream *obs)
     122              : {
     123       795288 :   unsigned int block_size = 1024;
     124       795288 :   struct lto_char_ptr_base *block;
     125       795288 :   struct lto_char_ptr_base *next_block;
     126       795288 :   if (!obs->first_block)
     127              :     return;
     128              : 
     129      1357396 :   for (block = obs->first_block; block; block = next_block)
     130              :     {
     131       701501 :       const char *base = ((char *)block) + sizeof (struct lto_char_ptr_base);
     132       701501 :       unsigned int num_chars = block_size - sizeof (struct lto_char_ptr_base);
     133              : 
     134              :       /* If this is not the last block, it is full.  If it is the last
     135              :          block, left_in_block indicates how many chars are unoccupied in
     136              :          this block; subtract from num_chars to obtain occupancy.  */
     137       701501 :       next_block = (struct lto_char_ptr_base *) block->ptr;
     138       701501 :       if (!next_block)
     139       655895 :         num_chars -= obs->left_in_block;
     140              : 
     141       701501 :       if (compression_stream)
     142       611500 :         lto_compress_block (compression_stream, base, num_chars);
     143              :       else
     144        90001 :         lang_hooks.lto.append_data (base, num_chars, block);
     145       701501 :       free (block);
     146       701501 :       block_size *= 2;
     147              :     }
     148              : }
     149              : 
     150              : /* Create the output block and return it.  */
     151              : 
     152              : struct lto_simple_output_block *
     153       110639 : lto_create_simple_output_block (enum lto_section_type section_type)
     154              : {
     155       110639 :   struct lto_simple_output_block *ob
     156              :     = ((struct lto_simple_output_block *)
     157       110639 :        xcalloc (1, sizeof (struct lto_simple_output_block)));
     158              : 
     159       110639 :   ob->section_type = section_type;
     160       110639 :   ob->decl_state = lto_get_out_decl_state ();
     161       221278 :   ob->main_stream = ((struct lto_output_stream *)
     162       110639 :                      xcalloc (1, sizeof (struct lto_output_stream)));
     163              : 
     164       110639 :   return ob;
     165              : }
     166              : 
     167              : 
     168              : /* Produce a simple section for one of the ipa passes.  */
     169              : 
     170              : void
     171       110639 : lto_destroy_simple_output_block (struct lto_simple_output_block *ob)
     172              : {
     173       110639 :   char *section_name;
     174       110639 :   struct lto_simple_header header;
     175              : 
     176       110639 :   section_name = lto_get_section_name (ob->section_type, NULL, 0, NULL);
     177       110639 :   lto_begin_section (section_name, !flag_wpa);
     178       110639 :   free (section_name);
     179              : 
     180              :   /* Write the header which says how to decode the pieces of the
     181              :      t.  */
     182       110639 :   memset (&header, 0, sizeof (struct lto_simple_header));
     183       110639 :   header.main_size = ob->main_stream->total_size;
     184       110639 :   lto_write_data (&header, sizeof header);
     185              : 
     186       110639 :   lto_write_stream (ob->main_stream);
     187              : 
     188              :   /* Put back the assembly section that was there before we started
     189              :      writing lto info.  */
     190       110639 :   lto_end_section ();
     191              : 
     192       110639 :   free (ob->main_stream);
     193       110639 :   free (ob);
     194       110639 : }
     195              : 
     196              : 
     197              : /* Return a new lto_out_decl_state. */
     198              : 
     199              : struct lto_out_decl_state *
     200       183657 : lto_new_out_decl_state (void)
     201              : {
     202       183657 :   struct lto_out_decl_state *state = XCNEW (struct lto_out_decl_state);
     203       183657 :   int i;
     204              : 
     205       550971 :   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
     206       183657 :     lto_init_tree_ref_encoder (&state->streams[i]);
     207              : 
     208              :   /* At WPA time we do not compress sections by default.  */
     209       183657 :   state->compressed = !flag_wpa;
     210              : 
     211       183657 :   return state;
     212              : }
     213              : 
     214              : 
     215              : /* Delete STATE and components.  */
     216              : 
     217              : void
     218       183657 : lto_delete_out_decl_state (struct lto_out_decl_state *state)
     219              : {
     220       183657 :   int i;
     221              : 
     222       367314 :   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
     223       183657 :     lto_destroy_tree_ref_encoder (&state->streams[i]);
     224              : 
     225       183657 :   free (state);
     226       183657 : }
     227              : 
     228              : 
     229              : /* Get the currently used lto_out_decl_state structure. */
     230              : 
     231              : struct lto_out_decl_state *
     232       756357 : lto_get_out_decl_state (void)
     233              : {
     234       756357 :   return decl_state_stack.last ();
     235              : }
     236              : 
     237              : /* Push STATE to top of out decl stack. */
     238              : 
     239              : void
     240       183657 : lto_push_out_decl_state (struct lto_out_decl_state *state)
     241              : {
     242       183657 :   decl_state_stack.safe_push (state);
     243       183657 : }
     244              : 
     245              : /* Pop the currently used out-decl state from top of stack. */
     246              : 
     247              : struct lto_out_decl_state *
     248       183657 : lto_pop_out_decl_state (void)
     249              : {
     250       183657 :   return decl_state_stack.pop ();
     251              : }
     252              : 
     253              : /* Record STATE after it has been used in serializing the body of
     254              :    FN_DECL.  STATE should no longer be used by the caller.  The ownership
     255              :    of it is taken over from this point.  */
     256              : 
     257              : void
     258       152431 : lto_record_function_out_decl_state (tree fn_decl,
     259              :                                     struct lto_out_decl_state *state)
     260              : {
     261       152431 :   int i;
     262              : 
     263              :   /* Strip all hash tables to save some memory. */
     264       457293 :   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
     265       152431 :     if (state->streams[i].tree_hash_table)
     266              :       {
     267       152431 :         delete state->streams[i].tree_hash_table;
     268       152431 :         state->streams[i].tree_hash_table = NULL;
     269              :       }
     270       152431 :   state->fn_decl = fn_decl;
     271       152431 :   lto_function_decl_states.safe_push (state);
     272       152431 : }
        

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.