LCOV - code coverage report
Current view: top level - gcc - cgraphbuild.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.1 % 216 199
Test Date: 2026-02-28 14:20:25 Functions: 94.7 % 19 18
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Callgraph construction.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              :    Contributed by Jan Hubicka
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "tree.h"
      26              : #include "gimple.h"
      27              : #include "tree-pass.h"
      28              : #include "cgraph.h"
      29              : #include "gimple-iterator.h"
      30              : #include "gimple-fold.h"
      31              : #include "gimple-walk.h"
      32              : #include "ipa-utils.h"
      33              : #include "except.h"
      34              : #include "gimplify.h"
      35              : 
      36              : /* Context of record_reference.  */
      37              : struct record_reference_ctx
      38              : {
      39              :   bool only_vars;
      40              :   struct varpool_node *varpool_node;
      41              : };
      42              : 
      43              : /* Walk tree and record all calls and references to functions/variables.
      44              :    Called via walk_tree: TP is pointer to tree to be examined.
      45              :    When DATA is non-null, record references to callgraph.
      46              :    */
      47              : 
      48              : static tree
      49     14721669 : record_reference (tree *tp, int *walk_subtrees, void *data)
      50              : {
      51     14721701 :   tree t = *tp;
      52     14721701 :   tree decl;
      53     14721701 :   record_reference_ctx *ctx = (record_reference_ctx *)data;
      54              : 
      55     14721701 :   t = canonicalize_constructor_val (t, NULL);
      56     14721701 :   if (!t)
      57           77 :     t = *tp;
      58     14721624 :   else if (t != *tp)
      59      4437248 :     *tp = t;
      60              : 
      61     14721701 :   switch (TREE_CODE (t))
      62              :     {
      63            0 :     case VAR_DECL:
      64            0 :     case FUNCTION_DECL:
      65            0 :       gcc_unreachable ();
      66      4625090 :       break;
      67              : 
      68      4625090 :     case FDESC_EXPR:
      69      4625090 :     case ADDR_EXPR:
      70              :       /* Record dereferences to the functions.  This makes the
      71              :          functions reachable unconditionally.  */
      72      4625090 :       decl = get_base_var (*tp);
      73      4625090 :       if (TREE_CODE (decl) == FUNCTION_DECL)
      74              :         {
      75      1125291 :           cgraph_node *node = cgraph_node::get_create (decl);
      76      1125291 :           if (!ctx->only_vars)
      77      1125291 :             node->mark_address_taken ();
      78      1125291 :           ctx->varpool_node->create_reference (node, IPA_REF_ADDR);
      79              :         }
      80              : 
      81      4625090 :       if (VAR_P (decl))
      82              :         {
      83              :           /* Replace vars with their DECL_VALUE_EXPR if any.
      84              :              This is normally done during gimplification, but
      85              :              static var initializers are never gimplified.  */
      86      2594747 :           if (DECL_HAS_VALUE_EXPR_P (decl))
      87              :             {
      88              :               tree *p;
      89           64 :               for (p = tp; *p != decl; p = &TREE_OPERAND (*p, 0))
      90              :                 ;
      91           32 :               *p = unshare_expr (DECL_VALUE_EXPR (decl));
      92           32 :               return record_reference (tp, walk_subtrees, data);
      93              :             }
      94      2594715 :           varpool_node *vnode = varpool_node::get_create (decl);
      95      2594715 :           ctx->varpool_node->create_reference (vnode, IPA_REF_ADDR);
      96              :         }
      97      4625058 :       *walk_subtrees = 0;
      98      4625058 :       break;
      99              : 
     100     10096611 :     default:
     101              :       /* Save some cycles by not walking types and declaration as we
     102              :          won't find anything useful there anyway.  */
     103     10096611 :       if (IS_TYPE_OR_DECL_P (*tp))
     104              :         {
     105            0 :           *walk_subtrees = 0;
     106            0 :           break;
     107              :         }
     108              :       break;
     109              :     }
     110              : 
     111              :   return NULL_TREE;
     112              : }
     113              : 
     114              : /* Record references to typeinfos in the type list LIST.  */
     115              : 
     116              : static void
     117       193830 : record_type_list (cgraph_node *node, tree list)
     118              : {
     119       217842 :   for (; list; list = TREE_CHAIN (list))
     120              :     {
     121        24012 :       tree type = TREE_VALUE (list);
     122              : 
     123        24012 :       if (TYPE_P (type))
     124        23401 :         type = lookup_type_for_runtime (type);
     125        24012 :       STRIP_NOPS (type);
     126        24012 :       if (TREE_CODE (type) == ADDR_EXPR)
     127              :         {
     128        24012 :           type = TREE_OPERAND (type, 0);
     129        24012 :           if (VAR_P (type))
     130              :             {
     131        24012 :               varpool_node *vnode = varpool_node::get_create (type);
     132        24012 :               node->create_reference (vnode, IPA_REF_ADDR);
     133              :             }
     134              :         }
     135              :     }
     136       193830 : }
     137              : 
     138              : /* Record all references we will introduce by producing EH tables
     139              :    for NODE.  */
     140              : 
     141              : static void
     142     11750537 : record_eh_tables (cgraph_node *node, function *fun)
     143              : {
     144     11750537 :   eh_region i;
     145              : 
     146     11750537 :   if (DECL_FUNCTION_PERSONALITY (node->decl))
     147              :     {
     148      2362626 :       tree per_decl = DECL_FUNCTION_PERSONALITY (node->decl);
     149      2362626 :       cgraph_node *per_node = cgraph_node::get_create (per_decl);
     150              : 
     151      2362626 :       node->create_reference (per_node, IPA_REF_ADDR);
     152      2362626 :       per_node->mark_address_taken ();
     153              :     }
     154              : 
     155     11750537 :   i = fun->eh->region_tree;
     156     11750537 :   if (!i)
     157              :     return;
     158              : 
     159      7814712 :   while (1)
     160              :     {
     161      7814712 :       switch (i->type)
     162              :         {
     163              :         case ERT_CLEANUP:
     164              :         case ERT_MUST_NOT_THROW:
     165              :           break;
     166              : 
     167       178658 :         case ERT_TRY:
     168       178658 :           {
     169       178658 :             eh_catch c;
     170       354934 :             for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
     171       176276 :               record_type_list (node, c->type_list);
     172              :           }
     173              :           break;
     174              : 
     175        17554 :         case ERT_ALLOWED_EXCEPTIONS:
     176        17554 :           record_type_list (node, i->u.allowed.type_list);
     177        17554 :           break;
     178              :         }
     179              :       /* If there are sub-regions, process them.  */
     180      7814712 :       if (i->inner)
     181              :         i = i->inner;
     182              :       /* If there are peers, process them.  */
     183      6058149 :       else if (i->next_peer)
     184              :         i = i->next_peer;
     185              :       /* Otherwise, step back up the tree to the next peer.  */
     186              :       else
     187              :         {
     188      5087518 :           do
     189              :             {
     190      5087518 :               i = i->outer;
     191      5087518 :               if (i == NULL)
     192              :                 return;
     193              :             }
     194      1756563 :           while (i->next_peer == NULL);
     195              :           i = i->next_peer;
     196              :         }
     197              :     }
     198              : }
     199              : 
     200              : /* Computes the frequency of the call statement so that it can be stored in
     201              :    cgraph_edge.  BB is the basic block of the call statement.  */
     202              : int
     203            0 : compute_call_stmt_bb_frequency (tree decl, basic_block bb)
     204              : {
     205            0 :   return bb->count.to_cgraph_frequency
     206            0 :       (ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count);
     207              : }
     208              : 
     209              : /* Mark address taken in STMT.  */
     210              : 
     211              : static bool
     212     32306913 : mark_address (gimple *stmt, tree addr, tree, void *data)
     213              : {
     214     32306913 :   addr = get_base_address (addr);
     215     32306913 :   if (TREE_CODE (addr) == FUNCTION_DECL)
     216              :     {
     217      1082834 :       cgraph_node *node = cgraph_node::get_create (addr);
     218      1082834 :       node->mark_address_taken ();
     219      1082834 :       ((symtab_node *)data)->create_reference (node, IPA_REF_ADDR, stmt);
     220              :     }
     221     31224079 :   else if (addr && VAR_P (addr)
     222     18835788 :            && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
     223              :     {
     224      7905431 :       varpool_node *vnode = varpool_node::get_create (addr);
     225              : 
     226      7905431 :       ((symtab_node *)data)->create_reference (vnode, IPA_REF_ADDR, stmt);
     227              :     }
     228              : 
     229     32306913 :   return false;
     230              : }
     231              : 
     232              : /* Mark load of T.  */
     233              : 
     234              : static bool
     235     61008229 : mark_load (gimple *stmt, tree t, tree, void *data)
     236              : {
     237     61008229 :   t = get_base_address (t);
     238     61008229 :   if (t && TREE_CODE (t) == FUNCTION_DECL)
     239              :     {
     240              :       /* ??? This can happen on platforms with descriptors when these are
     241              :          directly manipulated in the code.  Pretend that it's an address.  */
     242          105 :       cgraph_node *node = cgraph_node::get_create (t);
     243          105 :       node->mark_address_taken ();
     244          105 :       ((symtab_node *)data)->create_reference (node, IPA_REF_ADDR, stmt);
     245          105 :     }
     246     61008124 :   else if (t && VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     247              :     {
     248     11262091 :       varpool_node *vnode = varpool_node::get_create (t);
     249              : 
     250     11262091 :       ((symtab_node *)data)->create_reference (vnode, IPA_REF_LOAD, stmt);
     251              :     }
     252     61008229 :   return false;
     253              : }
     254              : 
     255              : /* Mark store of T.  */
     256              : 
     257              : static bool
     258     61441066 : mark_store (gimple *stmt, tree t, tree, void *data)
     259              : {
     260     61441066 :   t = get_base_address (t);
     261     61441066 :   if (t && VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     262              :     {
     263      5769952 :       varpool_node *vnode = varpool_node::get_create (t);
     264              : 
     265      5769952 :       ((symtab_node *)data)->create_reference (vnode, IPA_REF_STORE, stmt);
     266              :      }
     267     61441066 :   return false;
     268              : }
     269              : 
     270              : /* Record all references from cgraph_node that are taken in statement STMT.  */
     271              : 
     272              : void
     273    304379879 : cgraph_node::record_stmt_references (gimple *stmt)
     274              : {
     275    304379879 :   walk_stmt_load_store_addr_ops (stmt, this, mark_load, mark_store,
     276              :                                  mark_address);
     277    304379879 : }
     278              : 
     279              : /* Create cgraph edges for function calls.
     280              :    Also look for functions and variables having addresses taken.  */
     281              : 
     282              : namespace {
     283              : 
     284              : const pass_data pass_data_build_cgraph_edges =
     285              : {
     286              :   GIMPLE_PASS, /* type */
     287              :   "*build_cgraph_edges", /* name */
     288              :   OPTGROUP_NONE, /* optinfo_flags */
     289              :   TV_NONE, /* tv_id */
     290              :   PROP_cfg, /* properties_required */
     291              :   0, /* properties_provided */
     292              :   0, /* properties_destroyed */
     293              :   0, /* todo_flags_start */
     294              :   0, /* todo_flags_finish */
     295              : };
     296              : 
     297              : class pass_build_cgraph_edges : public gimple_opt_pass
     298              : {
     299              : public:
     300       285722 :   pass_build_cgraph_edges (gcc::context *ctxt)
     301       571444 :     : gimple_opt_pass (pass_data_build_cgraph_edges, ctxt)
     302              :   {}
     303              : 
     304              :   /* opt_pass methods: */
     305              :   unsigned int execute (function *) final override;
     306              : 
     307              : }; // class pass_build_cgraph_edges
     308              : 
     309              : unsigned int
     310      2869200 : pass_build_cgraph_edges::execute (function *fun)
     311              : {
     312      2869200 :   basic_block bb;
     313      2869200 :   cgraph_node *node = cgraph_node::get (current_function_decl);
     314      2869200 :   gimple_stmt_iterator gsi;
     315      2869200 :   tree decl;
     316      2869200 :   unsigned ix;
     317              : 
     318              :   /* Create the callgraph edges and record the nodes referenced by the function.
     319              :      body.  */
     320     19916360 :   FOR_EACH_BB_FN (bb, fun)
     321              :     {
     322     98709737 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     323              :         {
     324     64615417 :           gimple *stmt = gsi_stmt (gsi);
     325     64615417 :           tree decl;
     326              : 
     327     64615417 :           if (is_gimple_debug (stmt))
     328      2326544 :             continue;
     329              : 
     330     62288873 :           if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
     331              :             {
     332     10134597 :               decl = gimple_call_fndecl (call_stmt);
     333     10134597 :               if (decl)
     334      9635695 :                 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count);
     335       498902 :               else if (gimple_call_internal_p (call_stmt))
     336              :                 ;
     337              :               else
     338       162942 :                 node->create_indirect_edge (call_stmt,
     339              :                                             gimple_call_flags (call_stmt),
     340              :                                             bb->count);
     341              :             }
     342     62288873 :           node->record_stmt_references (stmt);
     343     62288873 :           if (gomp_parallel *omp_par_stmt = dyn_cast <gomp_parallel *> (stmt))
     344              :             {
     345            0 :               tree fn = gimple_omp_parallel_child_fn (omp_par_stmt);
     346            0 :               node->create_reference (cgraph_node::get_create (fn),
     347              :                                       IPA_REF_ADDR, stmt);
     348              :             }
     349     62288873 :           if (gimple_code (stmt) == GIMPLE_OMP_TASK)
     350              :             {
     351            0 :               tree fn = gimple_omp_task_child_fn (stmt);
     352            0 :               if (fn)
     353            0 :                 node->create_reference (cgraph_node::get_create (fn),
     354              :                                         IPA_REF_ADDR, stmt);
     355            0 :               fn = gimple_omp_task_copy_fn (stmt);
     356            0 :               if (fn)
     357            0 :                 node->create_reference (cgraph_node::get_create (fn),
     358              :                                         IPA_REF_ADDR, stmt);
     359              :             }
     360              :         }
     361     17047160 :       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     362            0 :         node->record_stmt_references (gsi_stmt (gsi));
     363              :    }
     364              : 
     365              :   /* Look for initializers of constant variables and private statics.  */
     366     20312012 :   FOR_EACH_LOCAL_DECL (fun, ix, decl)
     367     15319686 :     if (VAR_P (decl)
     368     15319686 :         && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
     369       285978 :         && !DECL_HAS_VALUE_EXPR_P (decl)
     370     15561540 :         && TREE_TYPE (decl) != error_mark_node)
     371       241781 :       varpool_node::finalize_decl (decl);
     372      2869200 :   record_eh_tables (node, fun);
     373              : 
     374      2869200 :   return 0;
     375              : }
     376              : 
     377              : } // anon namespace
     378              : 
     379              : gimple_opt_pass *
     380       285722 : make_pass_build_cgraph_edges (gcc::context *ctxt)
     381              : {
     382       285722 :   return new pass_build_cgraph_edges (ctxt);
     383              : }
     384              : 
     385              : /* Record references to functions and other variables present in the
     386              :    initial value of DECL, a variable.
     387              :    When ONLY_VARS is true, we mark needed only variables, not functions.  */
     388              : 
     389              : void
     390      2004301 : record_references_in_initializer (tree decl, bool only_vars)
     391              : {
     392      2004301 :   varpool_node *node = varpool_node::get_create (decl);
     393      2004301 :   hash_set<tree> visited_nodes;
     394      2004301 :   record_reference_ctx ctx = {false, NULL};
     395              : 
     396      2004301 :   ctx.varpool_node = node;
     397      2004301 :   ctx.only_vars = only_vars;
     398      2004301 :   walk_tree (&DECL_INITIAL (decl), record_reference,
     399              :              &ctx, &visited_nodes);
     400      2004301 : }
     401              : 
     402              : /* Rebuild cgraph edges for current function node.  This needs to be run after
     403              :    passes that don't update the cgraph.  */
     404              : 
     405              : unsigned int
     406      8653797 : cgraph_edge::rebuild_edges (void)
     407              : {
     408      8653797 :   basic_block bb;
     409      8653797 :   cgraph_node *node = cgraph_node::get (current_function_decl);
     410      8653797 :   gimple_stmt_iterator gsi;
     411              : 
     412      8653797 :   node->remove_callees ();
     413      8653797 :   node->remove_all_references ();
     414              : 
     415      8653797 :   node->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
     416              : 
     417     58389033 :   FOR_EACH_BB_FN (bb, cfun)
     418              :     {
     419    317439261 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     420              :         {
     421    217968789 :           gimple *stmt = gsi_stmt (gsi);
     422    217968789 :           tree decl;
     423              : 
     424    217968789 :           if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
     425              :             {
     426     28853879 :               decl = gimple_call_fndecl (call_stmt);
     427     28853879 :               if (decl)
     428     26686353 :                 node->create_edge (cgraph_node::get_create (decl), call_stmt,
     429              :                                    bb->count);
     430      2167526 :               else if (gimple_call_internal_p (call_stmt))
     431              :                 ;
     432              :               else
     433       505272 :                 node->create_indirect_edge (call_stmt,
     434              :                                             gimple_call_flags (call_stmt),
     435              :                                             bb->count);
     436              :             }
     437    217968789 :           node->record_stmt_references (stmt);
     438              :         }
     439     62797164 :       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     440     13061928 :         node->record_stmt_references (gsi_stmt (gsi));
     441              :     }
     442      8653797 :   record_eh_tables (node, cfun);
     443      8653797 :   gcc_assert (!node->inlined_to);
     444      8653797 :   return 0;
     445              : }
     446              : 
     447              : /* Rebuild cgraph references for current function node.  This needs to be run
     448              :    after passes that don't update the cgraph.  */
     449              : 
     450              : void
     451       227540 : cgraph_edge::rebuild_references (void)
     452              : {
     453       227540 :   basic_block bb;
     454       227540 :   cgraph_node *node = cgraph_node::get (current_function_decl);
     455       227540 :   gimple_stmt_iterator gsi;
     456       227540 :   ipa_ref *ref = NULL;
     457       227540 :   int i;
     458              : 
     459              :   /* Keep speculative references for further cgraph edge expansion.  */
     460       629568 :   for (i = 0; node->iterate_reference (i, ref);)
     461       174488 :     if (!ref->speculative)
     462       171710 :       ref->remove_reference ();
     463              :     else
     464         2778 :       i++;
     465              : 
     466      2142978 :   FOR_EACH_BB_FN (bb, cfun)
     467              :     {
     468     14574565 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     469     10743689 :         node->record_stmt_references (gsi_stmt (gsi));
     470      2232038 :       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     471       316600 :         node->record_stmt_references (gsi_stmt (gsi));
     472              :     }
     473       227540 :   record_eh_tables (node, cfun);
     474       227540 : }
     475              : 
     476              : namespace {
     477              : 
     478              : const pass_data pass_data_rebuild_cgraph_edges =
     479              : {
     480              :   GIMPLE_PASS, /* type */
     481              :   "*rebuild_cgraph_edges", /* name */
     482              :   OPTGROUP_NONE, /* optinfo_flags */
     483              :   TV_CGRAPH, /* tv_id */
     484              :   PROP_cfg, /* properties_required */
     485              :   0, /* properties_provided */
     486              :   0, /* properties_destroyed */
     487              :   0, /* todo_flags_start */
     488              :   0, /* todo_flags_finish */
     489              : };
     490              : 
     491              : class pass_rebuild_cgraph_edges : public gimple_opt_pass
     492              : {
     493              : public:
     494      1142888 :   pass_rebuild_cgraph_edges (gcc::context *ctxt)
     495      2285776 :     : gimple_opt_pass (pass_data_rebuild_cgraph_edges, ctxt)
     496              :   {}
     497              : 
     498              :   /* opt_pass methods: */
     499       857166 :   opt_pass * clone () final override
     500              :   {
     501       857166 :     return new pass_rebuild_cgraph_edges (m_ctxt);
     502              :   }
     503      8546646 :   unsigned int execute (function *) final override
     504              :   {
     505      8546646 :     return cgraph_edge::rebuild_edges ();
     506              :   }
     507              : 
     508              : }; // class pass_rebuild_cgraph_edges
     509              : 
     510              : } // anon namespace
     511              : 
     512              : gimple_opt_pass *
     513       285722 : make_pass_rebuild_cgraph_edges (gcc::context *ctxt)
     514              : {
     515       285722 :   return new pass_rebuild_cgraph_edges (ctxt);
     516              : }
     517              : 
     518              : 
     519              : namespace {
     520              : 
     521              : const pass_data pass_data_remove_cgraph_callee_edges =
     522              : {
     523              :   GIMPLE_PASS, /* type */
     524              :   "*remove_cgraph_callee_edges", /* name */
     525              :   OPTGROUP_NONE, /* optinfo_flags */
     526              :   TV_NONE, /* tv_id */
     527              :   0, /* properties_required */
     528              :   0, /* properties_provided */
     529              :   0, /* properties_destroyed */
     530              :   0, /* todo_flags_start */
     531              :   0, /* todo_flags_finish */
     532              : };
     533              : 
     534              : class pass_remove_cgraph_callee_edges : public gimple_opt_pass
     535              : {
     536              : public:
     537       857166 :   pass_remove_cgraph_callee_edges (gcc::context *ctxt)
     538      1714332 :     : gimple_opt_pass (pass_data_remove_cgraph_callee_edges, ctxt)
     539              :   {}
     540              : 
     541              :   /* opt_pass methods: */
     542       571444 :   opt_pass * clone () final override {
     543       571444 :     return new pass_remove_cgraph_callee_edges (m_ctxt);
     544              :   }
     545              :   unsigned int execute (function *) final override;
     546              : 
     547              : }; // class pass_remove_cgraph_callee_edges
     548              : 
     549              : unsigned int
     550      3456352 : pass_remove_cgraph_callee_edges::execute (function *)
     551              : {
     552      3456352 :   cgraph_node *node = cgraph_node::get (current_function_decl);
     553      3456352 :   node->remove_callees ();
     554      3456352 :   node->remove_all_references ();
     555      3456352 :   return 0;
     556              : }
     557              : 
     558              : } // anon namespace
     559              : 
     560              : gimple_opt_pass *
     561       285722 : make_pass_remove_cgraph_callee_edges (gcc::context *ctxt)
     562              : {
     563       285722 :   return new pass_remove_cgraph_callee_edges (ctxt);
     564              : }
        

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.