LCOV - code coverage report
Current view: top level - gcc - cgraphclones.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.4 % 569 486
Test Date: 2026-08-22 16:33:35 Functions: 92.0 % 25 23
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Callgraph clones
       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              : /* This module provide facilities for cloning functions.  I.e. creating
      22              :    new functions based on existing functions with simple modifications,
      23              :    such as replacement of parameters.
      24              : 
      25              :    To allow whole program optimization without actual presence of function
      26              :    bodies, an additional infrastructure is provided for so-called virtual
      27              :    clones
      28              : 
      29              :    A virtual clone in the callgraph is a function that has no
      30              :    associated body, just a description of how to create its body based
      31              :    on a different function (which itself may be a virtual clone).
      32              : 
      33              :    The description of function modifications includes adjustments to
      34              :    the function's signature (which allows, for example, removing or
      35              :    adding function arguments), substitutions to perform on the
      36              :    function body, and, for inlined functions, a pointer to the
      37              :    function that it will be inlined into.
      38              : 
      39              :    It is also possible to redirect any edge of the callgraph from a
      40              :    function to its virtual clone.  This implies updating of the call
      41              :    site to adjust for the new function signature.
      42              : 
      43              :    Most of the transformations performed by inter-procedural
      44              :    optimizations can be represented via virtual clones.  For
      45              :    instance, a constant propagation pass can produce a virtual clone
      46              :    of the function which replaces one of its arguments by a
      47              :    constant.  The inliner can represent its decisions by producing a
      48              :    clone of a function whose body will be later integrated into
      49              :    a given function.
      50              : 
      51              :    Using virtual clones, the program can be easily updated
      52              :    during the Execute stage, solving most of pass interactions
      53              :    problems that would otherwise occur during Transform.
      54              : 
      55              :    Virtual clones are later materialized in the LTRANS stage and
      56              :    turned into real functions.  Passes executed after the virtual
      57              :    clone were introduced also perform their Transform stage
      58              :    on new functions, so for a pass there is no significant
      59              :    difference between operating on a real function or a virtual
      60              :    clone introduced before its Execute stage.
      61              : 
      62              :    Optimization passes then work on virtual clones introduced before
      63              :    their Execute stage as if they were real functions.  The
      64              :    only difference is that clones are not visible during the
      65              :    Generate Summary stage.  */
      66              : 
      67              : #include "config.h"
      68              : #include "system.h"
      69              : #include "coretypes.h"
      70              : #include "backend.h"
      71              : #include "target.h"
      72              : #include "rtl.h"
      73              : #include "tree.h"
      74              : #include "gimple.h"
      75              : #include "stringpool.h"
      76              : #include "cgraph.h"
      77              : #include "lto-streamer.h"
      78              : #include "tree-eh.h"
      79              : #include "tree-cfg.h"
      80              : #include "tree-inline.h"
      81              : #include "attribs.h"
      82              : #include "dumpfile.h"
      83              : #include "gimple-pretty-print.h"
      84              : #include "alloc-pool.h"
      85              : #include "symbol-summary.h"
      86              : #include "tree-vrp.h"
      87              : #include "sreal.h"
      88              : #include "ipa-cp.h"
      89              : #include "ipa-prop.h"
      90              : #include "ipa-fnsummary.h"
      91              : #include "symtab-thunks.h"
      92              : #include "symtab-clones.h"
      93              : 
      94              : /* Create clone of edge in the node N represented by CALL_EXPR
      95              :    the callgraph.  */
      96              : 
      97              : cgraph_edge *
      98      7934265 : cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid,
      99              :                     profile_count num, profile_count den,
     100              :                     bool update_original)
     101              : {
     102      7934265 :   cgraph_edge *new_edge;
     103      7934265 :   profile_count::adjust_for_ipa_scaling (&num, &den);
     104      7934265 :   profile_count prof_count = count.apply_scale (num, den);
     105              : 
     106      7934265 :   if (indirect_unknown_callee)
     107              :     {
     108       179415 :       tree decl;
     109              : 
     110       178765 :       if (call_stmt && (decl = gimple_call_fndecl (call_stmt))
     111              :           /* When the call is speculative, we need to resolve it
     112              :              via cgraph_resolve_speculation and not here.  */
     113       188069 :           && !speculative)
     114              :         {
     115         8654 :           cgraph_node *callee = cgraph_node::get (decl);
     116         8654 :           gcc_checking_assert (callee);
     117         8654 :           new_edge = n->create_edge (callee, call_stmt, prof_count, true);
     118              :         }
     119              :       else
     120              :         {
     121       341522 :           new_edge = n->create_indirect_edge (call_stmt,
     122       170761 :                                               indirect_info->ecf_flags,
     123              :                                               prof_count, true);
     124              : 
     125       170761 :           if (indirect_info->kind == CIIK_POLYMORPHIC)
     126       108376 :             new_edge->indirect_info
     127       108376 :               = (new (ggc_alloc<cgraph_polymorphic_indirect_info> ())
     128              :                  cgraph_polymorphic_indirect_info (
     129       108376 :                      *(const cgraph_polymorphic_indirect_info *) indirect_info));
     130        62385 :           else if (indirect_info->kind == CIIK_SIMPLE)
     131        62271 :             new_edge->indirect_info
     132        62271 :               = (new (ggc_alloc<cgraph_simple_indirect_info> ())
     133              :                  cgraph_simple_indirect_info (
     134        62271 :                      *(const cgraph_simple_indirect_info *) indirect_info));
     135              :           else
     136          114 :             new_edge->indirect_info
     137          114 :               = (new (ggc_alloc<cgraph_indirect_call_info> ())
     138              :                  cgraph_indirect_call_info(
     139          114 :                      *(const cgraph_indirect_call_info *) indirect_info));
     140              :         }
     141              :     }
     142              :   else
     143              :     {
     144      7754850 :       new_edge = n->create_edge (callee, call_stmt, prof_count, true);
     145      7754850 :       if (indirect_info)
     146              :         {
     147            0 :           new_edge->indirect_info
     148            0 :             = ggc_cleared_alloc<cgraph_indirect_call_info> ();
     149            0 :           *new_edge->indirect_info = *indirect_info;
     150              :         }
     151              :     }
     152              : 
     153      7934265 :   new_edge->inline_failed = inline_failed;
     154      7934265 :   new_edge->indirect_inlining_edge = indirect_inlining_edge;
     155      7934265 :   if (!call_stmt)
     156       236886 :     new_edge->lto_stmt_uid = stmt_uid;
     157      7934265 :   new_edge->speculative_id = speculative_id;
     158              :   /* Clone flags that depend on call_stmt availability manually.  */
     159      7934265 :   new_edge->can_throw_external = can_throw_external;
     160      7934265 :   new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
     161      7934265 :   new_edge->speculative = speculative;
     162      7934265 :   new_edge->callback = callback;
     163      7934265 :   new_edge->has_callback = has_callback;
     164      7934265 :   new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
     165              : 
     166              :   /* Update IPA profile.  Local profiles need no updating in original.  */
     167      7934265 :   if (update_original)
     168      7203898 :     count = count.combine_with_ipa_count_within (count.ipa ()
     169      7203898 :                                                  - new_edge->count.ipa (),
     170      7203898 :                                                  caller->count);
     171      7934265 :   symtab->call_edge_duplication_hooks (this, new_edge);
     172      7934265 :   return new_edge;
     173              : }
     174              : 
     175              : /* Set flags of NEW_NODE and its decl.  NEW_NODE is a newly created private
     176              :    clone or its thunk.  */
     177              : 
     178              : void
     179       146416 : set_new_clone_decl_and_node_flags (cgraph_node *new_node)
     180              : {
     181       146416 :   DECL_EXTERNAL (new_node->decl) = 0;
     182       146416 :   TREE_PUBLIC (new_node->decl) = 0;
     183       146416 :   DECL_COMDAT (new_node->decl) = 0;
     184       146416 :   DECL_WEAK (new_node->decl) = 0;
     185       146416 :   DECL_VIRTUAL_P (new_node->decl) = 0;
     186       146416 :   DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0;
     187       146416 :   DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
     188       146416 :   DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0);
     189       146416 :   DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0);
     190       146416 :   DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
     191              : 
     192       146416 :   new_node->externally_visible = 0;
     193              :   /* Clones of callbacks might have their address taken, and thus cannot be
     194              :      local.  */
     195       146416 :   new_node->local = !new_node->address_taken;
     196       146416 :   new_node->lowered = true;
     197       146416 :   new_node->semantic_interposition = 0;
     198       146416 : }
     199              : 
     200              : /* Duplicate thunk THUNK if necessary but make it to refer to NODE.
     201              :    ARGS_TO_SKIP, if non-NULL, determines which parameters should be omitted.
     202              :    Function can return NODE if no thunk is necessary, which can happen when
     203              :    thunk is this_adjusting but we are removing this parameter.  */
     204              : 
     205              : static cgraph_node *
     206           30 : duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
     207              : {
     208           30 :   cgraph_node *new_thunk, *thunk_of;
     209           30 :   thunk_of = thunk->callees->callee->ultimate_alias_target ();
     210              : 
     211           30 :   if (thunk_of->thunk)
     212            0 :     node = duplicate_thunk_for_node (thunk_of, node);
     213              : 
     214           30 :   if (!DECL_ARGUMENTS (thunk->decl))
     215            0 :     thunk->get_untransformed_body ();
     216              : 
     217           30 :   thunk_info *i = thunk_info::get (thunk);
     218           30 :   cgraph_edge *cs;
     219           30 :   for (cs = node->callers; cs; cs = cs->next_caller)
     220           12 :     if (cs->caller->thunk)
     221              :       {
     222           12 :         thunk_info *i2 = thunk_info::get (cs->caller);
     223           12 :         if (*i2 == *i)
     224              :           return cs->caller;
     225              :       }
     226              : 
     227           18 :   tree new_decl;
     228           18 :   clone_info *info = clone_info::get (node);
     229           18 :   if (info && info->param_adjustments)
     230              :     {
     231              :       /* We do not need to duplicate this_adjusting thunks if we have removed
     232              :          this.  */
     233           15 :       if (i->this_adjusting
     234           15 :           && !info->param_adjustments->first_param_intact_p ())
     235            0 :         return node;
     236              : 
     237           15 :       new_decl = copy_node (thunk->decl);
     238           15 :       ipa_param_body_adjustments body_adj (info->param_adjustments,
     239           15 :                                            new_decl);
     240           15 :       body_adj.modify_formal_parameters ();
     241           15 :     }
     242              :   else
     243              :     {
     244            3 :       new_decl = copy_node (thunk->decl);
     245            3 :       for (tree *arg = &DECL_ARGUMENTS (new_decl);
     246            9 :            *arg; arg = &DECL_CHAIN (*arg))
     247              :         {
     248            6 :           tree next = DECL_CHAIN (*arg);
     249            6 :           *arg = copy_node (*arg);
     250            6 :           DECL_CONTEXT (*arg) = new_decl;
     251            6 :           DECL_CHAIN (*arg) = next;
     252              :         }
     253              :     }
     254              : 
     255           18 :   gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl));
     256           18 :   gcc_checking_assert (!DECL_INITIAL (new_decl));
     257           18 :   gcc_checking_assert (!DECL_RESULT (new_decl));
     258           18 :   gcc_checking_assert (!DECL_RTL_SET_P (new_decl));
     259              : 
     260           18 :   DECL_NAME (new_decl) = clone_function_name_numbered (thunk->decl,
     261              :                                                        "artificial_thunk");
     262           18 :   SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
     263              : 
     264              :   /* We need to force DECL_IGNORED_P because the new thunk is created after
     265              :      early debug was run.  */
     266           18 :   DECL_IGNORED_P (new_decl) = 1;
     267              : 
     268           18 :   new_thunk = cgraph_node::create (new_decl);
     269           18 :   set_new_clone_decl_and_node_flags (new_thunk);
     270           18 :   new_thunk->definition = true;
     271           18 :   new_thunk->can_change_signature = node->can_change_signature;
     272           18 :   new_thunk->thunk = thunk->thunk;
     273           18 :   new_thunk->unique_name = in_lto_p;
     274           18 :   new_thunk->former_clone_of = thunk->decl;
     275           18 :   if (info && info->param_adjustments)
     276           15 :     clone_info::get_create (new_thunk)->param_adjustments
     277           15 :            = info->param_adjustments;
     278           18 :   new_thunk->unit_id = thunk->unit_id;
     279           18 :   new_thunk->merged_comdat = thunk->merged_comdat;
     280           18 :   new_thunk->merged_extern_inline = thunk->merged_extern_inline;
     281              : 
     282           18 :   cgraph_edge *e = new_thunk->create_edge (node, NULL, new_thunk->count);
     283           18 :   symtab->call_edge_duplication_hooks (thunk->callees, e);
     284           18 :   symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
     285           18 :   return new_thunk;
     286              : }
     287              : 
     288              : /* If E does not lead to a thunk, simply redirect it to N.  Otherwise create
     289              :    one or more equivalent thunks for N and redirect E to the first in the
     290              :    chain.  Note that it is then necessary to call
     291              :    n->expand_all_artificial_thunks once all callers are redirected.  */
     292              : 
     293              : void
     294       434735 : cgraph_edge::redirect_callee_duplicating_thunks (cgraph_node *n)
     295              : {
     296       434735 :   cgraph_node *orig_to = callee->ultimate_alias_target ();
     297       434735 :   if (orig_to->thunk)
     298           30 :     n = duplicate_thunk_for_node (orig_to, n);
     299              : 
     300       434735 :   redirect_callee (n);
     301       434735 : }
     302              : 
     303              : /* Call expand_thunk on all callers that are thunks and if analyze those nodes
     304              :    that were expanded.  */
     305              : 
     306              : void
     307      3364622 : cgraph_node::expand_all_artificial_thunks ()
     308              : {
     309      3364622 :   cgraph_edge *e;
     310      3799691 :   for (e = callers; e;)
     311       435069 :     if (e->caller->thunk)
     312              :       {
     313           18 :         cgraph_node *thunk = e->caller;
     314              : 
     315           18 :         e = e->next_caller;
     316           18 :         if (expand_thunk (thunk, false, false))
     317              :           {
     318            0 :             thunk->thunk = false;
     319            0 :             thunk->analyze ();
     320            0 :             ipa_analyze_node (thunk);
     321            0 :             inline_analyze_function (thunk);
     322              :           }
     323           18 :         thunk->expand_all_artificial_thunks ();
     324              :       }
     325              :     else
     326       435051 :       e = e->next_caller;
     327      3364622 : }
     328              : 
     329              : /* Dump information about creation of a call graph node clone to the dump file
     330              :    created by the -fdump-ipa-clones option.  ORIGINAL is the function being
     331              :    cloned, CLONE is the new clone.  SUFFIX is a string that helps identify the
     332              :    reason for cloning, often it is the suffix used by a particular IPA pass to
     333              :    create unique function names.  SUFFIX can be NULL and in that case the
     334              :    dumping will not take place, which must be the case only for helper clones
     335              :    which will never be emitted to the output.  */
     336              : 
     337              : void
     338      4942512 : dump_callgraph_transformation (const cgraph_node *original,
     339              :                                const cgraph_node *clone,
     340              :                                const char *suffix)
     341              : {
     342      4942512 :   if (suffix && symtab->ipa_clones_dump_file)
     343              :     {
     344           52 :       fprintf (symtab->ipa_clones_dump_file,
     345              :                "Callgraph clone;%s;%d;%s;%d;%d;%s;%d;%s;%d;%d;%s\n",
     346              :                original->asm_name (), original->get_uid (),
     347           26 :                DECL_SOURCE_FILE (original->decl),
     348           26 :                DECL_SOURCE_LINE (original->decl),
     349           26 :                DECL_SOURCE_COLUMN (original->decl), clone->asm_name (),
     350           26 :                clone->get_uid (), DECL_SOURCE_FILE (clone->decl),
     351           26 :                DECL_SOURCE_LINE (clone->decl), DECL_SOURCE_COLUMN (clone->decl),
     352              :                suffix);
     353              : 
     354           26 :       symtab->cloned_nodes.add (original);
     355           26 :       symtab->cloned_nodes.add (clone);
     356              :     }
     357      4942512 : }
     358              : 
     359              : /* Turn profile of N to local profile.   */
     360              : 
     361              : static void
     362            0 : localize_profile (cgraph_node *n)
     363              : {
     364            0 :   n->count = n->count.guessed_local ();
     365            0 :   for (cgraph_edge *e = n->callees; e; e=e->next_callee)
     366              :     {
     367            0 :       e->count = e->count.guessed_local ();
     368            0 :       if (!e->inline_failed)
     369            0 :         localize_profile (e->callee);
     370              :     }
     371            0 :   for (cgraph_edge *e = n->indirect_calls; e; e=e->next_callee)
     372            0 :     e->count = e->count.guessed_local ();
     373            0 : }
     374              : 
     375              : /* Create node representing clone of N executed COUNT times.  Decrease
     376              :    the execution counts from original node too.
     377              :    The new clone will have decl set to DECL that may or may not be the same
     378              :    as decl of N.
     379              : 
     380              :    When UPDATE_ORIGINAL is true, the counts are subtracted from the original
     381              :    function's profile to reflect the fact that part of execution is handled
     382              :    by node.
     383              :    When CALL_DUPLICATION_HOOK is true, the ipa passes are acknowledged about
     384              :    the new clone. Otherwise the caller is responsible for doing so later.
     385              : 
     386              :    If the new node is being inlined into another one, NEW_INLINED_TO should be
     387              :    the outline function the new one is (even indirectly) inlined to.  All hooks
     388              :    will see this in node's inlined_to, when invoked.  Should be NULL if the
     389              :    node is not inlined.
     390              : 
     391              :    SUFFIX is string that is appended to the original name, it should only be
     392              :    NULL if NEW_INLINED_TO is not NULL or if the clone being created is
     393              :    temporary and a record about it should not be added into the ipa-clones dump
     394              :    file.
     395              : 
     396              :    If PARAM_ADJUSTMENTS is non-NULL, the parameter manipulation information
     397              :    will be overwritten by the new structure.  Otherwise the new node will
     398              :    share parameter manipulation information with the original node.  */
     399              : 
     400              : cgraph_node *
     401      3364456 : cgraph_node::create_clone (tree new_decl, profile_count prof_count,
     402              :                            bool update_original,
     403              :                            vec<cgraph_edge *> redirect_callers,
     404              :                            bool call_duplication_hook,
     405              :                            cgraph_node *new_inlined_to,
     406              :                            ipa_param_adjustments *param_adjustments,
     407              :                            const char *suffix)
     408              : {
     409      3364456 :   cgraph_node *new_node = symtab->create_empty ();
     410      3364456 :   cgraph_edge *e;
     411      3364456 :   unsigned i;
     412      3364456 :   profile_count old_count = count;
     413      3364456 :   bool nonzero = count.ipa ().nonzero_p ();
     414              : 
     415      3364456 :   if (new_inlined_to)
     416      3193196 :     dump_callgraph_transformation (this, new_inlined_to, "inlining to");
     417              : 
     418              :   /* When inlining we scale precisely to prof_count, when cloning we can
     419              :      preserve local profile.  */
     420      3193196 :   if (!new_inlined_to)
     421       171260 :     prof_count = count.combine_with_ipa_count (prof_count);
     422      3364456 :   new_node->count = prof_count;
     423      3364456 :   new_node->has_omp_variant_constructs = this->has_omp_variant_constructs;
     424              : 
     425              :   /* Update IPA profile.  Local profiles need no updating in original.  */
     426      3364456 :   if (update_original)
     427              :     {
     428      3171520 :       if (inlined_to)
     429       504368 :         count = count.combine_with_ipa_count_within (count.ipa ()
     430      1008736 :                                                      - prof_count.ipa (),
     431              :                                                      inlined_to->count);
     432              :       else
     433      2667152 :         count = count.combine_with_ipa_count (count.ipa () - prof_count.ipa ());
     434              :     }
     435      3364456 :   new_node->decl = new_decl;
     436      3364456 :   new_node->order = order;
     437      3364456 :   new_node->register_symbol ();
     438      3364456 :   new_node->lto_file_data = lto_file_data;
     439      3364456 :   new_node->analyzed = analyzed;
     440      3364456 :   new_node->definition = definition;
     441      3364456 :   new_node->versionable = versionable;
     442      3364456 :   new_node->can_change_signature = can_change_signature;
     443      3364456 :   new_node->redefined_extern_inline = redefined_extern_inline;
     444      3364456 :   new_node->semantic_interposition = semantic_interposition;
     445      3364456 :   new_node->tm_may_enter_irr = tm_may_enter_irr;
     446      3364456 :   new_node->externally_visible = false;
     447      3364456 :   new_node->no_reorder = no_reorder;
     448      3364456 :   new_node->local = true;
     449      3364456 :   new_node->inlined_to = new_inlined_to;
     450      3364456 :   new_node->rtl = rtl;
     451      3364456 :   new_node->frequency = frequency;
     452      3364456 :   new_node->tp_first_run = tp_first_run;
     453      3364456 :   new_node->tm_clone = tm_clone;
     454      3364456 :   new_node->icf_merged = icf_merged;
     455      3364456 :   new_node->thunk = thunk;
     456      3364456 :   new_node->unit_id = unit_id;
     457      3364456 :   new_node->merged_comdat = merged_comdat;
     458      3364456 :   new_node->merged_extern_inline = merged_extern_inline;
     459      3364456 :   new_node->must_remain_in_tu_body = must_remain_in_tu_body;
     460      3364456 :   clone_info *info = clone_info::get (this);
     461              : 
     462      3364456 :   if (param_adjustments)
     463       140376 :     clone_info::get_create (new_node)->param_adjustments = param_adjustments;
     464      3224080 :   else if (info && info->param_adjustments)
     465       345697 :     clone_info::get_create (new_node)->param_adjustments
     466       345697 :          = info->param_adjustments;
     467      3364456 :   new_node->split_part = split_part;
     468              : 
     469      3799036 :   FOR_EACH_VEC_ELT (redirect_callers, i, e)
     470              :     {
     471              :       /* Redirect calls to the old version node to point to its new
     472              :          version.  The only exception is when the edge was proved to
     473              :          be unreachable during the cloning procedure.  */
     474       434580 :       if (!e->callee
     475       434580 :           || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
     476              :                                                   BUILT_IN_UNREACHABLE_TRAP))
     477       434580 :         e->redirect_callee_duplicating_thunks (new_node);
     478              :     }
     479      3364456 :   new_node->expand_all_artificial_thunks ();
     480              : 
     481      6753498 :   for (e = callees;e; e=e->next_callee)
     482      3389042 :     e->clone (new_node, e->call_stmt, e->lto_stmt_uid, new_node->count, old_count,
     483              :               update_original);
     484              : 
     485      3444704 :   for (e = indirect_calls; e; e = e->next_callee)
     486        80248 :     e->clone (new_node, e->call_stmt, e->lto_stmt_uid,
     487              :               new_node->count, old_count, update_original);
     488      3364456 :   new_node->clone_references (this);
     489              : 
     490      3364456 :   new_node->next_sibling_clone = clones;
     491      3364456 :   if (clones)
     492      1662863 :     clones->prev_sibling_clone = new_node;
     493      3364456 :   clones = new_node;
     494      3364456 :   new_node->clone_of = this;
     495              : 
     496      3364456 :   if (call_duplication_hook)
     497      3194829 :     symtab->call_cgraph_duplication_hooks (this, new_node);
     498              :   /* With partial train run we do not want to assume that original's
     499              :      count is zero whenever we redurect all executed edges to clone.
     500              :      Simply drop profile to local one in this case.  */
     501      3364456 :   if (update_original
     502      3171520 :       && opt_for_fn (decl, flag_profile_partial_training)
     503            0 :       && nonzero
     504            0 :       && count.ipa_p ()
     505      3364456 :       && !count.ipa ().nonzero_p ()
     506      3364456 :       && !inlined_to)
     507            0 :     localize_profile (this);
     508              : 
     509      3364456 :   if (!new_inlined_to)
     510       171260 :     dump_callgraph_transformation (this, new_node, suffix);
     511              : 
     512      3364456 :   return new_node;
     513              : }
     514              : 
     515              : static GTY(()) hash_map<const char *, unsigned> *clone_fn_ids;
     516              : 
     517              : /* Return a new assembler name for a clone of decl named NAME.  Apart
     518              :    from the string SUFFIX, the new name will end with a unique (for
     519              :    each NAME) unspecified number.  If clone numbering is not needed
     520              :    then the two argument clone_function_name should be used instead.
     521              :    Should not be called directly except for by
     522              :    lto-partition.cc:privatize_symbol_name_1.  */
     523              : 
     524              : tree
     525       112826 : clone_function_name_numbered (const char *name, const char *suffix)
     526              : {
     527              :   /* Initialize the function->counter mapping the first time it's
     528              :      needed.  */
     529       112826 :   if (!clone_fn_ids)
     530        21157 :     clone_fn_ids = hash_map<const char *, unsigned int>::create_ggc (64);
     531       338478 :   unsigned int &suffix_counter = clone_fn_ids->get_or_insert (
     532       112826 :                                    IDENTIFIER_POINTER (get_identifier (name)));
     533       112826 :   return clone_function_name (name, suffix, suffix_counter++);
     534              : }
     535              : 
     536              : /* Return a new assembler name for a clone of DECL.  Apart from string
     537              :    SUFFIX, the new name will end with a unique (for each DECL
     538              :    assembler name) unspecified number.  If clone numbering is not
     539              :    needed then the two argument clone_function_name should be used
     540              :    instead.  */
     541              : 
     542              : tree
     543       112826 : clone_function_name_numbered (tree decl, const char *suffix)
     544              : {
     545       112826 :   tree name = DECL_ASSEMBLER_NAME (decl);
     546       112826 :   return clone_function_name_numbered (IDENTIFIER_POINTER (name),
     547       112826 :                                        suffix);
     548              : }
     549              : 
     550              : /* Return a new assembler name for a clone of decl named NAME.  Apart
     551              :    from the string SUFFIX, the new name will end with the specified
     552              :    NUMBER.  If clone numbering is not needed then the two argument
     553              :    clone_function_name should be used instead.  */
     554              : 
     555              : tree
     556       259553 : clone_function_name (const char *name, const char *suffix,
     557              :                      unsigned long number)
     558              : {
     559       259553 :   size_t len = strlen (name);
     560       259553 :   char *tmp_name, *prefix;
     561              : 
     562       259553 :   prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
     563       259553 :   memcpy (prefix, name, len);
     564       259553 :   strcpy (prefix + len + 1, suffix);
     565       259553 :   prefix[len] = symbol_table::symbol_suffix_separator ();
     566       259553 :   ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, number);
     567       259553 :   return get_identifier (tmp_name);
     568              : }
     569              : 
     570              : /* Return a new assembler name for a clone of DECL.  Apart from the
     571              :    string SUFFIX, the new name will end with the specified NUMBER.  If
     572              :    clone numbering is not needed then the two argument
     573              :    clone_function_name should be used instead.  */
     574              : 
     575              : tree
     576       146398 : clone_function_name (tree decl, const char *suffix,
     577              :                      unsigned long number)
     578              : {
     579       292796 :   return clone_function_name (
     580       146398 :            IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), suffix, number);
     581              : }
     582              : 
     583              : /* Return a new assembler name ending with the string SUFFIX for a
     584              :    clone of DECL.  */
     585              : 
     586              : tree
     587        67004 : clone_function_name (tree decl, const char *suffix)
     588              : {
     589        67004 :   tree identifier = DECL_ASSEMBLER_NAME (decl);
     590              :   /* For consistency this needs to behave the same way as
     591              :      ASM_FORMAT_PRIVATE_NAME does, but without the final number
     592              :      suffix.  */
     593        67004 :   return clone_identifier (identifier, suffix);
     594              : }
     595              : 
     596              : /*  Return true if symbol is valid in assembler name.  */
     597              : 
     598              : static bool
     599         9810 : is_valid_asm_symbol (char c)
     600              : {
     601         9810 :   if ('a' <= c && c <= 'z')
     602              :     return true;
     603         1849 :   if ('A' <= c && c <= 'Z')
     604              :     return true;
     605         1849 :   if ('0' <= c && c <= '9')
     606              :     return true;
     607          812 :   if (c == '_')
     608          705 :     return true;
     609              :   return false;
     610              : }
     611              : 
     612              : /* Return a new clone of ID ending with the string SUFFIX.
     613              :    If FILTER_SUFFIX is true, any illegal asm characters in the SUFFIX are
     614              :    replaced with _.  */
     615              : 
     616              : tree
     617        68443 : clone_identifier (tree id, const char *suffix, bool filter_suffix)
     618              : {
     619        68443 :   char *separator = XALLOCAVEC (char, 2);
     620        68443 :   separator[0] = symbol_table::symbol_suffix_separator ();
     621        68443 :   separator[1] = 0;
     622              : #if defined (NO_DOT_IN_LABEL) && defined (NO_DOLLAR_IN_LABEL)
     623              :   const char *prefix = "__";
     624              : #else
     625        68443 :   const char *prefix = "";
     626              : #endif
     627        68443 :   if (!suffix)
     628          161 :     suffix = "";
     629              : 
     630        68443 :   if (!filter_suffix)
     631              :     {
     632        67322 :       char *result = ACONCAT (
     633              :         (prefix, IDENTIFIER_POINTER (id), separator, suffix, (char *) 0));
     634        67322 :       return get_identifier (result);
     635              :     }
     636              :   else
     637              :     {
     638              :       /* Replace any illegal chars with _.  */
     639         1121 :       int suffix_len = strlen (suffix);
     640         1121 :       char *converted_suffix = XALLOCAVEC (char, suffix_len + 1);
     641        10931 :       for (int i = 0; i < suffix_len; i++)
     642         9810 :         if (!is_valid_asm_symbol (suffix[i]))
     643          107 :           converted_suffix[i] = '_';
     644              :         else
     645         9703 :           converted_suffix[i] = suffix[i];
     646         1121 :       converted_suffix[suffix_len] = '\0';
     647              : 
     648         1121 :       char *result = ACONCAT ((prefix, IDENTIFIER_POINTER (id), separator,
     649              :                                converted_suffix, (char *) 0));
     650         1121 :       return get_identifier (result);
     651              :     }
     652              : }
     653              : 
     654              : /* Create callgraph node clone with new declaration.  The actual body will be
     655              :    copied later at compilation stage.  The name of the new clone will be
     656              :    constructed from the name of the original node, SUFFIX and NUM_SUFFIX.
     657              : 
     658              :    TODO: after merging in ipa-sra use function call notes instead of args_to_skip
     659              :    bitmap interface.
     660              :    */
     661              : cgraph_node *
     662       146398 : cgraph_node::create_virtual_clone (const vec<cgraph_edge *> &redirect_callers,
     663              :                                    vec<ipa_replace_map *, va_gc> *tree_map,
     664              :                                    ipa_param_adjustments *param_adjustments,
     665              :                                    const char * suffix, unsigned num_suffix)
     666              : {
     667       146398 :   tree old_decl = decl;
     668       146398 :   cgraph_node *new_node = NULL;
     669       146398 :   tree new_decl;
     670       146398 :   size_t len, i;
     671       146398 :   ipa_replace_map *map;
     672       146398 :   char *name;
     673              : 
     674       146398 :   gcc_checking_assert (versionable);
     675              :   /* TODO: It would be nice if we could recognize that param_adjustments do not
     676              :      actually perform any changes, but at the moment let's require it simply
     677              :      does not exist.  */
     678       146398 :   gcc_assert (can_change_signature || !param_adjustments);
     679              : 
     680              :   /* Make a new FUNCTION_DECL tree node */
     681       144983 :   if (!param_adjustments)
     682         6022 :     new_decl = copy_node (old_decl);
     683              :   else
     684       140376 :     new_decl = param_adjustments->adjust_decl (old_decl);
     685              : 
     686              :   /* These pointers represent function body and will be populated only when clone
     687              :      is materialized.  */
     688       146398 :   gcc_assert (new_decl != old_decl);
     689       146398 :   DECL_STRUCT_FUNCTION (new_decl) = NULL;
     690       146398 :   DECL_ARGUMENTS (new_decl) = NULL;
     691       146398 :   DECL_INITIAL (new_decl) = NULL;
     692       146398 :   DECL_RESULT (new_decl) = NULL;
     693              :   /* We cannot do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
     694              :      sometimes storing only clone decl instead of original.  */
     695              : 
     696              :   /* Generate a new name for the new version. */
     697       146398 :   len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
     698       146398 :   name = XALLOCAVEC (char, len + strlen (suffix) + 2);
     699       146398 :   memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
     700       146398 :   strcpy (name + len + 1, suffix);
     701       146398 :   name[len] = '.';
     702       146398 :   DECL_NAME (new_decl) = get_identifier (name);
     703       146398 :   SET_DECL_ASSEMBLER_NAME (new_decl,
     704              :                            clone_function_name (old_decl, suffix, num_suffix));
     705       146398 :   SET_DECL_RTL (new_decl, NULL);
     706              : 
     707       146398 :   new_node = create_clone (new_decl, count, false,
     708              :                            redirect_callers, false, NULL, param_adjustments,
     709              :                            suffix);
     710              : 
     711              :   /* Update the properties.
     712              :      Make clone visible only within this translation unit.  Make sure
     713              :      that is not weak also.
     714              :      ??? We cannot use COMDAT linkage because there is no
     715              :      ABI support for this.  */
     716       146398 :   set_new_clone_decl_and_node_flags (new_node);
     717       146398 :   new_node->ipcp_clone = ipcp_clone;
     718       146398 :   if (tree_map)
     719        14157 :     clone_info::get_create (new_node)->tree_map = tree_map;
     720       146398 :   if (!implicit_section)
     721       146386 :     new_node->set_section (*this);
     722              : 
     723              :   /* Clones of global symbols or symbols with unique names are unique.  */
     724       146398 :   if ((TREE_PUBLIC (old_decl)
     725       111340 :        && !DECL_EXTERNAL (old_decl)
     726        96077 :        && !DECL_WEAK (old_decl)
     727         1916 :        && !DECL_COMDAT (old_decl))
     728       255822 :       || in_lto_p)
     729         7142 :     new_node->unique_name = true;
     730       170894 :   FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
     731              :     {
     732        24496 :       tree repl = map->new_tree;
     733        24496 :       if (map->force_load_ref)
     734              :         {
     735          389 :           gcc_assert (TREE_CODE (repl) == ADDR_EXPR);
     736          389 :           repl = get_base_address (TREE_OPERAND (repl, 0));
     737              :         }
     738        24496 :       new_node->maybe_create_reference (repl, NULL);
     739              :     }
     740              : 
     741       146398 :   if (ipa_transforms_to_apply.exists ())
     742       127291 :     new_node->ipa_transforms_to_apply
     743       127291 :       = ipa_transforms_to_apply.copy ();
     744              : 
     745       146398 :   symtab->call_cgraph_duplication_hooks (this, new_node);
     746              : 
     747       146398 :   return new_node;
     748              : }
     749              : 
     750              : /* callgraph node being removed from symbol table; see if its entry can be
     751              :    replaced by other inline clone.
     752              :    INFO is clone info to attach to the new root.  */
     753              : cgraph_node *
     754    106741875 : cgraph_node::find_replacement (clone_info *info)
     755              : {
     756    106741875 :   cgraph_node *next_inline_clone, *replacement;
     757              : 
     758    106741875 :   for (next_inline_clone = clones;
     759              :        next_inline_clone
     760    106741875 :        && next_inline_clone->decl != decl;
     761            0 :        next_inline_clone = next_inline_clone->next_sibling_clone)
     762              :     ;
     763              : 
     764              :   /* If there is inline clone of the node being removed, we need
     765              :      to put it into the position of removed node and reorganize all
     766              :      other clones to be based on it.  */
     767    106741875 :   if (next_inline_clone)
     768              :     {
     769       433025 :       cgraph_node *n;
     770       433025 :       cgraph_node *new_clones;
     771              : 
     772       433025 :       replacement = next_inline_clone;
     773              : 
     774              :       /* Unlink inline clone from the list of clones of removed node.  */
     775       433025 :       if (next_inline_clone->next_sibling_clone)
     776       264854 :         next_inline_clone->next_sibling_clone->prev_sibling_clone
     777       264854 :           = next_inline_clone->prev_sibling_clone;
     778       433025 :       if (next_inline_clone->prev_sibling_clone)
     779              :         {
     780            0 :           gcc_assert (clones != next_inline_clone);
     781            0 :           next_inline_clone->prev_sibling_clone->next_sibling_clone
     782            0 :             = next_inline_clone->next_sibling_clone;
     783              :         }
     784              :       else
     785              :         {
     786       433025 :           gcc_assert (clones == next_inline_clone);
     787       433025 :           clones = next_inline_clone->next_sibling_clone;
     788              :         }
     789              : 
     790       433025 :       new_clones = clones;
     791       433025 :       clones = NULL;
     792              : 
     793              :       /* Copy clone info.  */
     794       433025 :       if (info)
     795        68928 :         *clone_info::get_create (next_inline_clone) = *info;
     796              : 
     797              :       /* Now place it into clone tree at same level at NODE.  */
     798       433025 :       next_inline_clone->clone_of = clone_of;
     799       433025 :       next_inline_clone->prev_sibling_clone = NULL;
     800       433025 :       next_inline_clone->next_sibling_clone = NULL;
     801       433025 :       if (clone_of)
     802              :         {
     803         3165 :           if (clone_of->clones)
     804         3165 :             clone_of->clones->prev_sibling_clone = next_inline_clone;
     805         3165 :           next_inline_clone->next_sibling_clone = clone_of->clones;
     806         3165 :           clone_of->clones = next_inline_clone;
     807              :         }
     808              : 
     809              :       /* Merge the clone list.  */
     810       433025 :       if (new_clones)
     811              :         {
     812       264854 :           if (!next_inline_clone->clones)
     813       261530 :             next_inline_clone->clones = new_clones;
     814              :           else
     815              :             {
     816              :               n = next_inline_clone->clones;
     817        10744 :               while (n->next_sibling_clone)
     818              :                 n = n->next_sibling_clone;
     819         3324 :               n->next_sibling_clone = new_clones;
     820         3324 :               new_clones->prev_sibling_clone = n;
     821              :             }
     822              :         }
     823              : 
     824              :       /* Update clone_of pointers.  */
     825       433025 :       n = new_clones;
     826      3022642 :       while (n)
     827              :         {
     828      2589617 :           n->clone_of = next_inline_clone;
     829      2589617 :           n = n->next_sibling_clone;
     830              :         }
     831              : 
     832              :       /* Update order in order to be able to find a LTO section
     833              :          with function body.  */
     834       433025 :       replacement->order = order;
     835              : 
     836       433025 :       return replacement;
     837              :     }
     838              :   else
     839              :     return NULL;
     840              : }
     841              : 
     842              : /* Like cgraph_set_call_stmt but walk the clone tree and update all
     843              :    clones sharing the same function body.
     844              :    When WHOLE_SPECULATIVE_EDGES is true, all three components of
     845              :    speculative edge gets updated.  Otherwise we update only direct
     846              :    call.  */
     847              : 
     848              : void
     849      1928032 : cgraph_node::set_call_stmt_including_clones (gimple *old_stmt,
     850              :                                              gcall *new_stmt,
     851              :                                              bool update_speculative)
     852              : {
     853      1928032 :   cgraph_node *node;
     854      1928032 :   cgraph_edge *master_edge = get_edge (old_stmt);
     855              : 
     856      1928032 :   if (master_edge)
     857      1816993 :     cgraph_edge::set_call_stmt (master_edge, new_stmt, update_speculative);
     858              : 
     859      1928032 :   node = clones;
     860      1928032 :   if (node)
     861      1352772 :     while (node != this)
     862              :       {
     863      1090088 :         cgraph_edge *edge = node->get_edge (old_stmt);
     864      1090088 :         if (edge)
     865              :           {
     866      1083628 :             edge = cgraph_edge::set_call_stmt (edge, new_stmt,
     867              :                                                update_speculative);
     868              :             /* If UPDATE_SPECULATIVE is false, it means that we are turning
     869              :                speculative call into a real code sequence.  Update the
     870              :                callgraph edges.  */
     871      1083628 :             if (edge->speculative && !update_speculative)
     872              :               {
     873            0 :                 cgraph_edge *indirect = edge->speculative_call_indirect_edge ();
     874              : 
     875            0 :                 for (cgraph_edge *next, *direct
     876            0 :                         = edge->first_speculative_call_target ();
     877            0 :                      direct;
     878            0 :                      direct = next)
     879              :                   {
     880            0 :                     next = direct->next_speculative_call_target ();
     881            0 :                     direct->speculative_call_target_ref ()->speculative = false;
     882            0 :                     direct->speculative = false;
     883              :                   }
     884            0 :                 indirect->speculative = false;
     885              :               }
     886              :           }
     887      1090088 :         if (node->clones)
     888              :           node = node->clones;
     889      1044267 :         else if (node->next_sibling_clone)
     890              :           node = node->next_sibling_clone;
     891              :         else
     892              :           {
     893       594658 :             while (node != this && !node->next_sibling_clone)
     894       308505 :               node = node->clone_of;
     895       286153 :             if (node != this)
     896        23469 :               node = node->next_sibling_clone;
     897              :           }
     898              :       }
     899      1928032 : }
     900              : 
     901              : /* Like cgraph_create_edge walk the clone tree and update all clones sharing
     902              :    same function body.  If clones already have edge for OLD_STMT; only
     903              :    update the edge same way as cgraph_set_call_stmt_including_clones does.
     904              : 
     905              :    TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
     906              :    frequencies of the clones.  */
     907              : 
     908              : void
     909            0 : cgraph_node::create_edge_including_clones (cgraph_node *callee,
     910              :                                            gimple *old_stmt, gcall *stmt,
     911              :                                            profile_count count,
     912              :                                            cgraph_inline_failed_t reason)
     913              : {
     914            0 :   cgraph_node *node;
     915              : 
     916            0 :   if (!get_edge (stmt))
     917              :     {
     918            0 :       cgraph_edge *edge = create_edge (callee, stmt, count);
     919            0 :       edge->inline_failed = reason;
     920              :     }
     921              : 
     922            0 :   node = clones;
     923            0 :   if (node)
     924            0 :     while (node != this)
     925              :       /* Thunk clones do not get updated while copying inline function body.  */
     926            0 :       if (!node->thunk)
     927              :         {
     928            0 :           cgraph_edge *edge = node->get_edge (old_stmt);
     929              : 
     930              :           /* It is possible that clones already contain the edge while
     931              :              master didn't.  Either we promoted indirect call into direct
     932              :              call in the clone or we are processing clones of unreachable
     933              :              master where edges has been removed.  */
     934            0 :           if (edge)
     935            0 :             edge = cgraph_edge::set_call_stmt (edge, stmt);
     936            0 :           else if (! node->get_edge (stmt))
     937              :             {
     938            0 :               edge = node->create_edge (callee, stmt, count);
     939            0 :               edge->inline_failed = reason;
     940              :             }
     941              : 
     942            0 :           if (node->clones)
     943              :             node = node->clones;
     944            0 :           else if (node->next_sibling_clone)
     945              :             node = node->next_sibling_clone;
     946              :           else
     947              :             {
     948            0 :               while (node != this && !node->next_sibling_clone)
     949            0 :                 node = node->clone_of;
     950            0 :               if (node != this)
     951            0 :                 node = node->next_sibling_clone;
     952              :             }
     953              :         }
     954            0 : }
     955              : 
     956              : /* Remove the node from cgraph and all inline clones inlined into it.
     957              :    Skip however removal of FORBIDDEN_NODE and return true if it needs to be
     958              :    removed.  This allows to call the function from outer loop walking clone
     959              :    tree.  */
     960              : 
     961              : bool
     962          518 : cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
     963              : {
     964          518 :   cgraph_edge *e, *next;
     965          518 :   bool found = false;
     966              : 
     967          518 :   if (this == forbidden_node)
     968              :     {
     969            0 :       cgraph_edge::remove (callers);
     970            0 :       return true;
     971              :     }
     972          632 :   for (e = callees; e; e = next)
     973              :     {
     974          114 :       next = e->next_callee;
     975          114 :       if (!e->inline_failed)
     976           19 :         found |= e->callee->remove_symbol_and_inline_clones (forbidden_node);
     977              :     }
     978          518 :   remove ();
     979          518 :   return found;
     980              : }
     981              : 
     982              : /* The edges representing the callers of the NEW_VERSION node were
     983              :    fixed by cgraph_function_versioning (), now the call_expr in their
     984              :    respective tree code should be updated to call the NEW_VERSION.  */
     985              : 
     986              : static void
     987        58106 : update_call_expr (cgraph_node *new_version)
     988              : {
     989        58106 :   cgraph_edge *e;
     990              : 
     991        58106 :   gcc_assert (new_version);
     992              : 
     993              :   /* Update the call expr on the edges to call the new version.  */
     994        58106 :   for (e = new_version->callers; e; e = e->next_caller)
     995              :     {
     996            0 :       function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
     997            0 :       gimple_call_set_fndecl (e->call_stmt, new_version->decl);
     998            0 :       maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
     999              :     }
    1000        58106 : }
    1001              : 
    1002              : 
    1003              : /* Create a new cgraph node which is the new version of
    1004              :    callgraph node.  REDIRECT_CALLERS holds the callers
    1005              :    edges which should be redirected to point to
    1006              :    NEW_VERSION.  ALL the callees edges of the node
    1007              :    are cloned to the new version node.  Return the new
    1008              :    version node.
    1009              : 
    1010              :    If non-NULL BLOCK_TO_COPY determine what basic blocks
    1011              :    was copied to prevent duplications of calls that are dead
    1012              :    in the clone.  */
    1013              : 
    1014              : cgraph_node *
    1015        61304 : cgraph_node::create_version_clone (tree new_decl,
    1016              :                                   vec<cgraph_edge *> redirect_callers,
    1017              :                                   bitmap bbs_to_copy,
    1018              :                                   const char *suffix)
    1019              :  {
    1020        61304 :    cgraph_node *new_version;
    1021        61304 :    cgraph_edge *e;
    1022        61304 :    unsigned i;
    1023              : 
    1024        61304 :    new_version = cgraph_node::create (new_decl);
    1025              : 
    1026        61304 :    new_version->analyzed = analyzed;
    1027        61304 :    new_version->definition = definition;
    1028        61304 :    new_version->local = local;
    1029        61304 :    new_version->externally_visible = false;
    1030        61304 :    new_version->no_reorder = no_reorder;
    1031        61304 :    new_version->local = new_version->definition;
    1032        61304 :    new_version->inlined_to = inlined_to;
    1033        61304 :    new_version->rtl = rtl;
    1034        61304 :    new_version->count = count;
    1035        61304 :    new_version->unit_id = unit_id;
    1036        61304 :    new_version->merged_comdat = merged_comdat;
    1037        61304 :    new_version->merged_extern_inline = merged_extern_inline;
    1038              : 
    1039       312618 :    for (e = callees; e; e=e->next_callee)
    1040       251314 :      if (!bbs_to_copy
    1041       251314 :          || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
    1042       191257 :        e->clone (new_version, e->call_stmt,
    1043              :                  e->lto_stmt_uid, count, count,
    1044              :                  true);
    1045        68987 :    for (e = indirect_calls; e; e=e->next_callee)
    1046         7683 :      if (!bbs_to_copy
    1047         7683 :          || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
    1048         5167 :        e->clone (new_version, e->call_stmt,
    1049              :                  e->lto_stmt_uid, count, count,
    1050              :                  true);
    1051        61304 :    FOR_EACH_VEC_ELT (redirect_callers, i, e)
    1052              :      {
    1053              :        /* Redirect calls to the old version node to point to its new
    1054              :           version.  */
    1055            0 :        e->redirect_callee (new_version);
    1056              :      }
    1057        61304 :    new_version->calls_comdat_local = new_version->check_calls_comdat_local_p ();
    1058              : 
    1059        61304 :    dump_callgraph_transformation (this, new_version, suffix);
    1060              : 
    1061        61304 :    return new_version;
    1062              :  }
    1063              : 
    1064              : /* Perform function versioning.
    1065              :    Function versioning includes copying of the tree and
    1066              :    a callgraph update (creating a new cgraph node and updating
    1067              :    its callees and callers).
    1068              : 
    1069              :    REDIRECT_CALLERS varray includes the edges to be redirected
    1070              :    to the new version.
    1071              : 
    1072              :    TREE_MAP is a mapping of tree nodes we want to replace with
    1073              :    new ones (according to results of prior analysis).
    1074              : 
    1075              :    If non-NULL PARAM_ADJUSTMENTS determine how function formal parameters
    1076              :    should be modified in the new version and if it should return void.
    1077              :    If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
    1078              :    If non_NULL NEW_ENTRY determine new entry BB of the clone.
    1079              :    SUFFIX is a string that will be used to create a new name for the new
    1080              :    function.
    1081              : 
    1082              :    If TARGET_ATTRIBUTES is non-null, when creating a new declaration,
    1083              :    add the attributes to DECL_ATTRIBUTES.  And call valid_attribute_p
    1084              :    that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
    1085              :    of the declaration.
    1086              : 
    1087              :    If VERSION_DECL is set true, use clone_function_name_numbered for the
    1088              :    function clone.  Otherwise, use clone_function_name.
    1089              : 
    1090              :    Return the new version's cgraph node.  */
    1091              : 
    1092              : cgraph_node *
    1093        58107 : cgraph_node::create_version_clone_with_body
    1094              :   (vec<cgraph_edge *> redirect_callers,
    1095              :    vec<ipa_replace_map *, va_gc> *tree_map,
    1096              :    ipa_param_adjustments *param_adjustments,
    1097              :    bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix,
    1098              :    tree target_attributes, bool version_decl)
    1099              : {
    1100        58107 :   tree old_decl = decl;
    1101        58107 :   cgraph_node *new_version_node = NULL;
    1102        58107 :   tree new_decl;
    1103              : 
    1104        58107 :   if (!tree_versionable_function_p (old_decl))
    1105              :     return NULL;
    1106              : 
    1107              :   /* TODO: Restore an assert that we do not change signature if
    1108              :      can_change_signature is false.  We cannot just check that
    1109              :      param_adjustments is NULL because unfortunately ipa-split removes return
    1110              :      values from such functions.  */
    1111              : 
    1112              :   /* Make a new FUNCTION_DECL tree node for the new version. */
    1113        58107 :   if (param_adjustments)
    1114        29880 :     new_decl = param_adjustments->adjust_decl (old_decl);
    1115              :   else
    1116        28227 :     new_decl = copy_node (old_decl);
    1117              : 
    1118              :   /* Generate a new name for the new version. */
    1119        58107 :   tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix)
    1120          125 :                 : clone_function_name (old_decl, suffix));
    1121        58107 :   DECL_NAME (new_decl) = fnname;
    1122        58107 :   SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
    1123        58107 :   SET_DECL_RTL (new_decl, NULL);
    1124              : 
    1125        58107 :   DECL_VIRTUAL_P (new_decl) = 0;
    1126              : 
    1127        58107 :   if (target_attributes)
    1128              :     {
    1129          125 :       DECL_ATTRIBUTES (new_decl) = target_attributes;
    1130              : 
    1131          125 :       location_t saved_loc = input_location;
    1132          125 :       tree v = TREE_VALUE (target_attributes);
    1133          125 :       input_location = DECL_SOURCE_LOCATION (new_decl);
    1134          125 :       bool r;
    1135          125 :       tree name_id = get_attribute_name (target_attributes);
    1136          125 :       const char *name_str = IDENTIFIER_POINTER (name_id);
    1137          125 :       if (strcmp (name_str, "target") == 0)
    1138          125 :         r = targetm.target_option.valid_attribute_p (new_decl, name_id, v, 1);
    1139            0 :       else if (strcmp (name_str, "target_version") == 0)
    1140            0 :         r = targetm.target_option.valid_version_attribute_p (new_decl, name_id,
    1141              :                                                              v, 1);
    1142              :       else
    1143            0 :         gcc_unreachable();
    1144              : 
    1145          125 :       input_location = saved_loc;
    1146          125 :       if (!r)
    1147              :         return NULL;
    1148              :     }
    1149              : 
    1150              :   /* When the old decl was a con-/destructor make sure the clone isn't.  */
    1151        58106 :   DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
    1152        58106 :   DECL_STATIC_DESTRUCTOR (new_decl) = 0;
    1153        58106 :   DECL_SET_IS_OPERATOR_NEW (new_decl, 0);
    1154        58106 :   DECL_SET_IS_OPERATOR_DELETE (new_decl, 0);
    1155        58106 :   DECL_IS_REPLACEABLE_OPERATOR (new_decl) = 0;
    1156              : 
    1157              :   /* Create the new version's call-graph node.
    1158              :      and update the edges of the new node. */
    1159        58106 :   new_version_node = create_version_clone (new_decl, redirect_callers,
    1160              :                                           bbs_to_copy, suffix);
    1161              : 
    1162        58106 :   if (ipa_transforms_to_apply.exists ())
    1163            0 :     new_version_node->ipa_transforms_to_apply
    1164            0 :       = ipa_transforms_to_apply.copy ();
    1165              :   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
    1166        58106 :   tree_function_versioning (old_decl, new_decl, tree_map, param_adjustments,
    1167              :                             false, bbs_to_copy, new_entry_block);
    1168              : 
    1169              :   /* Update the new version's properties.
    1170              :      Make The new version visible only within this translation unit.  Make sure
    1171              :      that is not weak also.
    1172              :      ??? We cannot use COMDAT linkage because there is no
    1173              :      ABI support for this.  */
    1174        58106 :   new_version_node->make_decl_local ();
    1175        58106 :   DECL_VIRTUAL_P (new_version_node->decl) = 0;
    1176        58106 :   new_version_node->externally_visible = 0;
    1177        58106 :   new_version_node->local = 1;
    1178        58106 :   new_version_node->lowered = true;
    1179        58106 :   if (!implicit_section)
    1180        58090 :     new_version_node->set_section (*this);
    1181              :   /* Clones of global symbols or symbols with unique names are unique.  */
    1182        58106 :   if ((TREE_PUBLIC (old_decl)
    1183        54426 :        && !DECL_EXTERNAL (old_decl)
    1184        44033 :        && !DECL_WEAK (old_decl)
    1185        13212 :        && !DECL_COMDAT (old_decl))
    1186        99320 :       || in_lto_p)
    1187        13252 :     new_version_node->unique_name = true;
    1188              : 
    1189              :   /* Update the call_expr on the edges to call the new version node. */
    1190        58106 :   update_call_expr (new_version_node);
    1191              : 
    1192        58106 :   symtab->call_cgraph_insertion_hooks (new_version_node);
    1193        58106 :   return new_version_node;
    1194              : }
    1195              : 
    1196              : /* Remove the node from the tree of virtual and inline clones and make it a
    1197              :    standalone node - not a clone any more.  */
    1198              : 
    1199       145833 : void cgraph_node::remove_from_clone_tree ()
    1200              : {
    1201       145833 :   if (next_sibling_clone)
    1202          953 :     next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
    1203       145833 :   if (prev_sibling_clone)
    1204         1513 :     prev_sibling_clone->next_sibling_clone = next_sibling_clone;
    1205              :   else
    1206       144320 :     clone_of->clones = next_sibling_clone;
    1207       145833 :   next_sibling_clone = NULL;
    1208       145833 :   prev_sibling_clone = NULL;
    1209       145833 :   clone_of = NULL;
    1210       145833 : }
    1211              : 
    1212              : /* Given virtual clone, turn it into actual clone.  */
    1213              : 
    1214              : void
    1215       145833 : cgraph_node::materialize_clone ()
    1216              : {
    1217       145833 :   clone_info *info = clone_info::get (this);
    1218       145833 :   clone_of->get_untransformed_body ();
    1219       145833 :   former_clone_of = clone_of->decl;
    1220       145833 :   if (clone_of->former_clone_of)
    1221         4325 :     former_clone_of = clone_of->former_clone_of;
    1222       145833 :   if (symtab->dump_file)
    1223              :     {
    1224            0 :       fprintf (symtab->dump_file, "cloning %s to %s\n",
    1225            0 :                clone_of->dump_name (),
    1226              :                dump_name ());
    1227            0 :       if (info && info->tree_map)
    1228              :         {
    1229            0 :           fprintf (symtab->dump_file, "    replace map:");
    1230            0 :           for (unsigned int i = 0;
    1231            0 :                i < vec_safe_length (info->tree_map);
    1232              :                i++)
    1233              :             {
    1234            0 :               ipa_replace_map *replace_info;
    1235            0 :               replace_info = (*info->tree_map)[i];
    1236            0 :               fprintf (symtab->dump_file, "%s %i -> ",
    1237              :                        i ? "," : "", replace_info->parm_num);
    1238            0 :               print_generic_expr (symtab->dump_file,
    1239              :                                   replace_info->new_tree);
    1240              :             }
    1241            0 :           fprintf (symtab->dump_file, "\n");
    1242              :         }
    1243            0 :       if (info && info->param_adjustments)
    1244            0 :         info->param_adjustments->dump (symtab->dump_file);
    1245              :     }
    1246       145833 :   clear_stmts_in_references ();
    1247              :   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
    1248       145833 :   tree_function_versioning (clone_of->decl, decl,
    1249              :                             info ? info->tree_map : NULL,
    1250              :                             info ? info->param_adjustments : NULL,
    1251              :                             true, NULL, NULL);
    1252       145833 :   if (symtab->dump_file)
    1253              :     {
    1254            0 :       dump_function_to_file (clone_of->decl, symtab->dump_file,
    1255              :                              dump_flags);
    1256            0 :       dump_function_to_file (decl, symtab->dump_file, dump_flags);
    1257              :     }
    1258              : 
    1259       145833 :   cgraph_node *this_clone_of = clone_of;
    1260              :   /* Function is no longer clone.  */
    1261       145833 :   remove_from_clone_tree ();
    1262       145833 :   if (!this_clone_of->analyzed && !this_clone_of->clones)
    1263       142208 :     this_clone_of->release_body ();
    1264       145833 : }
    1265              : 
    1266              : #include "gt-cgraphclones.h"
        

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.