LCOV - code coverage report
Current view: top level - gcc - cgraphclones.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.0 % 534 443
Test Date: 2024-11-30 13:30:02 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                 :     5795865 : 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                 :     5795865 :   cgraph_edge *new_edge;
     103                 :     5795865 :   profile_count::adjust_for_ipa_scaling (&num, &den);
     104                 :     5795865 :   profile_count prof_count = count.apply_scale (num, den);
     105                 :             : 
     106                 :     5795865 :   if (indirect_unknown_callee)
     107                 :             :     {
     108                 :      160784 :       tree decl;
     109                 :             : 
     110                 :      160557 :       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                 :      165806 :           && !speculative)
     114                 :             :         {
     115                 :        5022 :           cgraph_node *callee = cgraph_node::get (decl);
     116                 :        5022 :           gcc_checking_assert (callee);
     117                 :        5022 :           new_edge = n->create_edge (callee, call_stmt, prof_count, true);
     118                 :             :         }
     119                 :             :       else
     120                 :             :         {
     121                 :      311524 :           new_edge = n->create_indirect_edge (call_stmt,
     122                 :      155762 :                                               indirect_info->ecf_flags,
     123                 :             :                                               prof_count, true);
     124                 :      155762 :           *new_edge->indirect_info = *indirect_info;
     125                 :             :         }
     126                 :             :     }
     127                 :             :   else
     128                 :             :     {
     129                 :     5635081 :       new_edge = n->create_edge (callee, call_stmt, prof_count, true);
     130                 :     5635081 :       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                 :     5795865 :   new_edge->inline_failed = inline_failed;
     139                 :     5795865 :   new_edge->indirect_inlining_edge = indirect_inlining_edge;
     140                 :     5795865 :   if (!call_stmt)
     141                 :      228202 :     new_edge->lto_stmt_uid = stmt_uid;
     142                 :     5795865 :   new_edge->speculative_id = speculative_id;
     143                 :             :   /* Clone flags that depend on call_stmt availability manually.  */
     144                 :     5795865 :   new_edge->can_throw_external = can_throw_external;
     145                 :     5795865 :   new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
     146                 :     5795865 :   new_edge->speculative = speculative;
     147                 :     5795865 :   new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
     148                 :             : 
     149                 :             :   /* Update IPA profile.  Local profiles need no updating in original.  */
     150                 :     5795865 :   if (update_original)
     151                 :     5205090 :     count = count.combine_with_ipa_count_within (count.ipa ()
     152                 :     5205090 :                                                  - new_edge->count.ipa (),
     153                 :     5205090 :                                                  caller->count);
     154                 :     5795865 :   symtab->call_edge_duplication_hooks (this, new_edge);
     155                 :     5795865 :   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                 :      109399 : set_new_clone_decl_and_node_flags (cgraph_node *new_node)
     163                 :             : {
     164                 :      109399 :   DECL_EXTERNAL (new_node->decl) = 0;
     165                 :      109399 :   TREE_PUBLIC (new_node->decl) = 0;
     166                 :      109399 :   DECL_COMDAT (new_node->decl) = 0;
     167                 :      109399 :   DECL_WEAK (new_node->decl) = 0;
     168                 :      109399 :   DECL_VIRTUAL_P (new_node->decl) = 0;
     169                 :      109399 :   DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0;
     170                 :      109399 :   DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
     171                 :      109399 :   DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0);
     172                 :      109399 :   DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0);
     173                 :      109399 :   DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
     174                 :             : 
     175                 :      109399 :   new_node->externally_visible = 0;
     176                 :      109399 :   new_node->local = 1;
     177                 :      109399 :   new_node->lowered = true;
     178                 :      109399 :   new_node->semantic_interposition = 0;
     179                 :      109399 : }
     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                 :      269103 : cgraph_edge::redirect_callee_duplicating_thunks (cgraph_node *n)
     276                 :             : {
     277                 :      269103 :   cgraph_node *orig_to = callee->ultimate_alias_target ();
     278                 :      269103 :   if (orig_to->thunk)
     279                 :          76 :     n = duplicate_thunk_for_node (orig_to, n);
     280                 :             : 
     281                 :      269103 :   redirect_callee (n);
     282                 :      269103 : }
     283                 :             : 
     284                 :             : /* Call expand_thunk on all callers that are thunks and if analyze those nodes
     285                 :             :    that were expanded.  */
     286                 :             : 
     287                 :             : void
     288                 :     2561580 : cgraph_node::expand_all_artificial_thunks ()
     289                 :             : {
     290                 :     2561580 :   cgraph_edge *e;
     291                 :     2830908 :   for (e = callers; e;)
     292                 :      269328 :     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                 :      269294 :       e = e->next_caller;
     308                 :     2561580 : }
     309                 :             : 
     310                 :             : void
     311                 :     3864849 : dump_callgraph_transformation (const cgraph_node *original,
     312                 :             :                                const cgraph_node *clone,
     313                 :             :                                const char *suffix)
     314                 :             : {
     315                 :     3864849 :   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                 :     3864849 : }
     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                 :     2561421 : 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                 :     2561421 :   cgraph_node *new_node = symtab->create_empty ();
     378                 :     2561421 :   cgraph_edge *e;
     379                 :     2561421 :   unsigned i;
     380                 :     2561421 :   profile_count old_count = count;
     381                 :     2561421 :   bool nonzero = count.ipa ().nonzero_p ();
     382                 :             : 
     383                 :     2561421 :   if (new_inlined_to)
     384                 :     2428150 :     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                 :     2428150 :   if (!new_inlined_to)
     389                 :      133271 :     prof_count = count.combine_with_ipa_count (prof_count);
     390                 :     2561421 :   new_node->count = prof_count;
     391                 :     2561421 :   new_node->calls_declare_variant_alt = this->calls_declare_variant_alt;
     392                 :             : 
     393                 :             :   /* Update IPA profile.  Local profiles need no updating in original.  */
     394                 :     2561421 :   if (update_original)
     395                 :             :     {
     396                 :     2411529 :       if (inlined_to)
     397                 :      336056 :         count = count.combine_with_ipa_count_within (count.ipa ()
     398                 :      672112 :                                                      - prof_count.ipa (),
     399                 :             :                                                      inlined_to->count);
     400                 :             :       else
     401                 :     2075473 :         count = count.combine_with_ipa_count (count.ipa () - prof_count.ipa ());
     402                 :             :     }
     403                 :     2561421 :   new_node->decl = new_decl;
     404                 :     2561421 :   new_node->register_symbol ();
     405                 :     2561421 :   new_node->lto_file_data = lto_file_data;
     406                 :     2561421 :   new_node->analyzed = analyzed;
     407                 :     2561421 :   new_node->definition = definition;
     408                 :     2561421 :   new_node->versionable = versionable;
     409                 :     2561421 :   new_node->can_change_signature = can_change_signature;
     410                 :     2561421 :   new_node->redefined_extern_inline = redefined_extern_inline;
     411                 :     2561421 :   new_node->semantic_interposition = semantic_interposition;
     412                 :     2561421 :   new_node->tm_may_enter_irr = tm_may_enter_irr;
     413                 :     2561421 :   new_node->externally_visible = false;
     414                 :     2561421 :   new_node->no_reorder = no_reorder;
     415                 :     2561421 :   new_node->local = true;
     416                 :     2561421 :   new_node->inlined_to = new_inlined_to;
     417                 :     2561421 :   new_node->rtl = rtl;
     418                 :     2561421 :   new_node->frequency = frequency;
     419                 :     2561421 :   new_node->tp_first_run = tp_first_run;
     420                 :     2561421 :   new_node->tm_clone = tm_clone;
     421                 :     2561421 :   new_node->icf_merged = icf_merged;
     422                 :     2561421 :   new_node->thunk = thunk;
     423                 :     2561421 :   new_node->unit_id = unit_id;
     424                 :     2561421 :   new_node->merged_comdat = merged_comdat;
     425                 :     2561421 :   new_node->merged_extern_inline = merged_extern_inline;
     426                 :     2561421 :   clone_info *info = clone_info::get (this);
     427                 :             : 
     428                 :     2561421 :   if (param_adjustments)
     429                 :      104243 :     clone_info::get_create (new_node)->param_adjustments = param_adjustments;
     430                 :     2457178 :   else if (info && info->param_adjustments)
     431                 :      196370 :     clone_info::get_create (new_node)->param_adjustments
     432                 :      196370 :          = info->param_adjustments;
     433                 :     2561421 :   new_node->split_part = split_part;
     434                 :             : 
     435                 :     2830312 :   FOR_EACH_VEC_ELT (redirect_callers, i, e)
     436                 :             :     {
     437                 :             :       /* Redirect calls to the old version node to point to its new
     438                 :             :          version.  The only exception is when the edge was proved to
     439                 :             :          be unreachable during the cloning procedure.  */
     440                 :      268891 :       if (!e->callee
     441                 :      268891 :           || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
     442                 :             :                                                   BUILT_IN_UNREACHABLE_TRAP))
     443                 :      268891 :         e->redirect_callee_duplicating_thunks (new_node);
     444                 :             :     }
     445                 :     2561421 :   new_node->expand_all_artificial_thunks ();
     446                 :             : 
     447                 :     4991368 :   for (e = callees;e; e=e->next_callee)
     448                 :     2429947 :     e->clone (new_node, e->call_stmt, e->lto_stmt_uid, new_node->count, old_count,
     449                 :             :               update_original);
     450                 :             : 
     451                 :     2632717 :   for (e = indirect_calls; e; e = e->next_callee)
     452                 :       71296 :     e->clone (new_node, e->call_stmt, e->lto_stmt_uid,
     453                 :             :               new_node->count, old_count, update_original);
     454                 :     2561421 :   new_node->clone_references (this);
     455                 :             : 
     456                 :     2561421 :   new_node->next_sibling_clone = clones;
     457                 :     2561421 :   if (clones)
     458                 :     1223714 :     clones->prev_sibling_clone = new_node;
     459                 :     2561421 :   clones = new_node;
     460                 :     2561421 :   new_node->clone_of = this;
     461                 :             : 
     462                 :     2561421 :   if (call_duplication_hook)
     463                 :     2429590 :     symtab->call_cgraph_duplication_hooks (this, new_node);
     464                 :             :   /* With partial train run we do not want to assume that original's
     465                 :             :      count is zero whenever we redurect all executed edges to clone.
     466                 :             :      Simply drop profile to local one in this case.  */
     467                 :     2561421 :   if (update_original
     468                 :     2411529 :       && opt_for_fn (decl, flag_profile_partial_training)
     469                 :           0 :       && nonzero
     470                 :           0 :       && count.ipa_p ()
     471                 :     2561421 :       && !count.ipa ().nonzero_p ()
     472                 :     2561421 :       && !inlined_to)
     473                 :           0 :     localize_profile (this);
     474                 :             : 
     475                 :     2561421 :   if (!new_inlined_to)
     476                 :      133271 :     dump_callgraph_transformation (this, new_node, suffix);
     477                 :             : 
     478                 :     2561421 :   return new_node;
     479                 :             : }
     480                 :             : 
     481                 :             : static GTY(()) hash_map<const char *, unsigned> *clone_fn_ids;
     482                 :             : 
     483                 :             : /* Return a new assembler name for a clone of decl named NAME.  Apart
     484                 :             :    from the string SUFFIX, the new name will end with a unique (for
     485                 :             :    each NAME) unspecified number.  If clone numbering is not needed
     486                 :             :    then the two argument clone_function_name should be used instead.
     487                 :             :    Should not be called directly except for by
     488                 :             :    lto-partition.cc:privatize_symbol_name_1.  */
     489                 :             : 
     490                 :             : tree
     491                 :       98869 : clone_function_name_numbered (const char *name, const char *suffix)
     492                 :             : {
     493                 :             :   /* Initialize the function->counter mapping the first time it's
     494                 :             :      needed.  */
     495                 :       98869 :   if (!clone_fn_ids)
     496                 :       19146 :     clone_fn_ids = hash_map<const char *, unsigned int>::create_ggc (64);
     497                 :      296607 :   unsigned int &suffix_counter = clone_fn_ids->get_or_insert (
     498                 :       98869 :                                    IDENTIFIER_POINTER (get_identifier (name)));
     499                 :       98869 :   return clone_function_name (name, suffix, suffix_counter++);
     500                 :             : }
     501                 :             : 
     502                 :             : /* Return a new assembler name for a clone of DECL.  Apart from string
     503                 :             :    SUFFIX, the new name will end with a unique (for each DECL
     504                 :             :    assembler name) unspecified number.  If clone numbering is not
     505                 :             :    needed then the two argument clone_function_name should be used
     506                 :             :    instead.  */
     507                 :             : 
     508                 :             : tree
     509                 :       98869 : clone_function_name_numbered (tree decl, const char *suffix)
     510                 :             : {
     511                 :       98869 :   tree name = DECL_ASSEMBLER_NAME (decl);
     512                 :       98869 :   return clone_function_name_numbered (IDENTIFIER_POINTER (name),
     513                 :       98869 :                                        suffix);
     514                 :             : }
     515                 :             : 
     516                 :             : /* Return a new assembler name for a clone of decl named NAME.  Apart
     517                 :             :    from the string SUFFIX, the new name will end with the specified
     518                 :             :    NUMBER.  If clone numbering is not needed then the two argument
     519                 :             :    clone_function_name should be used instead.  */
     520                 :             : 
     521                 :             : tree
     522                 :      216099 : clone_function_name (const char *name, const char *suffix,
     523                 :             :                      unsigned long number)
     524                 :             : {
     525                 :      216099 :   size_t len = strlen (name);
     526                 :      216099 :   char *tmp_name, *prefix;
     527                 :             : 
     528                 :      216099 :   prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
     529                 :      216099 :   memcpy (prefix, name, len);
     530                 :      216099 :   strcpy (prefix + len + 1, suffix);
     531                 :      216099 :   prefix[len] = symbol_table::symbol_suffix_separator ();
     532                 :      216099 :   ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, number);
     533                 :      216099 :   return get_identifier (tmp_name);
     534                 :             : }
     535                 :             : 
     536                 :             : /* Return a new assembler name for a clone of DECL.  Apart from the
     537                 :             :    string SUFFIX, the new name will end with the specified NUMBER.  If
     538                 :             :    clone numbering is not needed then the two argument
     539                 :             :    clone_function_name should be used instead.  */
     540                 :             : 
     541                 :             : tree
     542                 :      109368 : clone_function_name (tree decl, const char *suffix,
     543                 :             :                      unsigned long number)
     544                 :             : {
     545                 :      218736 :   return clone_function_name (
     546                 :      109368 :            IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), suffix, number);
     547                 :             : }
     548                 :             : 
     549                 :             : /* Return a new assembler name ending with the string SUFFIX for a
     550                 :             :    clone of DECL.  */
     551                 :             : 
     552                 :             : tree
     553                 :      102076 : clone_function_name (tree decl, const char *suffix)
     554                 :             : {
     555                 :      102076 :   tree identifier = DECL_ASSEMBLER_NAME (decl);
     556                 :             :   /* For consistency this needs to behave the same way as
     557                 :             :      ASM_FORMAT_PRIVATE_NAME does, but without the final number
     558                 :             :      suffix.  */
     559                 :      102076 :   char *separator = XALLOCAVEC (char, 2);
     560                 :      102076 :   separator[0] = symbol_table::symbol_suffix_separator ();
     561                 :      102076 :   separator[1] = 0;
     562                 :             : #if defined (NO_DOT_IN_LABEL) && defined (NO_DOLLAR_IN_LABEL)
     563                 :             :   const char *prefix = "__";
     564                 :             : #else
     565                 :      102076 :   const char *prefix = "";
     566                 :             : #endif
     567                 :      102076 :   char *result = ACONCAT ((prefix,
     568                 :             :                            IDENTIFIER_POINTER (identifier),
     569                 :             :                            separator,
     570                 :             :                            suffix,
     571                 :             :                            (char*)0));
     572                 :      102076 :   return get_identifier (result);
     573                 :             : }
     574                 :             : 
     575                 :             : 
     576                 :             : /* Create callgraph node clone with new declaration.  The actual body will be
     577                 :             :    copied later at compilation stage.  The name of the new clone will be
     578                 :             :    constructed from the name of the original node, SUFFIX and NUM_SUFFIX.
     579                 :             : 
     580                 :             :    TODO: after merging in ipa-sra use function call notes instead of args_to_skip
     581                 :             :    bitmap interface.
     582                 :             :    */
     583                 :             : cgraph_node *
     584                 :      109368 : cgraph_node::create_virtual_clone (const vec<cgraph_edge *> &redirect_callers,
     585                 :             :                                    vec<ipa_replace_map *, va_gc> *tree_map,
     586                 :             :                                    ipa_param_adjustments *param_adjustments,
     587                 :             :                                    const char * suffix, unsigned num_suffix)
     588                 :             : {
     589                 :      109368 :   tree old_decl = decl;
     590                 :      109368 :   cgraph_node *new_node = NULL;
     591                 :      109368 :   tree new_decl;
     592                 :      109368 :   size_t len, i;
     593                 :      109368 :   ipa_replace_map *map;
     594                 :      109368 :   char *name;
     595                 :             : 
     596                 :      109368 :   gcc_checking_assert (versionable);
     597                 :             :   /* TODO: It would be nice if we could recognize that param_adjustments do not
     598                 :             :      actually perform any changes, but at the moment let's require it simply
     599                 :             :      does not exist.  */
     600                 :      109368 :   gcc_assert (can_change_signature || !param_adjustments);
     601                 :             : 
     602                 :             :   /* Make a new FUNCTION_DECL tree node */
     603                 :      108235 :   if (!param_adjustments)
     604                 :        5125 :     new_decl = copy_node (old_decl);
     605                 :             :   else
     606                 :      104243 :     new_decl = param_adjustments->adjust_decl (old_decl);
     607                 :             : 
     608                 :             :   /* These pointers represent function body and will be populated only when clone
     609                 :             :      is materialized.  */
     610                 :      109368 :   gcc_assert (new_decl != old_decl);
     611                 :      109368 :   DECL_STRUCT_FUNCTION (new_decl) = NULL;
     612                 :      109368 :   DECL_ARGUMENTS (new_decl) = NULL;
     613                 :      109368 :   DECL_INITIAL (new_decl) = NULL;
     614                 :      109368 :   DECL_RESULT (new_decl) = NULL;
     615                 :             :   /* We cannot do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
     616                 :             :      sometimes storing only clone decl instead of original.  */
     617                 :             : 
     618                 :             :   /* Generate a new name for the new version. */
     619                 :      109368 :   len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
     620                 :      109368 :   name = XALLOCAVEC (char, len + strlen (suffix) + 2);
     621                 :      109368 :   memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
     622                 :      109368 :   strcpy (name + len + 1, suffix);
     623                 :      109368 :   name[len] = '.';
     624                 :      109368 :   DECL_NAME (new_decl) = get_identifier (name);
     625                 :      109368 :   SET_DECL_ASSEMBLER_NAME (new_decl,
     626                 :             :                            clone_function_name (old_decl, suffix, num_suffix));
     627                 :      109368 :   SET_DECL_RTL (new_decl, NULL);
     628                 :             : 
     629                 :      109368 :   new_node = create_clone (new_decl, count, false,
     630                 :             :                            redirect_callers, false, NULL, param_adjustments,
     631                 :             :                            suffix);
     632                 :             : 
     633                 :             :   /* Update the properties.
     634                 :             :      Make clone visible only within this translation unit.  Make sure
     635                 :             :      that is not weak also.
     636                 :             :      ??? We cannot use COMDAT linkage because there is no
     637                 :             :      ABI support for this.  */
     638                 :      109368 :   set_new_clone_decl_and_node_flags (new_node);
     639                 :      109368 :   new_node->ipcp_clone = ipcp_clone;
     640                 :      109368 :   if (tree_map)
     641                 :       10886 :     clone_info::get_create (new_node)->tree_map = tree_map;
     642                 :      109368 :   if (!implicit_section)
     643                 :      109336 :     new_node->set_section (*this);
     644                 :             : 
     645                 :             :   /* Clones of global symbols or symbols with unique names are unique.  */
     646                 :      109368 :   if ((TREE_PUBLIC (old_decl)
     647                 :       79967 :        && !DECL_EXTERNAL (old_decl)
     648                 :       73056 :        && !DECL_WEAK (old_decl)
     649                 :        2160 :        && !DECL_COMDAT (old_decl))
     650                 :      187175 :       || in_lto_p)
     651                 :        5838 :     new_node->unique_name = true;
     652                 :      127323 :   FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
     653                 :             :     {
     654                 :       17955 :       tree repl = map->new_tree;
     655                 :       17955 :       if (map->force_load_ref)
     656                 :             :         {
     657                 :         300 :           gcc_assert (TREE_CODE (repl) == ADDR_EXPR);
     658                 :         300 :           repl = get_base_address (TREE_OPERAND (repl, 0));
     659                 :             :         }
     660                 :       17955 :       new_node->maybe_create_reference (repl, NULL);
     661                 :             :     }
     662                 :             : 
     663                 :      109368 :   if (ipa_transforms_to_apply.exists ())
     664                 :       92068 :     new_node->ipa_transforms_to_apply
     665                 :       92068 :       = ipa_transforms_to_apply.copy ();
     666                 :             : 
     667                 :      109368 :   symtab->call_cgraph_duplication_hooks (this, new_node);
     668                 :             : 
     669                 :      109368 :   return new_node;
     670                 :             : }
     671                 :             : 
     672                 :             : /* callgraph node being removed from symbol table; see if its entry can be
     673                 :             :    replaced by other inline clone.
     674                 :             :    INFO is clone info to attach to the new root.  */
     675                 :             : cgraph_node *
     676                 :    88605029 : cgraph_node::find_replacement (clone_info *info)
     677                 :             : {
     678                 :    88605029 :   cgraph_node *next_inline_clone, *replacement;
     679                 :             : 
     680                 :    88605029 :   for (next_inline_clone = clones;
     681                 :             :        next_inline_clone
     682                 :    88605029 :        && next_inline_clone->decl != decl;
     683                 :           0 :        next_inline_clone = next_inline_clone->next_sibling_clone)
     684                 :             :     ;
     685                 :             : 
     686                 :             :   /* If there is inline clone of the node being removed, we need
     687                 :             :      to put it into the position of removed node and reorganize all
     688                 :             :      other clones to be based on it.  */
     689                 :    88605029 :   if (next_inline_clone)
     690                 :             :     {
     691                 :      343082 :       cgraph_node *n;
     692                 :      343082 :       cgraph_node *new_clones;
     693                 :             : 
     694                 :      343082 :       replacement = next_inline_clone;
     695                 :             : 
     696                 :             :       /* Unlink inline clone from the list of clones of removed node.  */
     697                 :      343082 :       if (next_inline_clone->next_sibling_clone)
     698                 :      208932 :         next_inline_clone->next_sibling_clone->prev_sibling_clone
     699                 :      208932 :           = next_inline_clone->prev_sibling_clone;
     700                 :      343082 :       if (next_inline_clone->prev_sibling_clone)
     701                 :             :         {
     702                 :           0 :           gcc_assert (clones != next_inline_clone);
     703                 :           0 :           next_inline_clone->prev_sibling_clone->next_sibling_clone
     704                 :           0 :             = next_inline_clone->next_sibling_clone;
     705                 :             :         }
     706                 :             :       else
     707                 :             :         {
     708                 :      343082 :           gcc_assert (clones == next_inline_clone);
     709                 :      343082 :           clones = next_inline_clone->next_sibling_clone;
     710                 :             :         }
     711                 :             : 
     712                 :      343082 :       new_clones = clones;
     713                 :      343082 :       clones = NULL;
     714                 :             : 
     715                 :             :       /* Copy clone info.  */
     716                 :      343082 :       if (info)
     717                 :       50048 :         *clone_info::get_create (next_inline_clone) = *info;
     718                 :             : 
     719                 :             :       /* Now place it into clone tree at same level at NODE.  */
     720                 :      343082 :       next_inline_clone->clone_of = clone_of;
     721                 :      343082 :       next_inline_clone->prev_sibling_clone = NULL;
     722                 :      343082 :       next_inline_clone->next_sibling_clone = NULL;
     723                 :      343082 :       if (clone_of)
     724                 :             :         {
     725                 :        2275 :           if (clone_of->clones)
     726                 :        2275 :             clone_of->clones->prev_sibling_clone = next_inline_clone;
     727                 :        2275 :           next_inline_clone->next_sibling_clone = clone_of->clones;
     728                 :        2275 :           clone_of->clones = next_inline_clone;
     729                 :             :         }
     730                 :             : 
     731                 :             :       /* Merge the clone list.  */
     732                 :      343082 :       if (new_clones)
     733                 :             :         {
     734                 :      208932 :           if (!next_inline_clone->clones)
     735                 :      206641 :             next_inline_clone->clones = new_clones;
     736                 :             :           else
     737                 :             :             {
     738                 :             :               n = next_inline_clone->clones;
     739                 :       10994 :               while (n->next_sibling_clone)
     740                 :             :                 n = n->next_sibling_clone;
     741                 :        2291 :               n->next_sibling_clone = new_clones;
     742                 :        2291 :               new_clones->prev_sibling_clone = n;
     743                 :             :             }
     744                 :             :         }
     745                 :             : 
     746                 :             :       /* Update clone_of pointers.  */
     747                 :             :       n = new_clones;
     748                 :     2483716 :       while (n)
     749                 :             :         {
     750                 :     2140634 :           n->clone_of = next_inline_clone;
     751                 :     2140634 :           n = n->next_sibling_clone;
     752                 :             :         }
     753                 :             : 
     754                 :             :       /* Update order in order to be able to find a LTO section
     755                 :             :          with function body.  */
     756                 :      343082 :       replacement->order = order;
     757                 :             : 
     758                 :      343082 :       return replacement;
     759                 :             :     }
     760                 :             :   else
     761                 :             :     return NULL;
     762                 :             : }
     763                 :             : 
     764                 :             : /* Like cgraph_set_call_stmt but walk the clone tree and update all
     765                 :             :    clones sharing the same function body.
     766                 :             :    When WHOLE_SPECULATIVE_EDGES is true, all three components of
     767                 :             :    speculative edge gets updated.  Otherwise we update only direct
     768                 :             :    call.  */
     769                 :             : 
     770                 :             : void
     771                 :     1361340 : cgraph_node::set_call_stmt_including_clones (gimple *old_stmt,
     772                 :             :                                              gcall *new_stmt,
     773                 :             :                                              bool update_speculative)
     774                 :             : {
     775                 :     1361340 :   cgraph_node *node;
     776                 :     1361340 :   cgraph_edge *master_edge = get_edge (old_stmt);
     777                 :             : 
     778                 :     1361340 :   if (master_edge)
     779                 :     1261819 :     cgraph_edge::set_call_stmt (master_edge, new_stmt, update_speculative);
     780                 :             : 
     781                 :     1361340 :   node = clones;
     782                 :     1361340 :   if (node)
     783                 :      962933 :     while (node != this)
     784                 :             :       {
     785                 :      753441 :         cgraph_edge *edge = node->get_edge (old_stmt);
     786                 :      753441 :         if (edge)
     787                 :             :           {
     788                 :      751476 :             edge = cgraph_edge::set_call_stmt (edge, new_stmt,
     789                 :             :                                                update_speculative);
     790                 :             :             /* If UPDATE_SPECULATIVE is false, it means that we are turning
     791                 :             :                speculative call into a real code sequence.  Update the
     792                 :             :                callgraph edges.  */
     793                 :      751476 :             if (edge->speculative && !update_speculative)
     794                 :             :               {
     795                 :           0 :                 cgraph_edge *indirect = edge->speculative_call_indirect_edge ();
     796                 :             : 
     797                 :           0 :                 for (cgraph_edge *next, *direct
     798                 :           0 :                         = edge->first_speculative_call_target ();
     799                 :           0 :                      direct;
     800                 :           0 :                      direct = next)
     801                 :             :                   {
     802                 :           0 :                     next = direct->next_speculative_call_target ();
     803                 :           0 :                     direct->speculative_call_target_ref ()->speculative = false;
     804                 :           0 :                     direct->speculative = false;
     805                 :             :                   }
     806                 :           0 :                 indirect->speculative = false;
     807                 :             :               }
     808                 :             :           }
     809                 :      753441 :         if (node->clones)
     810                 :             :           node = node->clones;
     811                 :      730589 :         else if (node->next_sibling_clone)
     812                 :             :           node = node->next_sibling_clone;
     813                 :             :         else
     814                 :             :           {
     815                 :      453709 :             while (node != this && !node->next_sibling_clone)
     816                 :      232344 :               node = node->clone_of;
     817                 :      221365 :             if (node != this)
     818                 :       11873 :               node = node->next_sibling_clone;
     819                 :             :           }
     820                 :             :       }
     821                 :     1361340 : }
     822                 :             : 
     823                 :             : /* Like cgraph_create_edge walk the clone tree and update all clones sharing
     824                 :             :    same function body.  If clones already have edge for OLD_STMT; only
     825                 :             :    update the edge same way as cgraph_set_call_stmt_including_clones does.
     826                 :             : 
     827                 :             :    TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
     828                 :             :    frequencies of the clones.  */
     829                 :             : 
     830                 :             : void
     831                 :           0 : cgraph_node::create_edge_including_clones (cgraph_node *callee,
     832                 :             :                                            gimple *old_stmt, gcall *stmt,
     833                 :             :                                            profile_count count,
     834                 :             :                                            cgraph_inline_failed_t reason)
     835                 :             : {
     836                 :           0 :   cgraph_node *node;
     837                 :             : 
     838                 :           0 :   if (!get_edge (stmt))
     839                 :             :     {
     840                 :           0 :       cgraph_edge *edge = create_edge (callee, stmt, count);
     841                 :           0 :       edge->inline_failed = reason;
     842                 :             :     }
     843                 :             : 
     844                 :           0 :   node = clones;
     845                 :           0 :   if (node)
     846                 :           0 :     while (node != this)
     847                 :             :       /* Thunk clones do not get updated while copying inline function body.  */
     848                 :           0 :       if (!node->thunk)
     849                 :             :         {
     850                 :           0 :           cgraph_edge *edge = node->get_edge (old_stmt);
     851                 :             : 
     852                 :             :           /* It is possible that clones already contain the edge while
     853                 :             :              master didn't.  Either we promoted indirect call into direct
     854                 :             :              call in the clone or we are processing clones of unreachable
     855                 :             :              master where edges has been removed.  */
     856                 :           0 :           if (edge)
     857                 :           0 :             edge = cgraph_edge::set_call_stmt (edge, stmt);
     858                 :           0 :           else if (! node->get_edge (stmt))
     859                 :             :             {
     860                 :           0 :               edge = node->create_edge (callee, stmt, count);
     861                 :           0 :               edge->inline_failed = reason;
     862                 :             :             }
     863                 :             : 
     864                 :           0 :           if (node->clones)
     865                 :             :             node = node->clones;
     866                 :           0 :           else if (node->next_sibling_clone)
     867                 :             :             node = node->next_sibling_clone;
     868                 :             :           else
     869                 :             :             {
     870                 :           0 :               while (node != this && !node->next_sibling_clone)
     871                 :           0 :                 node = node->clone_of;
     872                 :           0 :               if (node != this)
     873                 :           0 :                 node = node->next_sibling_clone;
     874                 :             :             }
     875                 :             :         }
     876                 :           0 : }
     877                 :             : 
     878                 :             : /* Remove the node from cgraph and all inline clones inlined into it.
     879                 :             :    Skip however removal of FORBIDDEN_NODE and return true if it needs to be
     880                 :             :    removed.  This allows to call the function from outer loop walking clone
     881                 :             :    tree.  */
     882                 :             : 
     883                 :             : bool
     884                 :          28 : cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
     885                 :             : {
     886                 :          28 :   cgraph_edge *e, *next;
     887                 :          28 :   bool found = false;
     888                 :             : 
     889                 :          28 :   if (this == forbidden_node)
     890                 :             :     {
     891                 :           0 :       cgraph_edge::remove (callers);
     892                 :           0 :       return true;
     893                 :             :     }
     894                 :          38 :   for (e = callees; e; e = next)
     895                 :             :     {
     896                 :          10 :       next = e->next_callee;
     897                 :          10 :       if (!e->inline_failed)
     898                 :           0 :         found |= e->callee->remove_symbol_and_inline_clones (forbidden_node);
     899                 :             :     }
     900                 :          28 :   remove ();
     901                 :          28 :   return found;
     902                 :             : }
     903                 :             : 
     904                 :             : /* The edges representing the callers of the NEW_VERSION node were
     905                 :             :    fixed by cgraph_function_versioning (), now the call_expr in their
     906                 :             :    respective tree code should be updated to call the NEW_VERSION.  */
     907                 :             : 
     908                 :             : static void
     909                 :       47466 : update_call_expr (cgraph_node *new_version)
     910                 :             : {
     911                 :       47466 :   cgraph_edge *e;
     912                 :             : 
     913                 :       47466 :   gcc_assert (new_version);
     914                 :             : 
     915                 :             :   /* Update the call expr on the edges to call the new version.  */
     916                 :       47466 :   for (e = new_version->callers; e; e = e->next_caller)
     917                 :             :     {
     918                 :           0 :       function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
     919                 :           0 :       gimple_call_set_fndecl (e->call_stmt, new_version->decl);
     920                 :           0 :       maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
     921                 :             :     }
     922                 :       47466 : }
     923                 :             : 
     924                 :             : 
     925                 :             : /* Create a new cgraph node which is the new version of
     926                 :             :    callgraph node.  REDIRECT_CALLERS holds the callers
     927                 :             :    edges which should be redirected to point to
     928                 :             :    NEW_VERSION.  ALL the callees edges of the node
     929                 :             :    are cloned to the new version node.  Return the new
     930                 :             :    version node.
     931                 :             : 
     932                 :             :    If non-NULL BLOCK_TO_COPY determine what basic blocks
     933                 :             :    was copied to prevent duplications of calls that are dead
     934                 :             :    in the clone.  */
     935                 :             : 
     936                 :             : cgraph_node *
     937                 :       50548 : cgraph_node::create_version_clone (tree new_decl,
     938                 :             :                                   vec<cgraph_edge *> redirect_callers,
     939                 :             :                                   bitmap bbs_to_copy,
     940                 :             :                                   const char *suffix)
     941                 :             :  {
     942                 :       50548 :    cgraph_node *new_version;
     943                 :       50548 :    cgraph_edge *e;
     944                 :       50548 :    unsigned i;
     945                 :             : 
     946                 :       50548 :    new_version = cgraph_node::create (new_decl);
     947                 :             : 
     948                 :       50548 :    new_version->analyzed = analyzed;
     949                 :       50548 :    new_version->definition = definition;
     950                 :       50548 :    new_version->local = local;
     951                 :       50548 :    new_version->externally_visible = false;
     952                 :       50548 :    new_version->no_reorder = no_reorder;
     953                 :       50548 :    new_version->local = new_version->definition;
     954                 :       50548 :    new_version->inlined_to = inlined_to;
     955                 :       50548 :    new_version->rtl = rtl;
     956                 :       50548 :    new_version->count = count;
     957                 :       50548 :    new_version->unit_id = unit_id;
     958                 :       50548 :    new_version->merged_comdat = merged_comdat;
     959                 :       50548 :    new_version->merged_extern_inline = merged_extern_inline;
     960                 :             : 
     961                 :      274874 :    for (e = callees; e; e=e->next_callee)
     962                 :      224326 :      if (!bbs_to_copy
     963                 :      224326 :          || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
     964                 :      175554 :        e->clone (new_version, e->call_stmt,
     965                 :             :                  e->lto_stmt_uid, count, count,
     966                 :             :                  true);
     967                 :       57829 :    for (e = indirect_calls; e; e=e->next_callee)
     968                 :        7281 :      if (!bbs_to_copy
     969                 :        7281 :          || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
     970                 :        4874 :        e->clone (new_version, e->call_stmt,
     971                 :             :                  e->lto_stmt_uid, count, count,
     972                 :             :                  true);
     973                 :       50548 :    FOR_EACH_VEC_ELT (redirect_callers, i, e)
     974                 :             :      {
     975                 :             :        /* Redirect calls to the old version node to point to its new
     976                 :             :           version.  */
     977                 :           0 :        e->redirect_callee (new_version);
     978                 :             :      }
     979                 :             : 
     980                 :       50548 :    dump_callgraph_transformation (this, new_version, suffix);
     981                 :             : 
     982                 :       50548 :    return new_version;
     983                 :             :  }
     984                 :             : 
     985                 :             : /* Perform function versioning.
     986                 :             :    Function versioning includes copying of the tree and
     987                 :             :    a callgraph update (creating a new cgraph node and updating
     988                 :             :    its callees and callers).
     989                 :             : 
     990                 :             :    REDIRECT_CALLERS varray includes the edges to be redirected
     991                 :             :    to the new version.
     992                 :             : 
     993                 :             :    TREE_MAP is a mapping of tree nodes we want to replace with
     994                 :             :    new ones (according to results of prior analysis).
     995                 :             : 
     996                 :             :    If non-NULL ARGS_TO_SKIP determine function parameters to remove
     997                 :             :    from new version.
     998                 :             :    If SKIP_RETURN is true, the new version will return void.
     999                 :             :    If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
    1000                 :             :    If non_NULL NEW_ENTRY determine new entry BB of the clone.
    1001                 :             : 
    1002                 :             :    If TARGET_ATTRIBUTES is non-null, when creating a new declaration,
    1003                 :             :    add the attributes to DECL_ATTRIBUTES.  And call valid_attribute_p
    1004                 :             :    that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
    1005                 :             :    of the declaration.
    1006                 :             : 
    1007                 :             :    If VERSION_DECL is set true, use clone_function_name_numbered for the
    1008                 :             :    function clone.  Otherwise, use clone_function_name.
    1009                 :             : 
    1010                 :             :    Return the new version's cgraph node.  */
    1011                 :             : 
    1012                 :             : cgraph_node *
    1013                 :       47467 : cgraph_node::create_version_clone_with_body
    1014                 :             :   (vec<cgraph_edge *> redirect_callers,
    1015                 :             :    vec<ipa_replace_map *, va_gc> *tree_map,
    1016                 :             :    ipa_param_adjustments *param_adjustments,
    1017                 :             :    bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix,
    1018                 :             :    tree target_attributes, bool version_decl)
    1019                 :             : {
    1020                 :       47467 :   tree old_decl = decl;
    1021                 :       47467 :   cgraph_node *new_version_node = NULL;
    1022                 :       47467 :   tree new_decl;
    1023                 :             : 
    1024                 :       47467 :   if (!tree_versionable_function_p (old_decl))
    1025                 :             :     return NULL;
    1026                 :             : 
    1027                 :             :   /* TODO: Restore an assert that we do not change signature if
    1028                 :             :      can_change_signature is false.  We cannot just check that
    1029                 :             :      param_adjustments is NULL because unfortunately ipa-split removes return
    1030                 :             :      values from such functions.  */
    1031                 :             : 
    1032                 :             :   /* Make a new FUNCTION_DECL tree node for the new version. */
    1033                 :       47467 :   if (param_adjustments)
    1034                 :       23830 :     new_decl = param_adjustments->adjust_decl (old_decl);
    1035                 :             :   else
    1036                 :       23637 :     new_decl = copy_node (old_decl);
    1037                 :             : 
    1038                 :             :   /* Generate a new name for the new version. */
    1039                 :       47467 :   tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix)
    1040                 :          98 :                 : clone_function_name (old_decl, suffix));
    1041                 :       47467 :   DECL_NAME (new_decl) = fnname;
    1042                 :       47467 :   SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
    1043                 :       47467 :   SET_DECL_RTL (new_decl, NULL);
    1044                 :             : 
    1045                 :       47467 :   DECL_VIRTUAL_P (new_decl) = 0;
    1046                 :             : 
    1047                 :       47467 :   if (target_attributes)
    1048                 :             :     {
    1049                 :          98 :       DECL_ATTRIBUTES (new_decl) = target_attributes;
    1050                 :             : 
    1051                 :          98 :       location_t saved_loc = input_location;
    1052                 :          98 :       tree v = TREE_VALUE (target_attributes);
    1053                 :          98 :       input_location = DECL_SOURCE_LOCATION (new_decl);
    1054                 :          98 :       bool r;
    1055                 :          98 :       tree name_id = get_attribute_name (target_attributes);
    1056                 :          98 :       const char *name_str = IDENTIFIER_POINTER (name_id);
    1057                 :          98 :       if (strcmp (name_str, "target") == 0)
    1058                 :          98 :         r = targetm.target_option.valid_attribute_p (new_decl, name_id, v, 1);
    1059                 :           0 :       else if (strcmp (name_str, "target_version") == 0)
    1060                 :           0 :         r = targetm.target_option.valid_version_attribute_p (new_decl, name_id,
    1061                 :             :                                                              v, 1);
    1062                 :             :       else
    1063                 :           0 :         gcc_unreachable();
    1064                 :             : 
    1065                 :          98 :       input_location = saved_loc;
    1066                 :          98 :       if (!r)
    1067                 :             :         return NULL;
    1068                 :             :     }
    1069                 :             : 
    1070                 :             :   /* When the old decl was a con-/destructor make sure the clone isn't.  */
    1071                 :       47466 :   DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
    1072                 :       47466 :   DECL_STATIC_DESTRUCTOR (new_decl) = 0;
    1073                 :       47466 :   DECL_SET_IS_OPERATOR_NEW (new_decl, 0);
    1074                 :       47466 :   DECL_SET_IS_OPERATOR_DELETE (new_decl, 0);
    1075                 :       47466 :   DECL_IS_REPLACEABLE_OPERATOR (new_decl) = 0;
    1076                 :             : 
    1077                 :             :   /* Create the new version's call-graph node.
    1078                 :             :      and update the edges of the new node. */
    1079                 :       47466 :   new_version_node = create_version_clone (new_decl, redirect_callers,
    1080                 :             :                                           bbs_to_copy, suffix);
    1081                 :             : 
    1082                 :       47466 :   if (ipa_transforms_to_apply.exists ())
    1083                 :           0 :     new_version_node->ipa_transforms_to_apply
    1084                 :           0 :       = ipa_transforms_to_apply.copy ();
    1085                 :             :   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
    1086                 :       47466 :   tree_function_versioning (old_decl, new_decl, tree_map, param_adjustments,
    1087                 :             :                             false, bbs_to_copy, new_entry_block);
    1088                 :             : 
    1089                 :             :   /* Update the new version's properties.
    1090                 :             :      Make The new version visible only within this translation unit.  Make sure
    1091                 :             :      that is not weak also.
    1092                 :             :      ??? We cannot use COMDAT linkage because there is no
    1093                 :             :      ABI support for this.  */
    1094                 :       47466 :   new_version_node->make_decl_local ();
    1095                 :       47466 :   DECL_VIRTUAL_P (new_version_node->decl) = 0;
    1096                 :       47466 :   new_version_node->externally_visible = 0;
    1097                 :       47466 :   new_version_node->local = 1;
    1098                 :       47466 :   new_version_node->lowered = true;
    1099                 :       47466 :   if (!implicit_section)
    1100                 :       47450 :     new_version_node->set_section (*this);
    1101                 :             :   /* Clones of global symbols or symbols with unique names are unique.  */
    1102                 :       47466 :   if ((TREE_PUBLIC (old_decl)
    1103                 :       44156 :        && !DECL_EXTERNAL (old_decl)
    1104                 :       36951 :        && !DECL_WEAK (old_decl)
    1105                 :       12500 :        && !DECL_COMDAT (old_decl))
    1106                 :       79122 :       || in_lto_p)
    1107                 :       12540 :     new_version_node->unique_name = true;
    1108                 :             : 
    1109                 :             :   /* Update the call_expr on the edges to call the new version node. */
    1110                 :       47466 :   update_call_expr (new_version_node);
    1111                 :             : 
    1112                 :       47466 :   symtab->call_cgraph_insertion_hooks (new_version_node);
    1113                 :       47466 :   return new_version_node;
    1114                 :             : }
    1115                 :             : 
    1116                 :             : /* Remove the node from the tree of virtual and inline clones and make it a
    1117                 :             :    standalone node - not a clone any more.  */
    1118                 :             : 
    1119                 :      108419 : void cgraph_node::remove_from_clone_tree ()
    1120                 :             : {
    1121                 :      108419 :   if (next_sibling_clone)
    1122                 :         308 :     next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
    1123                 :      108419 :   if (prev_sibling_clone)
    1124                 :         501 :     prev_sibling_clone->next_sibling_clone = next_sibling_clone;
    1125                 :             :   else
    1126                 :      107918 :     clone_of->clones = next_sibling_clone;
    1127                 :      108419 :   next_sibling_clone = NULL;
    1128                 :      108419 :   prev_sibling_clone = NULL;
    1129                 :      108419 :   clone_of = NULL;
    1130                 :      108419 : }
    1131                 :             : 
    1132                 :             : /* Given virtual clone, turn it into actual clone.  */
    1133                 :             : 
    1134                 :             : void
    1135                 :      108419 : cgraph_node::materialize_clone ()
    1136                 :             : {
    1137                 :      108419 :   clone_info *info = clone_info::get (this);
    1138                 :      108419 :   clone_of->get_untransformed_body ();
    1139                 :      108419 :   former_clone_of = clone_of->decl;
    1140                 :      108419 :   if (clone_of->former_clone_of)
    1141                 :        3294 :     former_clone_of = clone_of->former_clone_of;
    1142                 :      108419 :   if (symtab->dump_file)
    1143                 :             :     {
    1144                 :           0 :       fprintf (symtab->dump_file, "cloning %s to %s\n",
    1145                 :           0 :                clone_of->dump_name (),
    1146                 :             :                dump_name ());
    1147                 :           0 :       if (info && info->tree_map)
    1148                 :             :         {
    1149                 :           0 :           fprintf (symtab->dump_file, "    replace map:");
    1150                 :           0 :           for (unsigned int i = 0;
    1151                 :           0 :                i < vec_safe_length (info->tree_map);
    1152                 :             :                i++)
    1153                 :             :             {
    1154                 :           0 :               ipa_replace_map *replace_info;
    1155                 :           0 :               replace_info = (*info->tree_map)[i];
    1156                 :           0 :               fprintf (symtab->dump_file, "%s %i -> ",
    1157                 :             :                        i ? "," : "", replace_info->parm_num);
    1158                 :           0 :               print_generic_expr (symtab->dump_file,
    1159                 :             :                                   replace_info->new_tree);
    1160                 :             :             }
    1161                 :           0 :           fprintf (symtab->dump_file, "\n");
    1162                 :             :         }
    1163                 :           0 :       if (info && info->param_adjustments)
    1164                 :           0 :         info->param_adjustments->dump (symtab->dump_file);
    1165                 :             :     }
    1166                 :      108419 :   clear_stmts_in_references ();
    1167                 :             :   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
    1168                 :      108419 :   tree_function_versioning (clone_of->decl, decl,
    1169                 :             :                             info ? info->tree_map : NULL,
    1170                 :             :                             info ? info->param_adjustments : NULL,
    1171                 :             :                             true, NULL, NULL);
    1172                 :      108419 :   if (symtab->dump_file)
    1173                 :             :     {
    1174                 :           0 :       dump_function_to_file (clone_of->decl, symtab->dump_file,
    1175                 :             :                              dump_flags);
    1176                 :           0 :       dump_function_to_file (decl, symtab->dump_file, dump_flags);
    1177                 :             :     }
    1178                 :             : 
    1179                 :      108419 :   cgraph_node *this_clone_of = clone_of;
    1180                 :             :   /* Function is no longer clone.  */
    1181                 :      108419 :   remove_from_clone_tree ();
    1182                 :      108419 :   if (!this_clone_of->analyzed && !this_clone_of->clones)
    1183                 :      105654 :     this_clone_of->release_body ();
    1184                 :      108419 : }
    1185                 :             : 
    1186                 :             : #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.