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