LCOV - code coverage report
Current view: top level - gcc - cgraphclones.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.0 % 535 444
Test Date: 2024-12-21 13:15:12 Functions: 91.3 % 23 21
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.