LCOV - code coverage report
Current view: top level - gcc - cgraph.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 81.7 % 2173 1775
Test Date: 2025-07-12 13:27:34 Functions: 93.0 % 128 119
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Callgraph handling code.
       2                 :             :    Copyright (C) 2003-2025 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 file contains basic routines manipulating call graph
      22                 :             : 
      23                 :             :     The call-graph is a data structure designed for inter-procedural
      24                 :             :     optimization.  It represents a multi-graph where nodes are functions
      25                 :             :     (symbols within symbol table) and edges are call sites. */
      26                 :             : 
      27                 :             : #include "config.h"
      28                 :             : #include "system.h"
      29                 :             : #include "coretypes.h"
      30                 :             : #include "backend.h"
      31                 :             : #include "target.h"
      32                 :             : #include "rtl.h"
      33                 :             : #include "tree.h"
      34                 :             : #include "gimple.h"
      35                 :             : #include "predict.h"
      36                 :             : #include "alloc-pool.h"
      37                 :             : #include "gimple-ssa.h"
      38                 :             : #include "cgraph.h"
      39                 :             : #include "lto-streamer.h"
      40                 :             : #include "fold-const.h"
      41                 :             : #include "varasm.h"
      42                 :             : #include "calls.h"
      43                 :             : #include "print-tree.h"
      44                 :             : #include "langhooks.h"
      45                 :             : #include "intl.h"
      46                 :             : #include "tree-eh.h"
      47                 :             : #include "gimple-iterator.h"
      48                 :             : #include "tree-cfg.h"
      49                 :             : #include "tree-ssa.h"
      50                 :             : #include "value-prof.h"
      51                 :             : #include "ipa-utils.h"
      52                 :             : #include "symbol-summary.h"
      53                 :             : #include "tree-vrp.h"
      54                 :             : #include "sreal.h"
      55                 :             : #include "ipa-cp.h"
      56                 :             : #include "ipa-prop.h"
      57                 :             : #include "ipa-fnsummary.h"
      58                 :             : #include "cfgloop.h"
      59                 :             : #include "gimple-pretty-print.h"
      60                 :             : #include "tree-dfa.h"
      61                 :             : #include "profile.h"
      62                 :             : #include "context.h"
      63                 :             : #include "gimplify.h"
      64                 :             : #include "stringpool.h"
      65                 :             : #include "attribs.h"
      66                 :             : #include "selftest.h"
      67                 :             : #include "tree-into-ssa.h"
      68                 :             : #include "ipa-inline.h"
      69                 :             : #include "tree-nested.h"
      70                 :             : #include "symtab-thunks.h"
      71                 :             : #include "symtab-clones.h"
      72                 :             : 
      73                 :             : /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this.  */
      74                 :             : #include "tree-pass.h"
      75                 :             : 
      76                 :             : /* Queue of cgraph nodes scheduled to be lowered.  */
      77                 :             : symtab_node *x_cgraph_nodes_queue;
      78                 :             : #define cgraph_nodes_queue ((cgraph_node *)x_cgraph_nodes_queue)
      79                 :             : 
      80                 :             : /* Symbol table global context.  */
      81                 :             : symbol_table *symtab;
      82                 :             : 
      83                 :             : /* List of hooks triggered on cgraph_edge events.  */
      84                 :             : struct cgraph_edge_hook_list {
      85                 :             :   cgraph_edge_hook hook;
      86                 :             :   void *data;
      87                 :             :   struct cgraph_edge_hook_list *next;
      88                 :             : };
      89                 :             : 
      90                 :             : /* List of hooks triggered on cgraph_node events.  */
      91                 :             : struct cgraph_node_hook_list {
      92                 :             :   cgraph_node_hook hook;
      93                 :             :   void *data;
      94                 :             :   struct cgraph_node_hook_list *next;
      95                 :             : };
      96                 :             : 
      97                 :             : /* List of hooks triggered on events involving two cgraph_edges.  */
      98                 :             : struct cgraph_2edge_hook_list {
      99                 :             :   cgraph_2edge_hook hook;
     100                 :             :   void *data;
     101                 :             :   struct cgraph_2edge_hook_list *next;
     102                 :             : };
     103                 :             : 
     104                 :             : /* List of hooks triggered on events involving two cgraph_nodes.  */
     105                 :             : struct cgraph_2node_hook_list {
     106                 :             :   cgraph_2node_hook hook;
     107                 :             :   void *data;
     108                 :             :   struct cgraph_2node_hook_list *next;
     109                 :             : };
     110                 :             : 
     111                 :             : /* Hash descriptor for cgraph_function_version_info.  */
     112                 :             : 
     113                 :             : struct function_version_hasher : ggc_ptr_hash<cgraph_function_version_info>
     114                 :             : {
     115                 :             :   static hashval_t hash (cgraph_function_version_info *);
     116                 :             :   static bool equal (cgraph_function_version_info *,
     117                 :             :                      cgraph_function_version_info *);
     118                 :             : };
     119                 :             : 
     120                 :             : /* Map a cgraph_node to cgraph_function_version_info using this htab.
     121                 :             :    The cgraph_function_version_info has a THIS_NODE field that is the
     122                 :             :    corresponding cgraph_node..  */
     123                 :             : 
     124                 :             : static GTY(()) hash_table<function_version_hasher> *cgraph_fnver_htab = NULL;
     125                 :             : 
     126                 :             : /* Hash function for cgraph_fnver_htab.  */
     127                 :             : hashval_t
     128                 :       97469 : function_version_hasher::hash (cgraph_function_version_info *ptr)
     129                 :             : {
     130                 :       97469 :   int uid = ptr->this_node->get_uid ();
     131                 :       97469 :   return (hashval_t)(uid);
     132                 :             : }
     133                 :             : 
     134                 :             : /* eq function for cgraph_fnver_htab.  */
     135                 :             : bool
     136                 :       80010 : function_version_hasher::equal (cgraph_function_version_info *n1,
     137                 :             :                                 cgraph_function_version_info *n2)
     138                 :             : {
     139                 :       80010 :   return n1->this_node->get_uid () == n2->this_node->get_uid ();
     140                 :             : }
     141                 :             : 
     142                 :             : /* Mark as GC root all allocated nodes.  */
     143                 :             : static GTY(()) struct cgraph_function_version_info *
     144                 :             :   version_info_node = NULL;
     145                 :             : 
     146                 :             : /* Return true if NODE's address can be compared.  */
     147                 :             : 
     148                 :             : bool
     149                 :     5001668 : symtab_node::address_can_be_compared_p ()
     150                 :             : {
     151                 :             :   /* Address of virtual tables and functions is never compared.  */
     152                 :     5001668 :   if (DECL_VIRTUAL_P (decl))
     153                 :             :     return false;
     154                 :             :   /* Address of C++ cdtors is never compared.  */
     155                 :     4912298 :   if (is_a <cgraph_node *> (this)
     156                 :      534480 :       && (DECL_CXX_CONSTRUCTOR_P (decl)
     157                 :      530392 :           || DECL_CXX_DESTRUCTOR_P (decl)))
     158                 :             :     return false;
     159                 :             :   /* Constant pool symbols addresses are never compared.
     160                 :             :      flag_merge_constants permits us to assume the same on readonly vars.  */
     161                 :     4906815 :   if (is_a <varpool_node *> (this)
     162                 :     4377818 :       && (DECL_IN_CONSTANT_POOL (decl)
     163                 :     4377815 :           || ((flag_merge_constants >= 2 || DECL_MERGEABLE (decl))
     164                 :        2072 :               && TREE_READONLY (decl) && !TREE_THIS_VOLATILE (decl))))
     165                 :        2068 :     return false;
     166                 :             :   return true;
     167                 :             : }
     168                 :             : 
     169                 :             : /* Get the cgraph_function_version_info node corresponding to node.  */
     170                 :             : cgraph_function_version_info *
     171                 :    97225841 : cgraph_node::function_version (void)
     172                 :             : {
     173                 :    97225841 :   cgraph_function_version_info key;
     174                 :    97225841 :   key.this_node = this;
     175                 :             : 
     176                 :    97225841 :   if (cgraph_fnver_htab == NULL)
     177                 :             :     return NULL;
     178                 :             : 
     179                 :       22095 :   return cgraph_fnver_htab->find (&key);
     180                 :             : }
     181                 :             : 
     182                 :             : /* If profile is IPA, turn it into local one.  */
     183                 :             : void
     184                 :           0 : cgraph_node::make_profile_local ()
     185                 :             : {
     186                 :           0 :   if (!count.ipa ().initialized_p ())
     187                 :             :     return;
     188                 :           0 :   if (!(count == profile_count::zero ()))
     189                 :           0 :     count = count.guessed_local ();
     190                 :           0 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
     191                 :             :     {
     192                 :           0 :       if (!e->inline_failed)
     193                 :           0 :         e->callee->make_profile_local ();
     194                 :           0 :       if (!(e->count == profile_count::zero ()))
     195                 :           0 :         e->count = e->count.guessed_local ();
     196                 :             :     }
     197                 :           0 :   for (cgraph_edge *e = indirect_calls; e; e = e->next_callee)
     198                 :           0 :     if (!(e->count == profile_count::zero ()))
     199                 :           0 :       e->count = e->count.guessed_local ();
     200                 :             : }
     201                 :             : 
     202                 :             : /* Turn profile to global0.  Walk into inlined functions.
     203                 :             :    QUALITY must be GUESSED_GLOBAL0, GUESSED_GLOBAL0_ADJUSTED
     204                 :             :    or GUESSED_GLOBAL0_AFDO  */
     205                 :             : void
     206                 :           5 : cgraph_node::make_profile_global0 (profile_quality quality)
     207                 :             : {
     208                 :           5 :   if (count == profile_count::zero ())
     209                 :             :     ;
     210                 :           5 :   else if (quality == GUESSED_GLOBAL0)
     211                 :             :     {
     212                 :           5 :       if (count.quality () == GUESSED_GLOBAL0)
     213                 :             :         return;
     214                 :           5 :       count = count.global0 ();
     215                 :             :     }
     216                 :           0 :   else if (quality == GUESSED_GLOBAL0_ADJUSTED)
     217                 :             :     {
     218                 :           0 :       if (count.quality () == GUESSED_GLOBAL0
     219                 :           0 :           || count.quality () == GUESSED_GLOBAL0_ADJUSTED)
     220                 :             :         return;
     221                 :           0 :       count = count.global0adjusted ();
     222                 :             :     }
     223                 :           0 :   else if (quality == GUESSED_GLOBAL0_AFDO)
     224                 :             :     {
     225                 :           0 :       if (count.quality () == GUESSED_GLOBAL0
     226                 :           0 :           || count.quality () == GUESSED_GLOBAL0_ADJUSTED
     227                 :           0 :           || count.quality () == GUESSED_GLOBAL0_AFDO)
     228                 :             :         return;
     229                 :           0 :       count = count.global0afdo ();
     230                 :             :     }
     231                 :             :   else
     232                 :           0 :     gcc_unreachable ();
     233                 :           6 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
     234                 :             :     {
     235                 :           1 :       if (!e->inline_failed)
     236                 :           0 :         e->callee->make_profile_global0 (quality);
     237                 :           1 :       if (e->count == profile_count::zero ())
     238                 :             :         ;
     239                 :           1 :       else if (quality == GUESSED_GLOBAL0)
     240                 :           1 :         e->count = e->count.global0 ();
     241                 :           0 :       else if (quality == GUESSED_GLOBAL0_ADJUSTED)
     242                 :           0 :         e->count = e->count.global0adjusted ();
     243                 :           0 :       else if (quality == GUESSED_GLOBAL0_AFDO)
     244                 :           0 :         e->count = e->count.global0afdo ();
     245                 :             :       else
     246                 :           0 :         gcc_unreachable ();
     247                 :             :     }
     248                 :           5 :   for (cgraph_edge *e = indirect_calls; e; e = e->next_callee)
     249                 :           0 :     if (e->count == profile_count::zero ())
     250                 :             :       ;
     251                 :           0 :     else if (quality == GUESSED_GLOBAL0)
     252                 :           0 :       e->count = e->count.global0 ();
     253                 :           0 :     else if (quality == GUESSED_GLOBAL0_ADJUSTED)
     254                 :           0 :       e->count = e->count.global0adjusted ();
     255                 :           0 :     else if (quality == GUESSED_GLOBAL0_AFDO)
     256                 :           0 :       e->count = e->count.global0afdo ();
     257                 :             :     else
     258                 :           0 :       gcc_unreachable ();
     259                 :             : }
     260                 :             : 
     261                 :             : /* Scale profile by NUM/DEN.  Walk into inlined functions.  */
     262                 :             : 
     263                 :             : void
     264                 :     1597493 : cgraph_node::apply_scale (profile_count num, profile_count den)
     265                 :             : {
     266                 :     1721330 :   if (num == den && !(num == profile_count::zero ()))
     267                 :      121864 :     return;
     268                 :             : 
     269                 :     2613257 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
     270                 :             :     {
     271                 :     1137628 :       if (!e->inline_failed)
     272                 :      139703 :         e->callee->apply_scale (num, den);
     273                 :     1137628 :       e->count = e->count.apply_scale (num, den);
     274                 :             :     }
     275                 :     1504939 :   for (cgraph_edge *e = indirect_calls; e; e = e->next_callee)
     276                 :       29310 :     e->count = e->count.apply_scale (num, den);
     277                 :     1475629 :   count = count.apply_scale (num, den);
     278                 :             : }
     279                 :             : 
     280                 :             : /* Scale profile to given IPA_COUNT.
     281                 :             :    IPA_COUNT should pass ipa_p () with a single exception.
     282                 :             :    It can be also GUESSED_LOCAL in case we want to
     283                 :             :    drop any IPA info about the profile.  */
     284                 :             : 
     285                 :             : void
     286                 :          30 : cgraph_node::scale_profile_to (profile_count ipa_count)
     287                 :             : {
     288                 :             :   /* If we do not know the adjustment, it is better to keep profile
     289                 :             :      as it is.  */
     290                 :          30 :   if (!ipa_count.initialized_p ()
     291                 :          30 :       || ipa_count == count)
     292                 :          10 :     return;
     293                 :             :   /* ipa-cp converts value to guessed-local in case it believes
     294                 :             :      that we lost track of IPA profile.  */
     295                 :          25 :   if (ipa_count.quality () == GUESSED_LOCAL)
     296                 :             :     {
     297                 :           0 :       make_profile_local ();
     298                 :           0 :       return;
     299                 :             :     }
     300                 :          25 :   if (ipa_count == profile_count::zero ())
     301                 :             :     {
     302                 :           5 :       make_profile_global0 (GUESSED_GLOBAL0);
     303                 :           5 :       return;
     304                 :             :     }
     305                 :          20 :   if (ipa_count == profile_count::adjusted_zero ())
     306                 :             :     {
     307                 :           0 :       make_profile_global0 (GUESSED_GLOBAL0_ADJUSTED);
     308                 :           0 :       return;
     309                 :             :     }
     310                 :          40 :   gcc_assert (ipa_count.ipa () == ipa_count
     311                 :             :               && !inlined_to);
     312                 :          20 :   profile_count num = count.combine_with_ipa_count (ipa_count);
     313                 :          20 :   profile_count den = count;
     314                 :          20 :   profile_count::adjust_for_ipa_scaling (&num, &den);
     315                 :             : }
     316                 :             : 
     317                 :             : /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
     318                 :             :    corresponding to cgraph_node NODE.  */
     319                 :             : cgraph_function_version_info *
     320                 :        1505 : cgraph_node::insert_new_function_version (void)
     321                 :             : {
     322                 :        1505 :   version_info_node = NULL;
     323                 :        1505 :   version_info_node = ggc_cleared_alloc<cgraph_function_version_info> ();
     324                 :        1505 :   version_info_node->this_node = this;
     325                 :             : 
     326                 :        1505 :   if (cgraph_fnver_htab == NULL)
     327                 :         197 :     cgraph_fnver_htab = hash_table<function_version_hasher>::create_ggc (2);
     328                 :             : 
     329                 :        1505 :   *cgraph_fnver_htab->find_slot (version_info_node, INSERT)
     330                 :        1505 :     = version_info_node;
     331                 :        1505 :   return version_info_node;
     332                 :             : }
     333                 :             : 
     334                 :             : /* Remove the cgraph_function_version_info node given by DECL_V.  */
     335                 :             : static void
     336                 :    93663152 : delete_function_version (cgraph_function_version_info *decl_v)
     337                 :             : {
     338                 :    93663152 :   if (decl_v == NULL)
     339                 :             :     return;
     340                 :             : 
     341                 :         265 :   if (version_info_node == decl_v)
     342                 :         205 :     version_info_node = NULL;
     343                 :             : 
     344                 :         265 :   if (decl_v->prev != NULL)
     345                 :         171 :     decl_v->prev->next = decl_v->next;
     346                 :             : 
     347                 :         265 :   if (decl_v->next != NULL)
     348                 :         226 :     decl_v->next->prev = decl_v->prev;
     349                 :             : 
     350                 :         265 :   if (cgraph_fnver_htab != NULL)
     351                 :         265 :     cgraph_fnver_htab->remove_elt (decl_v);
     352                 :             : }
     353                 :             : 
     354                 :             : /* Remove the cgraph_function_version_info and cgraph_node for DECL.  This
     355                 :             :    DECL is a duplicate declaration.  */
     356                 :             : void
     357                 :         258 : cgraph_node::delete_function_version_by_decl (tree decl)
     358                 :             : {
     359                 :         258 :   cgraph_node *decl_node = cgraph_node::get (decl);
     360                 :             : 
     361                 :         258 :   if (decl_node == NULL)
     362                 :             :     return;
     363                 :             : 
     364                 :         204 :   delete_function_version (decl_node->function_version ());
     365                 :             : 
     366                 :         204 :   decl_node->remove ();
     367                 :             : }
     368                 :             : 
     369                 :             : /* Add decl to the structure of semantically identical function versions.
     370                 :             :    The node is inserted at the point maintaining the priority ordering on the
     371                 :             :    versions.  */
     372                 :             : void
     373                 :         897 : cgraph_node::add_function_version (cgraph_function_version_info *fn_v,
     374                 :             :                                    tree decl)
     375                 :             : {
     376                 :         897 :   cgraph_node *decl_node = cgraph_node::get_create (decl);
     377                 :         897 :   cgraph_function_version_info *decl_v = NULL;
     378                 :             : 
     379                 :         897 :   gcc_assert (decl_node != NULL);
     380                 :             : 
     381                 :         897 :   decl_v = decl_node->function_version ();
     382                 :             : 
     383                 :             :   /* If the nodes are already linked, skip.  */
     384                 :         897 :   if (decl_v != NULL && (decl_v->next || decl_v->prev))
     385                 :             :     return;
     386                 :             : 
     387                 :         897 :   if (decl_v == NULL)
     388                 :         897 :     decl_v = decl_node->insert_new_function_version ();
     389                 :             : 
     390                 :         897 :   gcc_assert (decl_v);
     391                 :         897 :   gcc_assert (fn_v);
     392                 :             : 
     393                 :             :   /* Go to start of the FMV structure.  */
     394                 :        5220 :   while (fn_v->prev)
     395                 :             :     fn_v = fn_v->prev;
     396                 :             : 
     397                 :         897 :   cgraph_function_version_info *insert_point_before = NULL;
     398                 :         897 :   cgraph_function_version_info *insert_point_after = fn_v;
     399                 :             : 
     400                 :             :   /* Find the insertion point for the new version to maintain ordering.
     401                 :             :      The default node must always go at the beginning.  */
     402                 :         897 :   if (!is_function_default_version (decl))
     403                 :             :     while (insert_point_after
     404                 :        9123 :            && (targetm.compare_version_priority
     405                 :        4428 :                  (decl, insert_point_after->this_node->decl) > 0
     406                 :         633 :                || is_function_default_version
     407                 :         633 :                     (insert_point_after->this_node->decl)
     408                 :         531 :                || lookup_attribute
     409                 :         531 :                     ("target_clones",
     410                 :         531 :                      DECL_ATTRIBUTES (insert_point_after->this_node->decl))))
     411                 :             :       {
     412                 :        3897 :         insert_point_before = insert_point_after;
     413                 :        3897 :         insert_point_after = insert_point_after->next;
     414                 :             :       }
     415                 :             : 
     416                 :         897 :   decl_v->prev = insert_point_before;
     417                 :         897 :   decl_v->next= insert_point_after;
     418                 :             : 
     419                 :         897 :   if (insert_point_before)
     420                 :         762 :     insert_point_before->next = decl_v;
     421                 :         897 :   if (insert_point_after)
     422                 :         630 :     insert_point_after->prev = decl_v;
     423                 :             : }
     424                 :             : 
     425                 :             : /* Initialize callgraph dump file.  */
     426                 :             : 
     427                 :             : void
     428                 :      299985 : symbol_table::initialize (void)
     429                 :             : {
     430                 :      299985 :   if (!dump_file)
     431                 :      299983 :     dump_file = dump_begin (TDI_cgraph, NULL);
     432                 :             : 
     433                 :      299985 :   if (!ipa_clones_dump_file)
     434                 :      299985 :     ipa_clones_dump_file = dump_begin (TDI_clones, NULL);
     435                 :      299985 : }
     436                 :             : 
     437                 :             : /* Allocate new callgraph node and insert it into basic data structures.  */
     438                 :             : 
     439                 :             : cgraph_node *
     440                 :    97345276 : symbol_table::create_empty (void)
     441                 :             : {
     442                 :    97345276 :   cgraph_count++;
     443                 :    97345276 :   return new (ggc_alloc<cgraph_node> ()) cgraph_node ();
     444                 :             : }
     445                 :             : 
     446                 :             : /* Register HOOK to be called with DATA on each removed edge.  */
     447                 :             : cgraph_edge_hook_list *
     448                 :     1873670 : symbol_table::add_edge_removal_hook (cgraph_edge_hook hook, void *data)
     449                 :             : {
     450                 :     1873670 :   cgraph_edge_hook_list *entry;
     451                 :     3747340 :   cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
     452                 :             : 
     453                 :     1873670 :   entry = (cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
     454                 :     1873670 :   entry->hook = hook;
     455                 :     1873670 :   entry->data = data;
     456                 :     1873670 :   entry->next = NULL;
     457                 :     6480739 :   while (*ptr)
     458                 :     4607069 :     ptr = &(*ptr)->next;
     459                 :     1873670 :   *ptr = entry;
     460                 :     1873670 :   return entry;
     461                 :             : }
     462                 :             : 
     463                 :             : /* Remove ENTRY from the list of hooks called on removing edges.  */
     464                 :             : void
     465                 :     1873656 : symbol_table::remove_edge_removal_hook (cgraph_edge_hook_list *entry)
     466                 :             : {
     467                 :     1873656 :   cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
     468                 :             : 
     469                 :     5107915 :   while (*ptr != entry)
     470                 :     3234259 :     ptr = &(*ptr)->next;
     471                 :     1873656 :   *ptr = entry->next;
     472                 :     1873656 :   free (entry);
     473                 :     1873656 : }
     474                 :             : 
     475                 :             : /* Call all edge removal hooks.  */
     476                 :             : void
     477                 :    43804167 : symbol_table::call_edge_removal_hooks (cgraph_edge *e)
     478                 :             : {
     479                 :    43804167 :   cgraph_edge_hook_list *entry = m_first_edge_removal_hook;
     480                 :    71012598 :   while (entry)
     481                 :             :   {
     482                 :    27208431 :     entry->hook (e, entry->data);
     483                 :    27208431 :     entry = entry->next;
     484                 :             :   }
     485                 :    43804167 : }
     486                 :             : 
     487                 :             : /* Register HOOK to be called with DATA on each removed node.  */
     488                 :             : cgraph_node_hook_list *
     489                 :     7976896 : symbol_table::add_cgraph_removal_hook (cgraph_node_hook hook, void *data)
     490                 :             : {
     491                 :     7976896 :   cgraph_node_hook_list *entry;
     492                 :    15953792 :   cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
     493                 :             : 
     494                 :     7976896 :   entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
     495                 :     7976896 :   entry->hook = hook;
     496                 :     7976896 :   entry->data = data;
     497                 :     7976896 :   entry->next = NULL;
     498                 :    41750423 :   while (*ptr)
     499                 :    33773527 :     ptr = &(*ptr)->next;
     500                 :     7976896 :   *ptr = entry;
     501                 :     7976896 :   return entry;
     502                 :             : }
     503                 :             : 
     504                 :             : /* Remove ENTRY from the list of hooks called on removing nodes.  */
     505                 :             : void
     506                 :     7870738 : symbol_table::remove_cgraph_removal_hook (cgraph_node_hook_list *entry)
     507                 :             : {
     508                 :     7870738 :   cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
     509                 :             : 
     510                 :    37287484 :   while (*ptr != entry)
     511                 :    29416746 :     ptr = &(*ptr)->next;
     512                 :     7870738 :   *ptr = entry->next;
     513                 :     7870738 :   free (entry);
     514                 :     7870738 : }
     515                 :             : 
     516                 :             : /* Call all node removal hooks.  */
     517                 :             : void
     518                 :    93694914 : symbol_table::call_cgraph_removal_hooks (cgraph_node *node)
     519                 :             : {
     520                 :    93694914 :   cgraph_node_hook_list *entry = m_first_cgraph_removal_hook;
     521                 :   133219803 :   while (entry)
     522                 :             :   {
     523                 :    39524889 :     entry->hook (node, entry->data);
     524                 :    39524889 :     entry = entry->next;
     525                 :             :   }
     526                 :    93694914 : }
     527                 :             : 
     528                 :             : /* Call all node removal hooks.  */
     529                 :             : void
     530                 :      117369 : symbol_table::call_cgraph_insertion_hooks (cgraph_node *node)
     531                 :             : {
     532                 :      117369 :   cgraph_node_hook_list *entry = m_first_cgraph_insertion_hook;
     533                 :      350756 :   while (entry)
     534                 :             :   {
     535                 :      233387 :     entry->hook (node, entry->data);
     536                 :      233387 :     entry = entry->next;
     537                 :             :   }
     538                 :      117369 : }
     539                 :             : 
     540                 :             : 
     541                 :             : /* Register HOOK to be called with DATA on each inserted node.  */
     542                 :             : cgraph_node_hook_list *
     543                 :     8455336 : symbol_table::add_cgraph_insertion_hook (cgraph_node_hook hook, void *data)
     544                 :             : {
     545                 :     8455336 :   cgraph_node_hook_list *entry;
     546                 :    16910672 :   cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
     547                 :             : 
     548                 :     8455336 :   entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
     549                 :     8455336 :   entry->hook = hook;
     550                 :     8455336 :   entry->data = data;
     551                 :     8455336 :   entry->next = NULL;
     552                 :    25043438 :   while (*ptr)
     553                 :    16588102 :     ptr = &(*ptr)->next;
     554                 :     8455336 :   *ptr = entry;
     555                 :     8455336 :   return entry;
     556                 :             : }
     557                 :             : 
     558                 :             : /* Remove ENTRY from the list of hooks called on inserted nodes.  */
     559                 :             : void
     560                 :     8310516 : symbol_table::remove_cgraph_insertion_hook (cgraph_node_hook_list *entry)
     561                 :             : {
     562                 :     8310516 :   cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
     563                 :             : 
     564                 :    22953700 :   while (*ptr != entry)
     565                 :    14643184 :     ptr = &(*ptr)->next;
     566                 :     8310516 :   *ptr = entry->next;
     567                 :     8310516 :   free (entry);
     568                 :     8310516 : }
     569                 :             : 
     570                 :             : /* Register HOOK to be called with DATA on each duplicated edge.  */
     571                 :             : cgraph_2edge_hook_list *
     572                 :     1645682 : symbol_table::add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
     573                 :             : {
     574                 :     1645682 :   cgraph_2edge_hook_list *entry;
     575                 :     3291364 :   cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
     576                 :             : 
     577                 :     1645682 :   entry = (cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
     578                 :     1645682 :   entry->hook = hook;
     579                 :     1645682 :   entry->data = data;
     580                 :     1645682 :   entry->next = NULL;
     581                 :     5282183 :   while (*ptr)
     582                 :     3636501 :     ptr = &(*ptr)->next;
     583                 :     1645682 :   *ptr = entry;
     584                 :     1645682 :   return entry;
     585                 :             : }
     586                 :             : 
     587                 :             : /* Remove ENTRY from the list of hooks called on duplicating edges.  */
     588                 :             : void
     589                 :     1645668 : symbol_table::remove_edge_duplication_hook (cgraph_2edge_hook_list *entry)
     590                 :             : {
     591                 :     1645668 :   cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
     592                 :             : 
     593                 :     3909359 :   while (*ptr != entry)
     594                 :     2263691 :     ptr = &(*ptr)->next;
     595                 :     1645668 :   *ptr = entry->next;
     596                 :     1645668 :   free (entry);
     597                 :     1645668 : }
     598                 :             : 
     599                 :             : /* Call all edge duplication hooks.  */
     600                 :             : void
     601                 :     6661254 : symbol_table::call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2)
     602                 :             : {
     603                 :     6661254 :   cgraph_2edge_hook_list *entry = m_first_edge_duplicated_hook;
     604                 :    19601254 :   while (entry)
     605                 :             :   {
     606                 :    12940000 :     entry->hook (cs1, cs2, entry->data);
     607                 :    12940000 :     entry = entry->next;
     608                 :             :   }
     609                 :     6661254 : }
     610                 :             : 
     611                 :             : /* Register HOOK to be called with DATA on each duplicated node.  */
     612                 :             : cgraph_2node_hook_list *
     613                 :     7837505 : symbol_table::add_cgraph_duplication_hook (cgraph_2node_hook hook, void *data)
     614                 :             : {
     615                 :     7837505 :   cgraph_2node_hook_list *entry;
     616                 :    15675010 :   cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
     617                 :             : 
     618                 :     7837505 :   entry = (cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
     619                 :     7837505 :   entry->hook = hook;
     620                 :     7837505 :   entry->data = data;
     621                 :     7837505 :   entry->next = NULL;
     622                 :    38786141 :   while (*ptr)
     623                 :    30948636 :     ptr = &(*ptr)->next;
     624                 :     7837505 :   *ptr = entry;
     625                 :     7837505 :   return entry;
     626                 :             : }
     627                 :             : 
     628                 :             : /* Remove ENTRY from the list of hooks called on duplicating nodes.  */
     629                 :             : void
     630                 :     7744159 : symbol_table::remove_cgraph_duplication_hook (cgraph_2node_hook_list *entry)
     631                 :             : {
     632                 :     7744159 :   cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
     633                 :             : 
     634                 :    35267944 :   while (*ptr != entry)
     635                 :    27523785 :     ptr = &(*ptr)->next;
     636                 :     7744159 :   *ptr = entry->next;
     637                 :     7744159 :   free (entry);
     638                 :     7744159 : }
     639                 :             : 
     640                 :             : /* Call all node duplication hooks.  */
     641                 :             : void
     642                 :     3072043 : symbol_table::call_cgraph_duplication_hooks (cgraph_node *node,
     643                 :             :                                              cgraph_node *node2)
     644                 :             : {
     645                 :     3072043 :   cgraph_2node_hook_list *entry = m_first_cgraph_duplicated_hook;
     646                 :    21712899 :   while (entry)
     647                 :             :   {
     648                 :    18640856 :     entry->hook (node, node2, entry->data);
     649                 :    18640856 :     entry = entry->next;
     650                 :             :   }
     651                 :     3072043 : }
     652                 :             : 
     653                 :             : /* Return cgraph node assigned to DECL.  Create new one when needed.  */
     654                 :             : 
     655                 :             : cgraph_node *
     656                 :    94075262 : cgraph_node::create (tree decl)
     657                 :             : {
     658                 :    94075262 :   cgraph_node *node = symtab->create_empty ();
     659                 :    94075262 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
     660                 :             : 
     661                 :    94075262 :   node->decl = decl;
     662                 :    94075262 :   node->semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
     663                 :             : 
     664                 :    94019896 :   if ((flag_openacc || flag_openmp)
     665                 :    94310393 :       && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
     666                 :             :     {
     667                 :        8376 :       node->offloadable = 1;
     668                 :        8376 :       if (ENABLE_OFFLOADING)
     669                 :             :         g->have_offload = true;
     670                 :             :     }
     671                 :             : 
     672                 :    94075262 :   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     673                 :         120 :     node->ifunc_resolver = true;
     674                 :             : 
     675                 :    94075262 :   node->register_symbol ();
     676                 :    94075262 :   maybe_record_nested_function (node);
     677                 :             : 
     678                 :    94075262 :   return node;
     679                 :             : }
     680                 :             : 
     681                 :             : /* Try to find a call graph node for declaration DECL and if it does not exist
     682                 :             :    or if it corresponds to an inline clone, create a new one.  */
     683                 :             : 
     684                 :             : cgraph_node *
     685                 :   514669329 : cgraph_node::get_create (tree decl)
     686                 :             : {
     687                 :   514669329 :   cgraph_node *first_clone = cgraph_node::get (decl);
     688                 :             : 
     689                 :   514669329 :   if (first_clone && !first_clone->inlined_to)
     690                 :             :     return first_clone;
     691                 :             : 
     692                 :    94010040 :   cgraph_node *node = cgraph_node::create (decl);
     693                 :    94010040 :   if (first_clone)
     694                 :             :     {
     695                 :           7 :       first_clone->clone_of = node;
     696                 :           7 :       node->clones = first_clone;
     697                 :           7 :       node->order = first_clone->order;
     698                 :           7 :       symtab->symtab_prevail_in_asm_name_hash (node);
     699                 :           7 :       node->decl->decl_with_vis.symtab_node = node;
     700                 :           7 :       if (dump_file && symtab->state != PARSING)
     701                 :           2 :         fprintf (dump_file, "Introduced new external node "
     702                 :             :                  "(%s) and turned into root of the clone tree.\n",
     703                 :             :                  node->dump_name ());
     704                 :             :     }
     705                 :    94010033 :   else if (dump_file && symtab->state != PARSING)
     706                 :        1135 :     fprintf (dump_file, "Introduced new external node "
     707                 :             :              "(%s).\n", node->dump_name ());
     708                 :             :   return node;
     709                 :             : }
     710                 :             : 
     711                 :             : /* Mark ALIAS as an alias to DECL.  DECL_NODE is cgraph node representing
     712                 :             :    the function body is associated with
     713                 :             :    (not necessarily cgraph_node (DECL)).  */
     714                 :             : 
     715                 :             : cgraph_node *
     716                 :     6785131 : cgraph_node::create_alias (tree alias, tree target)
     717                 :             : {
     718                 :     6785131 :   cgraph_node *alias_node;
     719                 :             : 
     720                 :     6785131 :   gcc_assert (TREE_CODE (target) == FUNCTION_DECL
     721                 :             :               || TREE_CODE (target) == IDENTIFIER_NODE);
     722                 :     6785131 :   gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
     723                 :     6785131 :   alias_node = cgraph_node::get_create (alias);
     724                 :     6785131 :   gcc_assert (!alias_node->definition);
     725                 :     6785131 :   alias_node->alias_target = target;
     726                 :     6785131 :   alias_node->definition = true;
     727                 :     6785131 :   alias_node->alias = true;
     728                 :     6785131 :   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     729                 :          47 :     alias_node->transparent_alias = alias_node->weakref = true;
     730                 :     6785131 :   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
     731                 :         315 :     alias_node->ifunc_resolver = true;
     732                 :     6785131 :   return alias_node;
     733                 :             : }
     734                 :             : 
     735                 :             : /* Attempt to mark ALIAS as an alias to DECL.  Return alias node if successful
     736                 :             :    and NULL otherwise.
     737                 :             :    Same body aliases are output whenever the body of DECL is output,
     738                 :             :    and cgraph_node::get (ALIAS) transparently returns
     739                 :             :    cgraph_node::get (DECL).  */
     740                 :             : 
     741                 :             : cgraph_node *
     742                 :     6765910 : cgraph_node::create_same_body_alias (tree alias, tree decl)
     743                 :             : {
     744                 :     6765910 :   cgraph_node *n;
     745                 :             : 
     746                 :             :   /* If aliases aren't supported by the assembler, fail.  */
     747                 :     6765910 :   if (!TARGET_SUPPORTS_ALIASES)
     748                 :             :     return NULL;
     749                 :             : 
     750                 :             :   /* Langhooks can create same body aliases of symbols not defined.
     751                 :             :      Those are useless. Drop them on the floor.  */
     752                 :     6765910 :   if (symtab->global_info_ready)
     753                 :             :     return NULL;
     754                 :             : 
     755                 :     6765910 :   n = cgraph_node::create_alias (alias, decl);
     756                 :     6765910 :   n->cpp_implicit_alias = true;
     757                 :     6765910 :   if (symtab->cpp_implicit_aliases_done)
     758                 :     3553252 :     n->resolve_alias (cgraph_node::get (decl));
     759                 :             :   return n;
     760                 :             : }
     761                 :             : 
     762                 :             : /* Add thunk alias into callgraph.  The alias declaration is ALIAS and it
     763                 :             :    aliases DECL with an adjustments made into the first parameter.
     764                 :             :    See comments in struct cgraph_thunk_info for detail on the parameters.  */
     765                 :             : 
     766                 :             : cgraph_node *
     767                 :        4390 : cgraph_node::create_thunk (tree alias, tree, bool this_adjusting,
     768                 :             :                            HOST_WIDE_INT fixed_offset,
     769                 :             :                            HOST_WIDE_INT virtual_value,
     770                 :             :                            HOST_WIDE_INT indirect_offset,
     771                 :             :                            tree virtual_offset,
     772                 :             :                            tree real_alias)
     773                 :             : {
     774                 :        4390 :   cgraph_node *node;
     775                 :             : 
     776                 :        4390 :   node = cgraph_node::get (alias);
     777                 :        4390 :   if (node)
     778                 :        3656 :     node->reset ();
     779                 :             :   else
     780                 :         734 :     node = cgraph_node::create (alias);
     781                 :             : 
     782                 :             :   /* Make sure that if VIRTUAL_OFFSET is in sync with VIRTUAL_VALUE.  */
     783                 :        4390 :   gcc_checking_assert (virtual_offset
     784                 :             :                        ? virtual_value == wi::to_wide (virtual_offset)
     785                 :             :                        : virtual_value == 0);
     786                 :             : 
     787                 :        4390 :   node->thunk = true;
     788                 :        4390 :   node->definition = true;
     789                 :             : 
     790                 :        4390 :   thunk_info *i;
     791                 :        4390 :   thunk_info local_info;
     792                 :        4390 :   if (symtab->state < CONSTRUCTION)
     793                 :             :     i = &local_info;
     794                 :             :   else
     795                 :           0 :     i = thunk_info::get_create (node);
     796                 :        4390 :   i->fixed_offset = fixed_offset;
     797                 :        4390 :   i->virtual_value = virtual_value;
     798                 :        4390 :   i->indirect_offset = indirect_offset;
     799                 :        4390 :   i->alias = real_alias;
     800                 :        4390 :   i->this_adjusting = this_adjusting;
     801                 :        4390 :   i->virtual_offset_p = virtual_offset != NULL;
     802                 :        4390 :   if (symtab->state < CONSTRUCTION)
     803                 :        4390 :     i->register_early (node);
     804                 :             : 
     805                 :        4390 :   return node;
     806                 :             : }
     807                 :             : 
     808                 :             : /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
     809                 :             :    Return NULL if there's no such node.  */
     810                 :             : 
     811                 :             : cgraph_node *
     812                 :           0 : cgraph_node::get_for_asmname (tree asmname)
     813                 :             : {
     814                 :             :   /* We do not want to look at inline clones.  */
     815                 :           0 :   for (symtab_node *node = symtab_node::get_for_asmname (asmname);
     816                 :           0 :        node;
     817                 :           0 :        node = node->next_sharing_asm_name)
     818                 :             :     {
     819                 :           0 :       cgraph_node *cn = dyn_cast <cgraph_node *> (node);
     820                 :           0 :       if (cn && !cn->inlined_to)
     821                 :             :         return cn;
     822                 :             :     }
     823                 :             :   return NULL;
     824                 :             : }
     825                 :             : 
     826                 :             : /* Returns a hash value for X (which really is a cgraph_edge).  */
     827                 :             : 
     828                 :             : hashval_t
     829                 :   214618830 : cgraph_edge_hasher::hash (cgraph_edge *e)
     830                 :             : {
     831                 :             :   /* This is a really poor hash function, but it is what htab_hash_pointer
     832                 :             :      uses.  */
     833                 :   214618830 :   return (hashval_t) ((intptr_t)e->call_stmt >> 3);
     834                 :             : }
     835                 :             : 
     836                 :             : /* Returns a hash value for X (which really is a cgraph_edge).  */
     837                 :             : 
     838                 :             : hashval_t
     839                 :    42405924 : cgraph_edge_hasher::hash (gimple *call_stmt)
     840                 :             : {
     841                 :             :   /* This is a really poor hash function, but it is what htab_hash_pointer
     842                 :             :      uses.  */
     843                 :    42405924 :   return (hashval_t) ((intptr_t)call_stmt >> 3);
     844                 :             : }
     845                 :             : 
     846                 :             : /* Return nonzero if the call_stmt of cgraph_edge X is stmt *Y.  */
     847                 :             : 
     848                 :             : inline bool
     849                 :   261797166 : cgraph_edge_hasher::equal (cgraph_edge *x, gimple *y)
     850                 :             : {
     851                 :   261797166 :   return x->call_stmt == y;
     852                 :             : }
     853                 :             : 
     854                 :             : /* Add call graph edge E to call site hash of its caller.  */
     855                 :             : 
     856                 :             : static inline void
     857                 :        2704 : cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
     858                 :             : {
     859                 :        2704 :   gimple *call = e->call_stmt;
     860                 :        2704 :   *e->caller->call_site_hash->find_slot_with_hash
     861                 :        2704 :       (call, cgraph_edge_hasher::hash (call), INSERT) = e;
     862                 :        2704 : }
     863                 :             : 
     864                 :             : /* Add call graph edge E to call site hash of its caller.  */
     865                 :             : 
     866                 :             : static inline void
     867                 :     8022893 : cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
     868                 :             : {
     869                 :             :   /* There are two speculative edges for every statement (one direct,
     870                 :             :      one indirect); always hash the direct one.  */
     871                 :     8022893 :   if (e->speculative && e->indirect_unknown_callee)
     872                 :             :     return;
     873                 :     8022890 :   cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
     874                 :     8022890 :       (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt), INSERT);
     875                 :     8022890 :   if (*slot)
     876                 :             :     {
     877                 :        2701 :       gcc_assert (((cgraph_edge *)*slot)->speculative);
     878                 :        2701 :       if (e->callee && (!e->prev_callee
     879                 :           0 :                         || !e->prev_callee->speculative
     880                 :           0 :                         || e->prev_callee->call_stmt != e->call_stmt))
     881                 :           0 :         *slot = e;
     882                 :        2701 :       return;
     883                 :             :     }
     884                 :     8020189 :   gcc_assert (!*slot || e->speculative);
     885                 :     8020189 :   *slot = e;
     886                 :             : }
     887                 :             : 
     888                 :             : /* Return the callgraph edge representing the GIMPLE_CALL statement
     889                 :             :    CALL_STMT.  */
     890                 :             : 
     891                 :             : cgraph_edge *
     892                 :   203284763 : cgraph_node::get_edge (gimple *call_stmt)
     893                 :             : {
     894                 :   203284763 :   cgraph_edge *e, *e2;
     895                 :   203284763 :   int n = 0;
     896                 :             : 
     897                 :   203284763 :   if (call_site_hash)
     898                 :    33361500 :     return call_site_hash->find_with_hash
     899                 :    33361500 :         (call_stmt, cgraph_edge_hasher::hash (call_stmt));
     900                 :             : 
     901                 :             :   /* This loop may turn out to be performance problem.  In such case adding
     902                 :             :      hashtables into call nodes with very many edges is probably best
     903                 :             :      solution.  It is not good idea to add pointer into CALL_EXPR itself
     904                 :             :      because we want to make possible having multiple cgraph nodes representing
     905                 :             :      different clones of the same body before the body is actually cloned.  */
     906                 :  1651113525 :   for (e = callees; e; e = e->next_callee)
     907                 :             :     {
     908                 :  1605665544 :       if (e->call_stmt == call_stmt)
     909                 :             :         break;
     910                 :  1481190262 :       n++;
     911                 :             :     }
     912                 :             : 
     913                 :   169923263 :   if (!e)
     914                 :    58873663 :     for (e = indirect_calls; e; e = e->next_callee)
     915                 :             :       {
     916                 :    16350077 :         if (e->call_stmt == call_stmt)
     917                 :             :           break;
     918                 :    13425682 :         n++;
     919                 :             :       }
     920                 :             : 
     921                 :   169923263 :   if (n > 100)
     922                 :             :     {
     923                 :       29202 :       call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc (120);
     924                 :     3000374 :       for (e2 = callees; e2; e2 = e2->next_callee)
     925                 :     2971172 :         cgraph_add_edge_to_call_site_hash (e2);
     926                 :      111887 :       for (e2 = indirect_calls; e2; e2 = e2->next_callee)
     927                 :       82685 :         cgraph_add_edge_to_call_site_hash (e2);
     928                 :             :     }
     929                 :             : 
     930                 :             :   return e;
     931                 :             : }
     932                 :             : 
     933                 :             : 
     934                 :             : /* Change field call_stmt of edge E to NEW_STMT.  If UPDATE_SPECULATIVE and E
     935                 :             :    is any component of speculative edge, then update all components.
     936                 :             :    Speculations can be resolved in the process and EDGE can be removed and
     937                 :             :    deallocated.  Return the edge that now represents the call.  */
     938                 :             : 
     939                 :             : cgraph_edge *
     940                 :     2527868 : cgraph_edge::set_call_stmt (cgraph_edge *e, gcall *new_stmt,
     941                 :             :                             bool update_speculative)
     942                 :             : {
     943                 :     2527868 :   tree decl;
     944                 :             : 
     945                 :     2527868 :   cgraph_node *new_direct_callee = NULL;
     946                 :     2498981 :   if ((e->indirect_unknown_callee || e->speculative)
     947                 :     2560707 :       && (decl = gimple_call_fndecl (new_stmt)))
     948                 :             :     {
     949                 :             :       /* Constant propagation and especially inlining can turn an indirect call
     950                 :             :          into a direct one.  */
     951                 :           0 :       new_direct_callee = cgraph_node::get (decl);
     952                 :           0 :       gcc_checking_assert (new_direct_callee);
     953                 :             :     }
     954                 :             : 
     955                 :             :   /* Speculative edges has three component, update all of them
     956                 :             :      when asked to.  */
     957                 :     2527868 :   if (update_speculative && e->speculative
     958                 :             :       /* If we are about to resolve the speculation by calling make_direct
     959                 :             :          below, do not bother going over all the speculative edges now.  */
     960                 :        1976 :       && !new_direct_callee)
     961                 :             :     {
     962                 :        1976 :       cgraph_edge *direct, *indirect, *next;
     963                 :        1976 :       ipa_ref *ref;
     964                 :        1976 :       bool e_indirect = e->indirect_unknown_callee;
     965                 :        1976 :       int n = 0;
     966                 :             : 
     967                 :        1976 :       direct = e->first_speculative_call_target ();
     968                 :        1976 :       indirect = e->speculative_call_indirect_edge ();
     969                 :             : 
     970                 :        1976 :       gcall *old_stmt = direct->call_stmt;
     971                 :        3952 :       for (cgraph_edge *d = direct; d; d = next)
     972                 :             :         {
     973                 :        1976 :           next = d->next_speculative_call_target ();
     974                 :        1976 :           cgraph_edge *d2 = set_call_stmt (d, new_stmt, false);
     975                 :        1976 :           gcc_assert (d2 == d);
     976                 :        1976 :           n++;
     977                 :             :         }
     978                 :        1976 :       gcc_checking_assert (indirect->num_speculative_call_targets_p () == n);
     979                 :        5046 :       for (unsigned int i = 0; e->caller->iterate_reference (i, ref); i++)
     980                 :        3070 :         if (ref->speculative && ref->stmt == old_stmt)
     981                 :             :           {
     982                 :        1976 :             ref->stmt = new_stmt;
     983                 :        1976 :             n--;
     984                 :             :           }
     985                 :             : 
     986                 :        1976 :       indirect = set_call_stmt (indirect, new_stmt, false);
     987                 :        1976 :       return e_indirect ? indirect : direct;
     988                 :             :     }
     989                 :             : 
     990                 :     2525892 :   if (new_direct_callee)
     991                 :           0 :     e = make_direct (e, new_direct_callee);
     992                 :             : 
     993                 :             :   /* Only direct speculative edges go to call_site_hash.  */
     994                 :     2525892 :   if (e->caller->call_site_hash
     995                 :      456531 :       && (!e->speculative || !e->indirect_unknown_callee)
     996                 :             :       /* It is possible that edge was previously speculative.  In this case
     997                 :             :          we have different value in call stmt hash which needs preserving.  */
     998                 :     2982423 :       && e->caller->get_edge (e->call_stmt) == e)
     999                 :      453827 :     e->caller->call_site_hash->remove_elt_with_hash
    1000                 :      453827 :       (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt));
    1001                 :             : 
    1002                 :     2525892 :   e->call_stmt = new_stmt;
    1003                 :             : 
    1004                 :     2525892 :   function *fun = DECL_STRUCT_FUNCTION (e->caller->decl);
    1005                 :     2525892 :   e->can_throw_external = stmt_can_throw_external (fun, new_stmt);
    1006                 :             :   /* Update call stite hash.  For speculative calls we only record the first
    1007                 :             :      direct edge.  */
    1008                 :     2525892 :   if (e->caller->call_site_hash
    1009                 :      456531 :       && (!e->speculative
    1010                 :           0 :           || (e->callee
    1011                 :           0 :               && (!e->prev_callee || !e->prev_callee->speculative
    1012                 :           0 :                   || e->prev_callee->call_stmt != e->call_stmt))
    1013                 :           0 :           || (e->speculative && !e->callee)))
    1014                 :      456531 :     cgraph_add_edge_to_call_site_hash (e);
    1015                 :             :   return e;
    1016                 :             : }
    1017                 :             : 
    1018                 :             : /* Allocate a cgraph_edge structure and fill it with data according to the
    1019                 :             :    parameters of which only CALLEE can be NULL (when creating an indirect call
    1020                 :             :    edge).  CLONING_P should be set if properties that are copied from an
    1021                 :             :    original edge should not be calculated.  */
    1022                 :             : 
    1023                 :             : cgraph_edge *
    1024                 :    44239120 : symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
    1025                 :             :                            gcall *call_stmt, profile_count count,
    1026                 :             :                            bool indir_unknown_callee, bool cloning_p)
    1027                 :             : {
    1028                 :    44239120 :   cgraph_edge *edge;
    1029                 :             : 
    1030                 :             :   /* LTO does not actually have access to the call_stmt since these
    1031                 :             :      have not been loaded yet.  */
    1032                 :    44239120 :   if (call_stmt)
    1033                 :             :     {
    1034                 :             :       /* This is a rather expensive check possibly triggering
    1035                 :             :          construction of call stmt hashtable.  */
    1036                 :    43390996 :       cgraph_edge *e;
    1037                 :    43390996 :       gcc_checking_assert (!(e = caller->get_edge (call_stmt))
    1038                 :             :                            || e->speculative);
    1039                 :             : 
    1040                 :    43390996 :       gcc_assert (is_gimple_call (call_stmt));
    1041                 :             :     }
    1042                 :             : 
    1043                 :    44239120 :   edge = ggc_alloc<cgraph_edge> ();
    1044                 :    44239120 :   edge->m_summary_id = -1;
    1045                 :    44239120 :   edges_count++;
    1046                 :             : 
    1047                 :    44239120 :   ++edges_max_uid;
    1048                 :    44239120 :   gcc_assert (edges_max_uid != 0);
    1049                 :    44239120 :   edge->m_uid = edges_max_uid;
    1050                 :    44239120 :   edge->aux = NULL;
    1051                 :    44239120 :   edge->caller = caller;
    1052                 :    44239120 :   edge->callee = callee;
    1053                 :    44239120 :   edge->prev_caller = NULL;
    1054                 :    44239120 :   edge->next_caller = NULL;
    1055                 :    44239120 :   edge->prev_callee = NULL;
    1056                 :    44239120 :   edge->next_callee = NULL;
    1057                 :    44239120 :   edge->lto_stmt_uid = 0;
    1058                 :    44239120 :   edge->speculative_id = 0;
    1059                 :             : 
    1060                 :    44239120 :   edge->count = count;
    1061                 :    44239120 :   edge->call_stmt = call_stmt;
    1062                 :    44239120 :   edge->indirect_info = NULL;
    1063                 :    44239120 :   edge->indirect_inlining_edge = 0;
    1064                 :    44239120 :   edge->speculative = false;
    1065                 :    44239120 :   edge->indirect_unknown_callee = indir_unknown_callee;
    1066                 :    44239120 :   if (call_stmt && caller->call_site_hash)
    1067                 :     4512505 :     cgraph_add_edge_to_call_site_hash (edge);
    1068                 :             : 
    1069                 :    44239120 :   if (cloning_p)
    1070                 :             :     return edge;
    1071                 :             : 
    1072                 :    37582991 :   edge->can_throw_external
    1073                 :    37582991 :     = call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl),
    1074                 :             :                                            call_stmt) : false;
    1075                 :    37582991 :   edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
    1076                 :    37582991 :   edge->call_stmt_cannot_inline_p = false;
    1077                 :             : 
    1078                 :    37582991 :   if (opt_for_fn (edge->caller->decl, flag_devirtualize)
    1079                 :    37582991 :       && call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
    1080                 :    29637166 :     edge->in_polymorphic_cdtor
    1081                 :    29637166 :       = decl_maybe_in_construction_p (NULL, NULL, call_stmt,
    1082                 :             :                                       caller->decl);
    1083                 :             :   else
    1084                 :     7945825 :     edge->in_polymorphic_cdtor = caller->thunk;
    1085                 :             : 
    1086                 :    36913665 :   if (callee && symtab->state != LTO_STREAMING
    1087                 :    73904477 :       && edge->callee->comdat_local_p ())
    1088                 :        7536 :     edge->caller->calls_comdat_local = true;
    1089                 :             : 
    1090                 :             :   return edge;
    1091                 :             : }
    1092                 :             : 
    1093                 :             : /* Create edge from a given function to CALLEE in the cgraph.  CLONING_P should
    1094                 :             :    be set if properties that are copied from an original edge should not be
    1095                 :             :    calculated.  */
    1096                 :             : 
    1097                 :             : cgraph_edge *
    1098                 :    43393913 : cgraph_node::create_edge (cgraph_node *callee,
    1099                 :             :                           gcall *call_stmt, profile_count count, bool cloning_p)
    1100                 :             : {
    1101                 :    43393913 :   cgraph_edge *edge = symtab->create_edge (this, callee, call_stmt, count,
    1102                 :             :                                            false, cloning_p);
    1103                 :             : 
    1104                 :    43393913 :   if (!cloning_p)
    1105                 :    36913665 :     initialize_inline_failed (edge);
    1106                 :             : 
    1107                 :    43393913 :   edge->next_caller = callee->callers;
    1108                 :    43393913 :   if (callee->callers)
    1109                 :    33716363 :     callee->callers->prev_caller = edge;
    1110                 :    43393913 :   edge->next_callee = callees;
    1111                 :    43393913 :   if (callees)
    1112                 :    33587135 :     callees->prev_callee = edge;
    1113                 :    43393913 :   callees = edge;
    1114                 :    43393913 :   callee->callers = edge;
    1115                 :             : 
    1116                 :    43393913 :   return edge;
    1117                 :             : }
    1118                 :             : 
    1119                 :             : /* Allocate cgraph_indirect_call_info and set its fields to default values. */
    1120                 :             : 
    1121                 :             : cgraph_indirect_call_info *
    1122                 :      845207 : cgraph_allocate_init_indirect_info (void)
    1123                 :             : {
    1124                 :      845207 :   cgraph_indirect_call_info *ii;
    1125                 :             : 
    1126                 :      845207 :   ii = ggc_cleared_alloc<cgraph_indirect_call_info> ();
    1127                 :      845207 :   ii->param_index = -1;
    1128                 :      845207 :   return ii;
    1129                 :             : }
    1130                 :             : 
    1131                 :             : /* Create an indirect edge with a yet-undetermined callee where the call
    1132                 :             :    statement destination is a formal parameter of the caller with index
    1133                 :             :    PARAM_INDEX. CLONING_P should be set if properties that are copied from an
    1134                 :             :    original edge should not be calculated and indirect_info structure should
    1135                 :             :    not be calculated.  */
    1136                 :             : 
    1137                 :             : cgraph_edge *
    1138                 :      845207 : cgraph_node::create_indirect_edge (gcall *call_stmt, int ecf_flags,
    1139                 :             :                                    profile_count count,
    1140                 :             :                                    bool cloning_p)
    1141                 :             : {
    1142                 :      845207 :   cgraph_edge *edge = symtab->create_edge (this, NULL, call_stmt, count, true,
    1143                 :             :                                            cloning_p);
    1144                 :      845207 :   tree target;
    1145                 :             : 
    1146                 :      845207 :   if (!cloning_p)
    1147                 :      669326 :     initialize_inline_failed (edge);
    1148                 :             : 
    1149                 :      845207 :   edge->indirect_info = cgraph_allocate_init_indirect_info ();
    1150                 :      845207 :   edge->indirect_info->ecf_flags = ecf_flags;
    1151                 :      845207 :   edge->indirect_info->vptr_changed = true;
    1152                 :             : 
    1153                 :             :   /* Record polymorphic call info.  */
    1154                 :      845207 :   if (!cloning_p
    1155                 :      845207 :       && call_stmt
    1156                 :      667160 :       && (target = gimple_call_fn (call_stmt))
    1157                 :     1512367 :       && virtual_method_call_p (target))
    1158                 :             :     {
    1159                 :       99899 :       ipa_polymorphic_call_context context (decl, target, call_stmt);
    1160                 :             : 
    1161                 :             :       /* Only record types can have virtual calls.  */
    1162                 :       99899 :       edge->indirect_info->polymorphic = true;
    1163                 :       99899 :       edge->indirect_info->param_index = -1;
    1164                 :       99899 :       edge->indirect_info->otr_token
    1165                 :       99899 :          = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
    1166                 :       99899 :       edge->indirect_info->otr_type = obj_type_ref_class (target);
    1167                 :       99899 :       gcc_assert (TREE_CODE (edge->indirect_info->otr_type) == RECORD_TYPE);
    1168                 :       99899 :       edge->indirect_info->context = context;
    1169                 :             :     }
    1170                 :             : 
    1171                 :      845207 :   edge->next_callee = indirect_calls;
    1172                 :      845207 :   if (indirect_calls)
    1173                 :      404290 :     indirect_calls->prev_callee = edge;
    1174                 :      845207 :   indirect_calls = edge;
    1175                 :             : 
    1176                 :      845207 :   return edge;
    1177                 :             : }
    1178                 :             : 
    1179                 :             : /* Remove the edge from the list of the callees of the caller.  */
    1180                 :             : 
    1181                 :             : void
    1182                 :     4516196 : cgraph_edge::remove_caller (void)
    1183                 :             : {
    1184                 :     4516196 :   if (prev_callee)
    1185                 :     3661486 :     prev_callee->next_callee = next_callee;
    1186                 :     4516196 :   if (next_callee)
    1187                 :     3064943 :     next_callee->prev_callee = prev_callee;
    1188                 :     4516196 :   if (!prev_callee)
    1189                 :             :     {
    1190                 :      854710 :       if (indirect_unknown_callee)
    1191                 :         827 :         caller->indirect_calls = next_callee;
    1192                 :             :       else
    1193                 :      853883 :         caller->callees = next_callee;
    1194                 :             :     }
    1195                 :     4516196 :   if (caller->call_site_hash
    1196                 :     4516196 :       && this == caller->get_edge (call_stmt))
    1197                 :      565003 :     caller->call_site_hash->remove_elt_with_hash
    1198                 :      565003 :         (call_stmt, cgraph_edge_hasher::hash (call_stmt));
    1199                 :     4516196 : }
    1200                 :             : 
    1201                 :             : /* Put the edge onto the free list.  */
    1202                 :             : 
    1203                 :             : void
    1204                 :    43804167 : symbol_table::free_edge (cgraph_edge *e)
    1205                 :             : {
    1206                 :    43804167 :   edges_count--;
    1207                 :    43804167 :   if (e->m_summary_id != -1)
    1208                 :    20470795 :     edge_released_summary_ids.safe_push (e->m_summary_id);
    1209                 :             : 
    1210                 :    43804167 :   if (e->indirect_info)
    1211                 :      838800 :     ggc_free (e->indirect_info);
    1212                 :    43804167 :   ggc_free (e);
    1213                 :    43804167 : }
    1214                 :             : 
    1215                 :             : /* Remove the edge in the cgraph.  */
    1216                 :             : 
    1217                 :             : void
    1218                 :       96313 : cgraph_edge::remove (cgraph_edge *edge)
    1219                 :             : {
    1220                 :             :   /* Call all edge removal hooks.  */
    1221                 :       96313 :   symtab->call_edge_removal_hooks (edge);
    1222                 :             : 
    1223                 :       96313 :   if (!edge->indirect_unknown_callee)
    1224                 :             :     /* Remove from callers list of the callee.  */
    1225                 :       94093 :     edge->remove_callee ();
    1226                 :             : 
    1227                 :             :   /* Remove from callees list of the callers.  */
    1228                 :       96313 :   edge->remove_caller ();
    1229                 :             : 
    1230                 :             :   /* Put the edge onto the free list.  */
    1231                 :       96313 :   symtab->free_edge (edge);
    1232                 :       96313 : }
    1233                 :             : 
    1234                 :             : /* Turn edge into speculative call calling N2. Update
    1235                 :             :    the profile so the direct call is taken COUNT times
    1236                 :             :    with FREQUENCY.
    1237                 :             : 
    1238                 :             :    At clone materialization time, the indirect call E will
    1239                 :             :    be expanded as:
    1240                 :             : 
    1241                 :             :    if (call_dest == N2)
    1242                 :             :      n2 ();
    1243                 :             :    else
    1244                 :             :      call call_dest
    1245                 :             : 
    1246                 :             :    At this time the function just creates the direct call,
    1247                 :             :    the reference representing the if conditional and attaches
    1248                 :             :    them all to the original indirect call statement.
    1249                 :             : 
    1250                 :             :    speculative_id is used to link direct calls with their corresponding
    1251                 :             :    IPA_REF_ADDR references when representing speculative calls.
    1252                 :             : 
    1253                 :             :    Return direct edge created.  */
    1254                 :             : 
    1255                 :             : cgraph_edge *
    1256                 :        5094 : cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count,
    1257                 :             :                                unsigned int speculative_id)
    1258                 :             : {
    1259                 :        5094 :   cgraph_node *n = caller;
    1260                 :        5094 :   ipa_ref *ref = NULL;
    1261                 :        5094 :   cgraph_edge *e2;
    1262                 :             : 
    1263                 :        5094 :   if (dump_file)
    1264                 :          26 :     fprintf (dump_file, "Indirect call -> speculative call %s => %s\n",
    1265                 :             :              n->dump_name (), n2->dump_name ());
    1266                 :        5094 :   speculative = true;
    1267                 :        5094 :   e2 = n->create_edge (n2, call_stmt, direct_count);
    1268                 :        5094 :   initialize_inline_failed (e2);
    1269                 :        5094 :   e2->speculative = true;
    1270                 :        5094 :   if (TREE_NOTHROW (n2->decl))
    1271                 :        3551 :     e2->can_throw_external = false;
    1272                 :             :   else
    1273                 :        1543 :     e2->can_throw_external = can_throw_external;
    1274                 :        5094 :   e2->lto_stmt_uid = lto_stmt_uid;
    1275                 :        5094 :   e2->speculative_id = speculative_id;
    1276                 :        5094 :   e2->in_polymorphic_cdtor = in_polymorphic_cdtor;
    1277                 :        5094 :   indirect_info->num_speculative_call_targets++;
    1278                 :        5094 :   count -= e2->count;
    1279                 :        5094 :   symtab->call_edge_duplication_hooks (this, e2);
    1280                 :        5094 :   ref = n->create_reference (n2, IPA_REF_ADDR, call_stmt);
    1281                 :        5094 :   ref->lto_stmt_uid = lto_stmt_uid;
    1282                 :        5094 :   ref->speculative_id = speculative_id;
    1283                 :        5094 :   ref->speculative = speculative;
    1284                 :        5094 :   n2->mark_address_taken ();
    1285                 :        5094 :   return e2;
    1286                 :             : }
    1287                 :             : 
    1288                 :             : /* Speculative call consists of an indirect edge and one or more
    1289                 :             :    direct edge+ref pairs.
    1290                 :             : 
    1291                 :             :    Given an edge which is part of speculative call, return the first
    1292                 :             :    direct call edge in the speculative call sequence.  */
    1293                 :             : 
    1294                 :             : cgraph_edge *
    1295                 :       19570 : cgraph_edge::first_speculative_call_target ()
    1296                 :             : {
    1297                 :       19570 :   cgraph_edge *e = this;
    1298                 :             : 
    1299                 :       19570 :   gcc_checking_assert (e->speculative);
    1300                 :       19570 :   if (e->callee)
    1301                 :             :     {
    1302                 :        2185 :       while (e->prev_callee && e->prev_callee->speculative
    1303                 :         156 :              && e->prev_callee->call_stmt == e->call_stmt
    1304                 :       14779 :              && e->prev_callee->lto_stmt_uid == e->lto_stmt_uid)
    1305                 :             :         e = e->prev_callee;
    1306                 :             :       return e;
    1307                 :             :     }
    1308                 :             :   /* Call stmt site hash always points to the first target of the
    1309                 :             :      speculative call sequence.  */
    1310                 :        4791 :   if (e->call_stmt)
    1311                 :        4782 :     return e->caller->get_edge (e->call_stmt);
    1312                 :          14 :   for (cgraph_edge *e2 = e->caller->callees; true; e2 = e2->next_callee)
    1313                 :          14 :     if (e2->speculative
    1314                 :           9 :         && e->call_stmt == e2->call_stmt
    1315                 :           9 :         && e->lto_stmt_uid == e2->lto_stmt_uid)
    1316                 :             :       return e2;
    1317                 :             : }
    1318                 :             : 
    1319                 :             : /* We always maintain first direct edge in the call site hash, if one
    1320                 :             :    exists.  E is going to be removed.  See if it is first one and update
    1321                 :             :    hash accordingly.  INDIRECT is the indirect edge of speculative call.
    1322                 :             :    We assume that INDIRECT->num_speculative_call_targets_p () is already
    1323                 :             :    updated for removal of E.  */
    1324                 :             : static void
    1325                 :       13878 : update_call_stmt_hash_for_removing_direct_edge (cgraph_edge *e,
    1326                 :             :                                                 cgraph_edge *indirect)
    1327                 :             : {
    1328                 :       13878 :   if (e->caller->call_site_hash)
    1329                 :             :     {
    1330                 :        2704 :       if (e->caller->get_edge (e->call_stmt) != e)
    1331                 :             :         ;
    1332                 :        2704 :       else if (!indirect->num_speculative_call_targets_p ())
    1333                 :        2704 :         cgraph_update_edge_in_call_site_hash (indirect);
    1334                 :             :       else
    1335                 :             :         {
    1336                 :           0 :           gcc_checking_assert (e->next_callee && e->next_callee->speculative
    1337                 :             :                                && e->next_callee->call_stmt == e->call_stmt);
    1338                 :           0 :           cgraph_update_edge_in_call_site_hash (e->next_callee);
    1339                 :             :         }
    1340                 :             :     }
    1341                 :       13878 : }
    1342                 :             : 
    1343                 :             : /* Speculative call EDGE turned out to be direct call to CALLEE_DECL.  Remove
    1344                 :             :    the speculative call sequence and return edge representing the call, the
    1345                 :             :    original EDGE can be removed and deallocated.  Return the edge that now
    1346                 :             :    represents the call.
    1347                 :             : 
    1348                 :             :    For "speculative" indirect call that contains multiple "speculative"
    1349                 :             :    targets (i.e. edge->indirect_info->num_speculative_call_targets > 1),
    1350                 :             :    decrease the count and only remove current direct edge.
    1351                 :             : 
    1352                 :             :    If no speculative direct call left to the speculative indirect call, remove
    1353                 :             :    the speculative of both the indirect call and corresponding direct edge.
    1354                 :             : 
    1355                 :             :    It is up to caller to iteratively resolve each "speculative" direct call and
    1356                 :             :    redirect the call as appropriate.  */
    1357                 :             : 
    1358                 :             : cgraph_edge *
    1359                 :        1075 : cgraph_edge::resolve_speculation (cgraph_edge *edge, tree callee_decl)
    1360                 :             : {
    1361                 :        1075 :   cgraph_edge *e2;
    1362                 :        1075 :   ipa_ref *ref;
    1363                 :             : 
    1364                 :        1075 :   gcc_assert (edge->speculative && (!callee_decl || edge->callee));
    1365                 :        1075 :   if (!edge->callee)
    1366                 :           0 :     e2 = edge->first_speculative_call_target ();
    1367                 :             :   else
    1368                 :             :     e2 = edge;
    1369                 :        1075 :   ref = e2->speculative_call_target_ref ();
    1370                 :        1075 :   edge = edge->speculative_call_indirect_edge ();
    1371                 :        1075 :   if (!callee_decl
    1372                 :        1736 :       || !ref->referred->semantically_equivalent_p
    1373                 :         661 :            (symtab_node::get (callee_decl)))
    1374                 :             :     {
    1375                 :         645 :       if (dump_file)
    1376                 :             :         {
    1377                 :           0 :           if (callee_decl)
    1378                 :             :             {
    1379                 :           0 :               fprintf (dump_file, "Speculative indirect call %s => %s has "
    1380                 :             :                        "turned out to have contradicting known target ",
    1381                 :           0 :                        edge->caller->dump_name (),
    1382                 :           0 :                        e2->callee->dump_name ());
    1383                 :           0 :               print_generic_expr (dump_file, callee_decl);
    1384                 :           0 :               fprintf (dump_file, "\n");
    1385                 :             :             }
    1386                 :             :           else
    1387                 :             :             {
    1388                 :           0 :               fprintf (dump_file, "Removing speculative call %s => %s\n",
    1389                 :           0 :                        edge->caller->dump_name (),
    1390                 :           0 :                        e2->callee->dump_name ());
    1391                 :             :             }
    1392                 :             :         }
    1393                 :             :     }
    1394                 :             :   else
    1395                 :             :     {
    1396                 :         430 :       cgraph_edge *tmp = edge;
    1397                 :         430 :       if (dump_file)
    1398                 :          37 :         fprintf (dump_file, "Speculative call turned into direct call.\n");
    1399                 :             :       edge = e2;
    1400                 :             :       e2 = tmp;
    1401                 :             :       /* FIXME:  If EDGE is inlined, we should scale up the frequencies
    1402                 :             :          and counts in the functions inlined through it.  */
    1403                 :             :     }
    1404                 :        1075 :   edge->count += e2->count;
    1405                 :        1075 :   if (edge->num_speculative_call_targets_p ())
    1406                 :             :     {
    1407                 :             :       /* The indirect edge has multiple speculative targets, don't remove
    1408                 :             :          speculative until all related direct edges are resolved.  */
    1409                 :         645 :       edge->indirect_info->num_speculative_call_targets--;
    1410                 :         645 :       if (!edge->indirect_info->num_speculative_call_targets)
    1411                 :         641 :         edge->speculative = false;
    1412                 :             :     }
    1413                 :             :   else
    1414                 :         430 :     edge->speculative = false;
    1415                 :        1075 :   e2->speculative = false;
    1416                 :        1075 :   update_call_stmt_hash_for_removing_direct_edge (e2, edge);
    1417                 :        1075 :   ref->remove_reference ();
    1418                 :        1075 :   if (e2->indirect_unknown_callee || e2->inline_failed)
    1419                 :        1046 :     remove (e2);
    1420                 :             :   else
    1421                 :          29 :     e2->callee->remove_symbol_and_inline_clones ();
    1422                 :        1075 :   return edge;
    1423                 :             : }
    1424                 :             : 
    1425                 :             : /* Return edge corresponding to speculative call to a given target.
    1426                 :             :    NULL if speculative call does not have one.  */
    1427                 :             : 
    1428                 :             : cgraph_edge *
    1429                 :           0 : cgraph_edge::speculative_call_for_target (cgraph_node *target)
    1430                 :             : {
    1431                 :           0 :   for (cgraph_edge *direct = first_speculative_call_target ();
    1432                 :           0 :        direct;
    1433                 :           0 :        direct = direct->next_speculative_call_target ())
    1434                 :           0 :     if (direct->speculative_call_target_ref ()
    1435                 :           0 :         ->referred->semantically_equivalent_p (target))
    1436                 :             :       return direct;
    1437                 :             :   return NULL;
    1438                 :             : }
    1439                 :             : 
    1440                 :             : /* Make an indirect or speculative EDGE with an unknown callee an ordinary edge
    1441                 :             :    leading to CALLEE.  Speculations can be resolved in the process and EDGE can
    1442                 :             :    be removed and deallocated.  Return the edge that now represents the
    1443                 :             :    call.  */
    1444                 :             : 
    1445                 :             : cgraph_edge *
    1446                 :        4220 : cgraph_edge::make_direct (cgraph_edge *edge, cgraph_node *callee)
    1447                 :             : {
    1448                 :        4220 :   gcc_assert (edge->indirect_unknown_callee || edge->speculative);
    1449                 :             : 
    1450                 :             :   /* If we are redirecting speculative call, make it non-speculative.  */
    1451                 :        4220 :   if (edge->speculative)
    1452                 :             :     {
    1453                 :         457 :       cgraph_edge *found = NULL;
    1454                 :         457 :       cgraph_edge *direct, *next;
    1455                 :             : 
    1456                 :         457 :       edge = edge->speculative_call_indirect_edge ();
    1457                 :             : 
    1458                 :             :       /* Look all speculative targets and remove all but one corresponding
    1459                 :             :          to callee (if it exists).  */
    1460                 :         457 :       for (direct = edge->first_speculative_call_target ();
    1461                 :         918 :            direct;
    1462                 :             :            direct = next)
    1463                 :             :         {
    1464                 :         461 :           next = direct->next_speculative_call_target ();
    1465                 :             : 
    1466                 :             :           /* Compare ref not direct->callee.  Direct edge is possibly
    1467                 :             :              inlined or redirected.  */
    1468                 :         922 :           if (!direct->speculative_call_target_ref ()
    1469                 :         461 :                ->referred->semantically_equivalent_p (callee))
    1470                 :          31 :             edge = direct->resolve_speculation (direct, NULL);
    1471                 :             :           else
    1472                 :             :             {
    1473                 :         430 :               gcc_checking_assert (!found);
    1474                 :             :               found = direct;
    1475                 :             :             }
    1476                 :             :         }
    1477                 :             : 
    1478                 :             :       /* On successful speculation just remove the indirect edge and
    1479                 :             :          return the pre existing direct edge.
    1480                 :             :          It is important to not remove it and redirect because the direct
    1481                 :             :          edge may be inlined or redirected.  */
    1482                 :         457 :       if (found)
    1483                 :             :         {
    1484                 :         430 :           cgraph_edge *e2 = resolve_speculation (found, callee->decl);
    1485                 :         430 :           gcc_checking_assert (!found->speculative && e2 == found);
    1486                 :             :           return found;
    1487                 :             :         }
    1488                 :          27 :       gcc_checking_assert (!edge->speculative);
    1489                 :             :     }
    1490                 :             : 
    1491                 :        3790 :   edge->indirect_unknown_callee = 0;
    1492                 :        3790 :   ggc_free (edge->indirect_info);
    1493                 :        3790 :   edge->indirect_info = NULL;
    1494                 :             : 
    1495                 :             :   /* Get the edge out of the indirect edge list. */
    1496                 :        3790 :   if (edge->prev_callee)
    1497                 :          95 :     edge->prev_callee->next_callee = edge->next_callee;
    1498                 :        3790 :   if (edge->next_callee)
    1499                 :         492 :     edge->next_callee->prev_callee = edge->prev_callee;
    1500                 :        3790 :   if (!edge->prev_callee)
    1501                 :        3695 :     edge->caller->indirect_calls = edge->next_callee;
    1502                 :             : 
    1503                 :             :   /* Put it into the normal callee list */
    1504                 :        3790 :   edge->prev_callee = NULL;
    1505                 :        3790 :   edge->next_callee = edge->caller->callees;
    1506                 :        3790 :   if (edge->caller->callees)
    1507                 :        2337 :     edge->caller->callees->prev_callee = edge;
    1508                 :        3790 :   edge->caller->callees = edge;
    1509                 :             : 
    1510                 :             :   /* Insert to callers list of the new callee.  */
    1511                 :        3790 :   edge->set_callee (callee);
    1512                 :             : 
    1513                 :             :   /* We need to re-determine the inlining status of the edge.  */
    1514                 :        3790 :   initialize_inline_failed (edge);
    1515                 :        3790 :   return edge;
    1516                 :             : }
    1517                 :             : 
    1518                 :             : /* Redirect callee of the edge to N.  The function does not update underlying
    1519                 :             :    call expression.  */
    1520                 :             : 
    1521                 :             : void
    1522                 :     4250959 : cgraph_edge::redirect_callee (cgraph_node *n)
    1523                 :             : {
    1524                 :     4250959 :   bool loc = callee->comdat_local_p ();
    1525                 :             :   /* Remove from callers list of the current callee.  */
    1526                 :     4250959 :   remove_callee ();
    1527                 :             : 
    1528                 :             :   /* Insert to callers list of the new callee.  */
    1529                 :     4250959 :   set_callee (n);
    1530                 :             : 
    1531                 :     4250959 :   if (!inline_failed)
    1532                 :             :     return;
    1533                 :      557195 :   if (!loc && n->comdat_local_p ())
    1534                 :             :     {
    1535                 :          56 :       cgraph_node *to = caller->inlined_to ? caller->inlined_to : caller;
    1536                 :          56 :       to->calls_comdat_local = true;
    1537                 :             :     }
    1538                 :      557139 :   else if (loc && !n->comdat_local_p ())
    1539                 :             :     {
    1540                 :          99 :       cgraph_node *to = caller->inlined_to ? caller->inlined_to : caller;
    1541                 :          99 :       gcc_checking_assert (to->calls_comdat_local);
    1542                 :          99 :       to->calls_comdat_local = to->check_calls_comdat_local_p ();
    1543                 :             :     }
    1544                 :             : }
    1545                 :             : 
    1546                 :             : /* If necessary, change the function declaration in the call statement
    1547                 :             :    associated with E so that it corresponds to the edge callee.  Speculations
    1548                 :             :    can be resolved in the process and EDGE can be removed and deallocated.
    1549                 :             : 
    1550                 :             :    The edge could be one of speculative direct call generated from speculative
    1551                 :             :    indirect call.  In this circumstance, decrease the speculative targets
    1552                 :             :    count (i.e. num_speculative_call_targets) and redirect call stmt to the
    1553                 :             :    corresponding i-th target.  If no speculative direct call left to the
    1554                 :             :    speculative indirect call, remove "speculative" of the indirect call and
    1555                 :             :    also redirect stmt to it's final direct target.
    1556                 :             : 
    1557                 :             :    When called from within tree-inline, KILLED_SSAs has to contain the pointer
    1558                 :             :    to killed_new_ssa_names within the copy_body_data structure and SSAs
    1559                 :             :    discovered to be useless (if LHS is removed) will be added to it, otherwise
    1560                 :             :    it needs to be NULL.
    1561                 :             : 
    1562                 :             :    It is up to caller to iteratively transform each "speculative"
    1563                 :             :    direct call as appropriate.  */
    1564                 :             : 
    1565                 :             : gimple *
    1566                 :     9469245 : cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e,
    1567                 :             :                                            hash_set <tree> *killed_ssas)
    1568                 :             : {
    1569                 :     9469245 :   tree decl = gimple_call_fndecl (e->call_stmt);
    1570                 :     9469245 :   gcall *new_stmt;
    1571                 :             : 
    1572                 :     9469245 :   if (e->speculative)
    1573                 :             :     {
    1574                 :             :       /* If there already is an direct call (i.e. as a result of inliner's
    1575                 :             :          substitution), forget about speculating.  */
    1576                 :       12803 :       if (decl)
    1577                 :           0 :         e = make_direct (e->speculative_call_indirect_edge (),
    1578                 :             :                          cgraph_node::get (decl));
    1579                 :             :       else
    1580                 :             :         {
    1581                 :             :           /* Be sure we redirect all speculative targets before poking
    1582                 :             :              about indirect edge.  */
    1583                 :       12803 :           gcc_checking_assert (e->callee);
    1584                 :       12803 :           cgraph_edge *indirect = e->speculative_call_indirect_edge ();
    1585                 :       12803 :           gcall *new_stmt;
    1586                 :       12803 :           ipa_ref *ref;
    1587                 :             : 
    1588                 :             :           /* Expand speculation into GIMPLE code.  */
    1589                 :       12803 :           if (dump_file)
    1590                 :             :             {
    1591                 :          42 :               fprintf (dump_file,
    1592                 :             :                        "Expanding speculative call of %s -> %s count: ",
    1593                 :          21 :                        e->caller->dump_name (),
    1594                 :             :                        e->callee->dump_name ());
    1595                 :          21 :               e->count.dump (dump_file);
    1596                 :          21 :               fprintf (dump_file, "\n");
    1597                 :             :             }
    1598                 :       12803 :           push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
    1599                 :             : 
    1600                 :       12803 :           profile_count all = indirect->count;
    1601                 :       12803 :           for (cgraph_edge *e2 = e->first_speculative_call_target ();
    1602                 :       25609 :                e2;
    1603                 :       12806 :                e2 = e2->next_speculative_call_target ())
    1604                 :       12806 :             all = all + e2->count;
    1605                 :       12803 :           profile_probability prob = e->count.probability_in (all);
    1606                 :       12803 :           if (!prob.initialized_p ())
    1607                 :         116 :             prob = profile_probability::even ();
    1608                 :       12803 :           ref = e->speculative_call_target_ref ();
    1609                 :       25606 :           new_stmt = gimple_ic (e->call_stmt,
    1610                 :             :                                 dyn_cast<cgraph_node *> (ref->referred),
    1611                 :             :                                 prob);
    1612                 :       12803 :           e->speculative = false;
    1613                 :       12803 :           if (indirect->num_speculative_call_targets_p ())
    1614                 :             :             {
    1615                 :             :               /* The indirect edge has multiple speculative targets, don't
    1616                 :             :                  remove speculative until all related direct edges are
    1617                 :             :                  redirected.  */
    1618                 :       12803 :               indirect->indirect_info->num_speculative_call_targets--;
    1619                 :       12803 :               if (!indirect->indirect_info->num_speculative_call_targets)
    1620                 :       12800 :                 indirect->speculative = false;
    1621                 :             :             }
    1622                 :             :           else
    1623                 :           0 :             indirect->speculative = false;
    1624                 :             :           /* Indirect edges are not both in the call site hash.
    1625                 :             :              get it updated.  */
    1626                 :       12803 :           update_call_stmt_hash_for_removing_direct_edge (e, indirect);
    1627                 :       12803 :           cgraph_edge::set_call_stmt (e, new_stmt, false);
    1628                 :       12803 :           e->count = gimple_bb (e->call_stmt)->count;
    1629                 :             : 
    1630                 :             :           /* Once we are done with expanding the sequence, update also indirect
    1631                 :             :              call probability.  Until then the basic block accounts for the
    1632                 :             :              sum of indirect edge and all non-expanded speculations.  */
    1633                 :       12803 :           if (!indirect->speculative)
    1634                 :       12800 :             indirect->count = gimple_bb (indirect->call_stmt)->count;
    1635                 :       12803 :           ref->speculative = false;
    1636                 :       12803 :           ref->stmt = NULL;
    1637                 :       12803 :           pop_cfun ();
    1638                 :             :           /* Continue redirecting E to proper target.  */
    1639                 :             :         }
    1640                 :             :     }
    1641                 :             : 
    1642                 :             : 
    1643                 :     9469245 :   if (e->indirect_unknown_callee
    1644                 :     9379434 :       || decl == e->callee->decl)
    1645                 :     8537812 :     return e->call_stmt;
    1646                 :             : 
    1647                 :      931433 :   if (decl && ipa_saved_clone_sources)
    1648                 :             :     {
    1649                 :      766632 :       tree *p = ipa_saved_clone_sources->get (e->callee);
    1650                 :      766632 :       if (p && decl == *p)
    1651                 :             :         {
    1652                 :       33235 :           gimple_call_set_fndecl (e->call_stmt, e->callee->decl);
    1653                 :       33235 :           return e->call_stmt;
    1654                 :             :         }
    1655                 :             :     }
    1656                 :      898198 :   if (flag_checking && decl)
    1657                 :             :     {
    1658                 :      882271 :       if (cgraph_node *node = cgraph_node::get (decl))
    1659                 :             :         {
    1660                 :      751081 :           clone_info *info = clone_info::get (node);
    1661                 :      751081 :           gcc_assert (!info || !info->param_adjustments);
    1662                 :             :         }
    1663                 :             :     }
    1664                 :             : 
    1665                 :      898198 :   clone_info *callee_info = clone_info::get (e->callee);
    1666                 :      898198 :   if (symtab->dump_file)
    1667                 :             :     {
    1668                 :           0 :       fprintf (symtab->dump_file, "updating call of %s -> %s: ",
    1669                 :           0 :                e->caller->dump_name (), e->callee->dump_name ());
    1670                 :           0 :       print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
    1671                 :           0 :       if (callee_info && callee_info->param_adjustments)
    1672                 :           0 :         callee_info->param_adjustments->dump (symtab->dump_file);
    1673                 :             :     }
    1674                 :             : 
    1675                 :      472272 :   if (ipa_param_adjustments *padjs
    1676                 :      898198 :          = callee_info ? callee_info->param_adjustments : NULL)
    1677                 :             :     {
    1678                 :             :       /* We need to defer cleaning EH info on the new statement to
    1679                 :             :          fixup-cfg.  We may not have dominator information at this point
    1680                 :             :          and thus would end up with unreachable blocks and have no way
    1681                 :             :          to communicate that we need to run CFG cleanup then.  */
    1682                 :      444361 :       int lp_nr = lookup_stmt_eh_lp (e->call_stmt);
    1683                 :      444361 :       if (lp_nr != 0)
    1684                 :      134228 :         remove_stmt_from_eh_lp (e->call_stmt);
    1685                 :             : 
    1686                 :      444361 :       tree old_fntype = gimple_call_fntype (e->call_stmt);
    1687                 :      444361 :       new_stmt = padjs->modify_call (e, false, killed_ssas);
    1688                 :      444361 :       cgraph_node *origin = e->callee;
    1689                 :      655680 :       while (origin->clone_of)
    1690                 :             :         origin = origin->clone_of;
    1691                 :             : 
    1692                 :      444361 :       if ((origin->former_clone_of
    1693                 :      347078 :            && old_fntype == TREE_TYPE (origin->former_clone_of))
    1694                 :      446472 :           || old_fntype == TREE_TYPE (origin->decl))
    1695                 :      344969 :         gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
    1696                 :             :       else
    1697                 :             :         {
    1698                 :       99392 :           tree new_fntype = padjs->build_new_function_type (old_fntype, true);
    1699                 :       99392 :           gimple_call_set_fntype (new_stmt, new_fntype);
    1700                 :             :         }
    1701                 :             : 
    1702                 :      444361 :       if (lp_nr != 0)
    1703                 :      134228 :         add_stmt_to_eh_lp (new_stmt, lp_nr);
    1704                 :             :     }
    1705                 :             :   else
    1706                 :             :     {
    1707                 :      453837 :       if (flag_checking
    1708                 :      453837 :           && !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    1709                 :             :                                                   BUILT_IN_UNREACHABLE_TRAP))
    1710                 :      301814 :         ipa_verify_edge_has_no_modifications (e);
    1711                 :      453837 :       new_stmt = e->call_stmt;
    1712                 :      453837 :       gimple_call_set_fndecl (new_stmt, e->callee->decl);
    1713                 :      453837 :       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
    1714                 :             :     }
    1715                 :             : 
    1716                 :             :   /* If changing the call to __cxa_pure_virtual or similar noreturn function,
    1717                 :             :      adjust gimple_call_fntype too.  */
    1718                 :      898198 :   if (gimple_call_noreturn_p (new_stmt)
    1719                 :      156028 :       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (e->callee->decl)))
    1720                 :      155955 :       && TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl))
    1721                 :     1054147 :       && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl)))
    1722                 :      155949 :           == void_type_node))
    1723                 :      155251 :     gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
    1724                 :             : 
    1725                 :             :   /* If the call becomes noreturn, remove the LHS if possible.  */
    1726                 :      898198 :   tree lhs = gimple_call_lhs (new_stmt);
    1727                 :      898198 :   if (lhs
    1728                 :      257004 :       && gimple_call_noreturn_p (new_stmt)
    1729                 :      941178 :       && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (new_stmt)))
    1730                 :          60 :           || should_remove_lhs_p (lhs)))
    1731                 :             :     {
    1732                 :       42939 :       gimple_call_set_lhs (new_stmt, NULL_TREE);
    1733                 :             :       /* We need to fix up the SSA name to avoid checking errors.  */
    1734                 :       42939 :       if (TREE_CODE (lhs) == SSA_NAME)
    1735                 :             :         {
    1736                 :       32095 :           tree var = create_tmp_reg_fn (DECL_STRUCT_FUNCTION (e->caller->decl),
    1737                 :       32095 :                                         TREE_TYPE (lhs), NULL);
    1738                 :       32095 :           SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
    1739                 :       32095 :           SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
    1740                 :       32095 :           set_ssa_default_def (DECL_STRUCT_FUNCTION (e->caller->decl),
    1741                 :             :                                var, lhs);
    1742                 :             :         }
    1743                 :       42939 :       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
    1744                 :             :     }
    1745                 :             : 
    1746                 :             :   /* If new callee has no static chain, remove it.  */
    1747                 :      898198 :   if (gimple_call_chain (new_stmt) && !DECL_STATIC_CHAIN (e->callee->decl))
    1748                 :             :     {
    1749                 :          56 :       gimple_call_set_chain (new_stmt, NULL);
    1750                 :          56 :       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
    1751                 :             :     }
    1752                 :             : 
    1753                 :      898198 :   maybe_remove_unused_call_args (DECL_STRUCT_FUNCTION (e->caller->decl),
    1754                 :             :                                  new_stmt);
    1755                 :             : 
    1756                 :      898198 :   e->caller->set_call_stmt_including_clones (e->call_stmt, new_stmt, false);
    1757                 :             : 
    1758                 :      898198 :   if (symtab->dump_file)
    1759                 :             :     {
    1760                 :           0 :       fprintf (symtab->dump_file, "  updated to:");
    1761                 :           0 :       print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
    1762                 :             :     }
    1763                 :             :   return new_stmt;
    1764                 :             : }
    1765                 :             : 
    1766                 :             : /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
    1767                 :             :    OLD_STMT changed into NEW_STMT.  OLD_CALL is gimple_call_fndecl
    1768                 :             :    of OLD_STMT if it was previously call statement.
    1769                 :             :    If NEW_STMT is NULL, the call has been dropped without any
    1770                 :             :    replacement.  */
    1771                 :             : 
    1772                 :             : static void
    1773                 :      118748 : cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
    1774                 :             :                                         gimple *old_stmt, tree old_call,
    1775                 :             :                                         gimple *new_stmt)
    1776                 :             : {
    1777                 :      118748 :   tree new_call = (new_stmt && is_gimple_call (new_stmt))
    1778                 :      124272 :                   ? gimple_call_fndecl (new_stmt) : 0;
    1779                 :             : 
    1780                 :             :   /* We are seeing indirect calls, then there is nothing to update.  */
    1781                 :      118748 :   if (!new_call && !old_call)
    1782                 :             :     return;
    1783                 :             :   /* See if we turned indirect call into direct call or folded call to one builtin
    1784                 :             :      into different builtin.  */
    1785                 :      116965 :   if (old_call != new_call)
    1786                 :             :     {
    1787                 :      115370 :       cgraph_edge *e = node->get_edge (old_stmt);
    1788                 :      115370 :       cgraph_edge *ne = NULL;
    1789                 :      115370 :       profile_count count;
    1790                 :             : 
    1791                 :      115370 :       if (e)
    1792                 :             :         {
    1793                 :             :           /* If call was devirtualized during cloning, mark edge
    1794                 :             :              as resolved.  */
    1795                 :       94111 :           if (e->speculative)
    1796                 :             :             {
    1797                 :           1 :               if (new_stmt && is_gimple_call (new_stmt))
    1798                 :             :                 {
    1799                 :           1 :                   tree decl = gimple_call_fndecl (new_stmt);
    1800                 :           1 :                   if (decl)
    1801                 :           1 :                     e = cgraph_edge::resolve_speculation (e, decl);
    1802                 :             :                 }
    1803                 :             :               else
    1804                 :           0 :                 e = cgraph_edge::resolve_speculation (e, NULL);
    1805                 :             :             }
    1806                 :             :           /* Keep calls marked as dead dead.  */
    1807                 :       94111 :           if (new_stmt && is_gimple_call (new_stmt) && e->callee
    1808                 :       94677 :               && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    1809                 :             :                                     BUILT_IN_UNREACHABLE_TRAP))
    1810                 :             :             {
    1811                 :           5 :               cgraph_edge::set_call_stmt (node->get_edge (old_stmt),
    1812                 :             :                                           as_a <gcall *> (new_stmt));
    1813                 :          32 :               return;
    1814                 :             :             }
    1815                 :             :           /* See if the edge is already there and has the correct callee.  It
    1816                 :             :              might be so because of indirect inlining has already updated
    1817                 :             :              it.  We also might've cloned and redirected the edge.  */
    1818                 :       94106 :           if (new_call && e->callee)
    1819                 :             :             {
    1820                 :             :               cgraph_node *callee = e->callee;
    1821                 :        1123 :               while (callee)
    1822                 :             :                 {
    1823                 :         584 :                   if (callee->decl == new_call
    1824                 :         584 :                       || callee->former_clone_of == new_call)
    1825                 :             :                     {
    1826                 :          22 :                       cgraph_edge::set_call_stmt (e, as_a <gcall *> (new_stmt));
    1827                 :          22 :                       return;
    1828                 :             :                     }
    1829                 :         562 :                   callee = callee->clone_of;
    1830                 :             :                 }
    1831                 :             :             }
    1832                 :             : 
    1833                 :             :           /* Otherwise remove edge and create new one; we can't simply redirect
    1834                 :             :              since function has changed, so inline plan and other information
    1835                 :             :              attached to edge is invalid.  */
    1836                 :       94084 :           count = e->count;
    1837                 :       94084 :           if (e->indirect_unknown_callee || e->inline_failed)
    1838                 :       94084 :             cgraph_edge::remove (e);
    1839                 :             :           else
    1840                 :           0 :             e->callee->remove_symbol_and_inline_clones ();
    1841                 :             :         }
    1842                 :       21259 :       else if (new_call)
    1843                 :             :         {
    1844                 :             :           /* We are seeing new direct call; compute profile info based on BB.  */
    1845                 :           4 :           basic_block bb = gimple_bb (new_stmt);
    1846                 :           4 :           count = bb->count;
    1847                 :             :         }
    1848                 :             : 
    1849                 :       94088 :       if (new_call)
    1850                 :             :         {
    1851                 :        2319 :           ne = node->create_edge (cgraph_node::get_create (new_call),
    1852                 :             :                                   as_a <gcall *> (new_stmt), count);
    1853                 :        2319 :           gcc_assert (ne->inline_failed);
    1854                 :             :         }
    1855                 :             :     }
    1856                 :             :   /* We only updated the call stmt; update pointer in cgraph edge..  */
    1857                 :        1595 :   else if (old_stmt != new_stmt)
    1858                 :           0 :     cgraph_edge::set_call_stmt (node->get_edge (old_stmt),
    1859                 :             :                                 as_a <gcall *> (new_stmt));
    1860                 :             : }
    1861                 :             : 
    1862                 :             : /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
    1863                 :             :    OLD_STMT changed into NEW_STMT.  OLD_DECL is gimple_call_fndecl
    1864                 :             :    of OLD_STMT before it was updated (updating can happen inplace).  */
    1865                 :             : 
    1866                 :             : void
    1867                 :       97148 : cgraph_update_edges_for_call_stmt (gimple *old_stmt, tree old_decl,
    1868                 :             :                                    gimple *new_stmt)
    1869                 :             : {
    1870                 :       97148 :   cgraph_node *orig = cgraph_node::get (cfun->decl);
    1871                 :       97148 :   cgraph_node *node;
    1872                 :             : 
    1873                 :       97148 :   gcc_checking_assert (orig);
    1874                 :       97148 :   gcc_assert (!orig->thunk);
    1875                 :       97148 :   cgraph_update_edges_for_call_stmt_node (orig, old_stmt, old_decl, new_stmt);
    1876                 :       97148 :   if (orig->clones)
    1877                 :       42563 :     for (node = orig->clones; node != orig;)
    1878                 :             :       {
    1879                 :             :         /* Do not attempt to adjust bodies of yet unexpanded thunks.  */
    1880                 :       21602 :         if (!node->thunk)
    1881                 :       21600 :           cgraph_update_edges_for_call_stmt_node (node, old_stmt, old_decl,
    1882                 :             :                                                   new_stmt);
    1883                 :       21602 :         if (node->clones)
    1884                 :             :           node = node->clones;
    1885                 :       21590 :         else if (node->next_sibling_clone)
    1886                 :             :           node = node->next_sibling_clone;
    1887                 :             :         else
    1888                 :             :           {
    1889                 :       41934 :             while (node != orig && !node->next_sibling_clone)
    1890                 :       20973 :               node = node->clone_of;
    1891                 :       20961 :             if (node != orig)
    1892                 :           0 :               node = node->next_sibling_clone;
    1893                 :             :           }
    1894                 :             :       }
    1895                 :       97148 : }
    1896                 :             : 
    1897                 :             : 
    1898                 :             : /* Remove all callees from the node.  */
    1899                 :             : 
    1900                 :             : void
    1901                 :   209806345 : cgraph_node::remove_callees (void)
    1902                 :             : {
    1903                 :   209806345 :   cgraph_edge *e, *f;
    1904                 :             : 
    1905                 :   209806345 :   calls_comdat_local = false;
    1906                 :             : 
    1907                 :             :   /* It is sufficient to remove the edges from the lists of callers of
    1908                 :             :      the callees.  The callee list of the node can be zapped with one
    1909                 :             :      assignment.  */
    1910                 :   248257736 :   for (e = callees; e; e = f)
    1911                 :             :     {
    1912                 :    38451391 :       f = e->next_callee;
    1913                 :    38451391 :       symtab->call_edge_removal_hooks (e);
    1914                 :    38451391 :       if (!e->indirect_unknown_callee)
    1915                 :    38451391 :         e->remove_callee ();
    1916                 :    38451391 :       symtab->free_edge (e);
    1917                 :             :     }
    1918                 :   210642925 :   for (e = indirect_calls; e; e = f)
    1919                 :             :     {
    1920                 :      836580 :       f = e->next_callee;
    1921                 :      836580 :       symtab->call_edge_removal_hooks (e);
    1922                 :      836580 :       if (!e->indirect_unknown_callee)
    1923                 :           0 :         e->remove_callee ();
    1924                 :      836580 :       symtab->free_edge (e);
    1925                 :             :     }
    1926                 :   209806345 :   indirect_calls = NULL;
    1927                 :   209806345 :   callees = NULL;
    1928                 :   209806345 :   if (call_site_hash)
    1929                 :             :     {
    1930                 :       29128 :       call_site_hash->empty ();
    1931                 :       29128 :       call_site_hash = NULL;
    1932                 :             :     }
    1933                 :   209806345 : }
    1934                 :             : 
    1935                 :             : /* Remove all callers from the node.  */
    1936                 :             : 
    1937                 :             : void
    1938                 :    93662948 : cgraph_node::remove_callers (void)
    1939                 :             : {
    1940                 :    93662948 :   cgraph_edge *e, *f;
    1941                 :             : 
    1942                 :             :   /* It is sufficient to remove the edges from the lists of callees of
    1943                 :             :      the callers.  The caller list of the node can be zapped with one
    1944                 :             :      assignment.  */
    1945                 :    98082831 :   for (e = callers; e; e = f)
    1946                 :             :     {
    1947                 :     4419883 :       f = e->next_caller;
    1948                 :     4419883 :       symtab->call_edge_removal_hooks (e);
    1949                 :     4419883 :       e->remove_caller ();
    1950                 :     4419883 :       symtab->free_edge (e);
    1951                 :             :     }
    1952                 :    93662948 :   callers = NULL;
    1953                 :    93662948 : }
    1954                 :             : 
    1955                 :             : /* Helper function for cgraph_release_function_body and free_lang_data.
    1956                 :             :    It releases body from function DECL without having to inspect its
    1957                 :             :    possibly non-existent symtab node.  */
    1958                 :             : 
    1959                 :             : void
    1960                 :   110756197 : release_function_body (tree decl)
    1961                 :             : {
    1962                 :   110756197 :   function *fn = DECL_STRUCT_FUNCTION (decl);
    1963                 :   110756197 :   if (fn)
    1964                 :             :     {
    1965                 :    92228644 :       if (fn->cfg
    1966                 :    92228644 :           && loops_for_fn (fn))
    1967                 :             :         {
    1968                 :     1715219 :           fn->curr_properties &= ~PROP_loops;
    1969                 :     1715219 :           loop_optimizer_finalize (fn);
    1970                 :             :         }
    1971                 :    92228644 :       if (fn->gimple_df)
    1972                 :             :         {
    1973                 :     1723850 :           delete_tree_ssa (fn);
    1974                 :     1723850 :           fn->eh = NULL;
    1975                 :             :         }
    1976                 :    92228644 :       if (fn->cfg)
    1977                 :             :         {
    1978                 :     1715220 :           gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
    1979                 :     1715220 :           gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
    1980                 :     1715220 :           delete_tree_cfg_annotations (fn);
    1981                 :     1715220 :           free_cfg (fn);
    1982                 :     1715220 :           fn->cfg = NULL;
    1983                 :             :         }
    1984                 :    92228644 :       if (fn->value_histograms)
    1985                 :          12 :         free_histograms (fn);
    1986                 :    92228644 :       gimple_set_body (decl, NULL);
    1987                 :             :       /* Struct function hangs a lot of data that would leak if we didn't
    1988                 :             :          removed all pointers to it.   */
    1989                 :    92228644 :       ggc_free (fn);
    1990                 :    92228644 :       DECL_STRUCT_FUNCTION (decl) = NULL;
    1991                 :             :     }
    1992                 :   110756197 :   DECL_SAVED_TREE (decl) = NULL;
    1993                 :   110756197 : }
    1994                 :             : 
    1995                 :             : /* Release memory used to represent body of function.
    1996                 :             :    Use this only for functions that are released before being translated to
    1997                 :             :    target code (i.e. RTL).  Functions that are compiled to RTL and beyond
    1998                 :             :    are free'd in final.cc via free_after_compilation().
    1999                 :             :    KEEP_ARGUMENTS are useful only if you want to rebuild body as thunk.  */
    2000                 :             : 
    2001                 :             : void
    2002                 :   103694985 : cgraph_node::release_body (bool keep_arguments)
    2003                 :             : {
    2004                 :   103694985 :   ipa_transforms_to_apply.release ();
    2005                 :   103694985 :   if (!used_as_abstract_origin && symtab->state != PARSING)
    2006                 :             :     {
    2007                 :   103107302 :       DECL_RESULT (decl) = NULL;
    2008                 :             : 
    2009                 :   103107302 :       if (!keep_arguments)
    2010                 :   103077363 :         DECL_ARGUMENTS (decl) = NULL;
    2011                 :             :     }
    2012                 :             :   /* If the node is abstract and needed, then do not clear
    2013                 :             :      DECL_INITIAL of its associated function declaration because it's
    2014                 :             :      needed to emit debug info later.  */
    2015                 :   103694985 :   if (!used_as_abstract_origin && DECL_INITIAL (decl))
    2016                 :    91684115 :     DECL_INITIAL (decl) = error_mark_node;
    2017                 :   103694985 :   release_function_body (decl);
    2018                 :   103694985 :   if (lto_file_data)
    2019                 :             :     {
    2020                 :       48696 :       lto_free_function_in_decl_state_for_node (this);
    2021                 :       48696 :       lto_file_data = NULL;
    2022                 :             :     }
    2023                 :   103694985 :   if (flag_checking && clones)
    2024                 :             :     {
    2025                 :             :       /* It is invalid to release body before materializing clones except
    2026                 :             :          for thunks that don't really need a body.  Verify also that we do
    2027                 :             :          not leak pointers to the call statements.  */
    2028                 :          30 :       for (cgraph_node *node = clones; node;
    2029                 :          18 :            node = node->next_sibling_clone)
    2030                 :          18 :         gcc_assert (node->thunk && !node->callees->call_stmt);
    2031                 :             :     }
    2032                 :   103694985 :   remove_callees ();
    2033                 :   103694985 :   remove_all_references ();
    2034                 :   103694985 : }
    2035                 :             : 
    2036                 :             : /* Remove function from symbol table.  */
    2037                 :             : 
    2038                 :             : void
    2039                 :    93662948 : cgraph_node::remove (void)
    2040                 :             : {
    2041                 :    93662948 :   bool clone_info_set = false;
    2042                 :    93662948 :   clone_info *info, saved_info;
    2043                 :    93662948 :   if (symtab->ipa_clones_dump_file && symtab->cloned_nodes.contains (this))
    2044                 :           4 :     fprintf (symtab->ipa_clones_dump_file,
    2045                 :             :              "Callgraph removal;%s;%d;%s;%d;%d\n", asm_name (), get_uid (),
    2046                 :           4 :              DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
    2047                 :           8 :              DECL_SOURCE_COLUMN (decl));
    2048                 :             : 
    2049                 :    93662948 :   if ((info = clone_info::get (this)) != NULL)
    2050                 :             :     {
    2051                 :      366715 :       saved_info = *info;
    2052                 :      366715 :       clone_info_set = true;
    2053                 :             :     }
    2054                 :    93662948 :   symtab->call_cgraph_removal_hooks (this);
    2055                 :    93662948 :   remove_callers ();
    2056                 :    93662948 :   remove_callees ();
    2057                 :    93662948 :   ipa_transforms_to_apply.release ();
    2058                 :    93662948 :   delete_function_version (function_version ());
    2059                 :             : 
    2060                 :             :   /* Incremental inlining access removed nodes stored in the postorder list.
    2061                 :             :      */
    2062                 :    93662948 :   force_output = false;
    2063                 :    93662948 :   forced_by_abi = false;
    2064                 :             : 
    2065                 :   186959181 :   unregister (clone_info_set ? &saved_info : NULL);
    2066                 :    93662948 :   if (prev_sibling_clone)
    2067                 :      720099 :     prev_sibling_clone->next_sibling_clone = next_sibling_clone;
    2068                 :    92942849 :   else if (clone_of)
    2069                 :             :     {
    2070                 :     1772948 :       clone_of->clones = next_sibling_clone;
    2071                 :     1772948 :       if (!clones)
    2072                 :             :         {
    2073                 :     1769802 :           bool need_body = false;
    2074                 :     1769802 :           for (cgraph_node *n = clone_of; n; n = n->clone_of)
    2075                 :     1764585 :             if (n->analyzed || n->clones)
    2076                 :             :               {
    2077                 :             :                 need_body = true;
    2078                 :             :                 break;
    2079                 :             :               }
    2080                 :     1764581 :           if (!need_body)
    2081                 :        5217 :             clone_of->release_body ();
    2082                 :             :         }
    2083                 :             :     }
    2084                 :    93662948 :   if (next_sibling_clone)
    2085                 :      915707 :     next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
    2086                 :    93662948 :   if (clones)
    2087                 :             :     {
    2088                 :       37814 :       cgraph_node *n, *next;
    2089                 :             : 
    2090                 :       37814 :       if (clone_of)
    2091                 :             :         {
    2092                 :      175960 :           for (n = clones; n->next_sibling_clone; n = n->next_sibling_clone)
    2093                 :      138146 :             n->clone_of = clone_of;
    2094                 :       37814 :           n->clone_of = clone_of;
    2095                 :       37814 :           n->next_sibling_clone = clone_of->clones;
    2096                 :       37814 :           if (clone_of->clones)
    2097                 :       32996 :             clone_of->clones->prev_sibling_clone = n;
    2098                 :       37814 :           clone_of->clones = clones;
    2099                 :             :         }
    2100                 :             :       else
    2101                 :             :         {
    2102                 :             :           /* We are removing node with clones.  This makes clones inconsistent,
    2103                 :             :              but assume they will be removed subsequently and just keep clone
    2104                 :             :              tree intact.  This can happen in unreachable function removal since
    2105                 :             :              we remove unreachable functions in random order, not by bottom-up
    2106                 :             :              walk of clone trees.  */
    2107                 :           0 :           for (n = clones; n; n = next)
    2108                 :             :             {
    2109                 :           0 :                next = n->next_sibling_clone;
    2110                 :           0 :                n->next_sibling_clone = NULL;
    2111                 :           0 :                n->prev_sibling_clone = NULL;
    2112                 :           0 :                n->clone_of = NULL;
    2113                 :             :             }
    2114                 :             :         }
    2115                 :             :     }
    2116                 :             : 
    2117                 :             :   /* While all the clones are removed after being proceeded, the function
    2118                 :             :      itself is kept in the cgraph even after it is compiled.  Check whether
    2119                 :             :      we are done with this body and reclaim it proactively if this is the case.
    2120                 :             :      */
    2121                 :    93662948 :   if (symtab->state != LTO_STREAMING)
    2122                 :             :     {
    2123                 :    93660908 :       cgraph_node *n = cgraph_node::get (decl);
    2124                 :    93660908 :       if (!n
    2125                 :    93660908 :           || (!n->clones && !n->clone_of && !n->inlined_to
    2126                 :     1130784 :               && ((symtab->global_info_ready || in_lto_p)
    2127                 :        9675 :                   && (TREE_ASM_WRITTEN (n->decl)
    2128                 :        9653 :                       || DECL_EXTERNAL (n->decl)
    2129                 :        5242 :                       || !n->analyzed
    2130                 :        5179 :                       || (!flag_wpa && n->in_other_partition)))))
    2131                 :    90765652 :         release_body ();
    2132                 :             :     }
    2133                 :             :   else
    2134                 :             :     {
    2135                 :        2040 :       lto_free_function_in_decl_state_for_node (this);
    2136                 :        2040 :       lto_file_data = NULL;
    2137                 :             :     }
    2138                 :             : 
    2139                 :    93662948 :   decl = NULL;
    2140                 :    93662948 :   if (call_site_hash)
    2141                 :             :     {
    2142                 :           0 :       call_site_hash->empty ();
    2143                 :           0 :       call_site_hash = NULL;
    2144                 :             :     }
    2145                 :             : 
    2146                 :    93662948 :   symtab->release_symbol (this);
    2147                 :    93662948 : }
    2148                 :             : 
    2149                 :             : /* Likewise indicate that a node is having address taken.  */
    2150                 :             : 
    2151                 :             : void
    2152                 :     4706545 : cgraph_node::mark_address_taken (void)
    2153                 :             : {
    2154                 :             :   /* Indirect inlining can figure out that all uses of the address are
    2155                 :             :      inlined.  */
    2156                 :     4706545 :   if (inlined_to)
    2157                 :             :     {
    2158                 :           0 :       gcc_assert (cfun->after_inlining);
    2159                 :           0 :       gcc_assert (callers->indirect_inlining_edge);
    2160                 :             :       return;
    2161                 :             :     }
    2162                 :             :   /* FIXME: address_taken flag is used both as a shortcut for testing whether
    2163                 :             :      IPA_REF_ADDR reference exists (and thus it should be set on node
    2164                 :             :      representing alias we take address of) and as a test whether address
    2165                 :             :      of the object was taken (and thus it should be set on node alias is
    2166                 :             :      referring to).  We should remove the first use and the remove the
    2167                 :             :      following set.  */
    2168                 :     4706545 :   address_taken = 1;
    2169                 :     4706545 :   cgraph_node *node = ultimate_alias_target ();
    2170                 :     4706545 :   node->address_taken = 1;
    2171                 :             : }
    2172                 :             : 
    2173                 :             : /* Return local info node for the compiled function.  */
    2174                 :             : 
    2175                 :             : cgraph_node *
    2176                 :    12508553 : cgraph_node::local_info_node (tree decl)
    2177                 :             : {
    2178                 :    12508553 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
    2179                 :    12508553 :   cgraph_node *node = get (decl);
    2180                 :    12508553 :   if (!node)
    2181                 :             :     return NULL;
    2182                 :    12508553 :   return node->ultimate_alias_target ();
    2183                 :             : }
    2184                 :             : 
    2185                 :             : /* Return RTL info for the compiled function.  */
    2186                 :             : 
    2187                 :             : cgraph_rtl_info *
    2188                 :    56802546 : cgraph_node::rtl_info (const_tree decl)
    2189                 :             : {
    2190                 :    56802546 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
    2191                 :    56802546 :   cgraph_node *node = get (decl);
    2192                 :    56802546 :   if (!node)
    2193                 :             :     return NULL;
    2194                 :    56666636 :   enum availability avail;
    2195                 :    56666636 :   node = node->ultimate_alias_target (&avail);
    2196                 :    56666636 :   if (decl != current_function_decl
    2197                 :    53748367 :       && (avail < AVAIL_AVAILABLE
    2198                 :    48674562 :           || (node->decl != current_function_decl
    2199                 :    48603342 :               && !TREE_ASM_WRITTEN (node->decl))))
    2200                 :             :     return NULL;
    2201                 :             :   /* Allocate if it doesn't exist.  */
    2202                 :    48163083 :   if (node->rtl == NULL)
    2203                 :             :     {
    2204                 :     1323831 :       node->rtl = ggc_cleared_alloc<cgraph_rtl_info> ();
    2205                 :     1323831 :       SET_HARD_REG_SET (node->rtl->function_used_regs);
    2206                 :             :     }
    2207                 :    48163083 :   return node->rtl;
    2208                 :             : }
    2209                 :             : 
    2210                 :             : /* Return a string describing the failure REASON.  */
    2211                 :             : 
    2212                 :             : const char*
    2213                 :        9723 : cgraph_inline_failed_string (cgraph_inline_failed_t reason)
    2214                 :             : {
    2215                 :             : #undef DEFCIFCODE
    2216                 :             : #define DEFCIFCODE(code, type, string)  string,
    2217                 :             : 
    2218                 :        9723 :   static const char *cif_string_table[CIF_N_REASONS] = {
    2219                 :             : #include "cif-code.def"
    2220                 :             :   };
    2221                 :             : 
    2222                 :             :   /* Signedness of an enum type is implementation defined, so cast it
    2223                 :             :      to unsigned before testing. */
    2224                 :        9723 :   gcc_assert ((unsigned) reason < CIF_N_REASONS);
    2225                 :        9723 :   return cif_string_table[reason];
    2226                 :             : }
    2227                 :             : 
    2228                 :             : /* Return a type describing the failure REASON.  */
    2229                 :             : 
    2230                 :             : cgraph_inline_failed_type_t
    2231                 :    71829554 : cgraph_inline_failed_type (cgraph_inline_failed_t reason)
    2232                 :             : {
    2233                 :             : #undef DEFCIFCODE
    2234                 :             : #define DEFCIFCODE(code, type, string)  type,
    2235                 :             : 
    2236                 :    71829554 :   static cgraph_inline_failed_type_t cif_type_table[CIF_N_REASONS] = {
    2237                 :             : #include "cif-code.def"
    2238                 :             :   };
    2239                 :             : 
    2240                 :             :   /* Signedness of an enum type is implementation defined, so cast it
    2241                 :             :      to unsigned before testing. */
    2242                 :    71829554 :   gcc_assert ((unsigned) reason < CIF_N_REASONS);
    2243                 :    71829554 :   return cif_type_table[reason];
    2244                 :             : }
    2245                 :             : 
    2246                 :             : /* Names used to print out the availability enum.  */
    2247                 :             : const char * const cgraph_availability_names[] =
    2248                 :             :   {"unset", "not_available", "overwritable", "available", "local"};
    2249                 :             : 
    2250                 :             : /* Output flags of edge to a file F.  */
    2251                 :             : 
    2252                 :             : void
    2253                 :       22427 : cgraph_edge::dump_edge_flags (FILE *f)
    2254                 :             : {
    2255                 :       22427 :   if (speculative)
    2256                 :         138 :     fprintf (f, "(speculative) ");
    2257                 :       22427 :   if (!inline_failed)
    2258                 :        1660 :     fprintf (f, "(inlined) ");
    2259                 :       22427 :   if (call_stmt_cannot_inline_p)
    2260                 :           0 :     fprintf (f, "(call_stmt_cannot_inline_p) ");
    2261                 :       22427 :   if (indirect_inlining_edge)
    2262                 :         325 :     fprintf (f, "(indirect_inlining) ");
    2263                 :       22427 :   if (count.initialized_p ())
    2264                 :             :     {
    2265                 :       21668 :       fprintf (f, "(");
    2266                 :       21668 :       count.dump (f);
    2267                 :       21668 :       fprintf (f, ",");
    2268                 :       21668 :       fprintf (f, "%.2f per call) ", sreal_frequency ().to_double ());
    2269                 :             :     }
    2270                 :       22427 :   if (can_throw_external)
    2271                 :        2732 :     fprintf (f, "(can throw external) ");
    2272                 :       22427 : }
    2273                 :             : 
    2274                 :             : /* Dump edge to stderr.  */
    2275                 :             : 
    2276                 :             : void
    2277                 :           0 : cgraph_edge::debug (void)
    2278                 :             : {
    2279                 :           0 :   fprintf (stderr, "%s -> %s ", caller->dump_asm_name (),
    2280                 :           0 :            callee == NULL ? "(null)" : callee->dump_asm_name ());
    2281                 :           0 :   dump_edge_flags (stderr);
    2282                 :           0 :   fprintf (stderr, "\n\n");
    2283                 :           0 :   caller->debug ();
    2284                 :           0 :   if (callee != NULL)
    2285                 :           0 :     callee->debug ();
    2286                 :           0 : }
    2287                 :             : 
    2288                 :             : /* Dump call graph node to file F.  */
    2289                 :             : 
    2290                 :             : void
    2291                 :        5710 : cgraph_node::dump (FILE *f)
    2292                 :             : {
    2293                 :        5710 :   cgraph_edge *edge;
    2294                 :             : 
    2295                 :        5710 :   dump_base (f);
    2296                 :             : 
    2297                 :        5710 :   if (inlined_to)
    2298                 :         716 :     fprintf (f, "  Function %s is inline copy in %s\n",
    2299                 :             :              dump_name (),
    2300                 :             :              inlined_to->dump_name ());
    2301                 :        5710 :   if (clone_of)
    2302                 :         701 :     fprintf (f, "  Clone of %s\n", clone_of->dump_asm_name ());
    2303                 :        5710 :   if (symtab->function_flags_ready)
    2304                 :       10284 :     fprintf (f, "  Availability: %s\n",
    2305                 :        5142 :              cgraph_availability_names [get_availability ()]);
    2306                 :             : 
    2307                 :        5710 :   if (profile_id)
    2308                 :         149 :     fprintf (f, "  Profile id: %i\n",
    2309                 :             :              profile_id);
    2310                 :        5710 :   if (unit_id)
    2311                 :         133 :     fprintf (f, "  Unit id: %i\n",
    2312                 :             :              unit_id);
    2313                 :        5710 :   cgraph_function_version_info *vi = function_version ();
    2314                 :        5710 :   if (vi != NULL)
    2315                 :             :     {
    2316                 :           0 :       fprintf (f, "  Version info: ");
    2317                 :           0 :       if (vi->prev != NULL)
    2318                 :             :         {
    2319                 :           0 :           fprintf (f, "prev: ");
    2320                 :           0 :           fprintf (f, "%s ", vi->prev->this_node->dump_asm_name ());
    2321                 :             :         }
    2322                 :           0 :       if (vi->next != NULL)
    2323                 :             :         {
    2324                 :           0 :           fprintf (f, "next: ");
    2325                 :           0 :           fprintf (f, "%s ", vi->next->this_node->dump_asm_name ());
    2326                 :             :         }
    2327                 :           0 :       if (vi->dispatcher_resolver != NULL_TREE)
    2328                 :           0 :         fprintf (f, "dispatcher: %s",
    2329                 :           0 :                  lang_hooks.decl_printable_name (vi->dispatcher_resolver, 2));
    2330                 :             : 
    2331                 :           0 :       fprintf (f, "\n");
    2332                 :             :     }
    2333                 :        5710 :   fprintf (f, "  Function flags:");
    2334                 :        5710 :   if (count.initialized_p ())
    2335                 :             :     {
    2336                 :        3506 :       fprintf (f, " count:");
    2337                 :        3506 :       count.dump (f);
    2338                 :             :     }
    2339                 :        5710 :   if (tp_first_run > 0)
    2340                 :          67 :     fprintf (f, " first_run:%" PRId64, (int64_t) tp_first_run);
    2341                 :        5710 :   if (cgraph_node *origin = nested_function_origin (this))
    2342                 :           0 :     fprintf (f, " nested in:%s", origin->dump_asm_name ());
    2343                 :        5710 :   if (gimple_has_body_p (decl))
    2344                 :        3749 :     fprintf (f, " body");
    2345                 :        5710 :   if (process)
    2346                 :           0 :     fprintf (f, " process");
    2347                 :        5710 :   if (local)
    2348                 :        1070 :     fprintf (f, " local");
    2349                 :        5710 :   if (redefined_extern_inline)
    2350                 :           0 :     fprintf (f, " redefined_extern_inline");
    2351                 :        5710 :   if (only_called_at_startup)
    2352                 :         391 :     fprintf (f, " only_called_at_startup");
    2353                 :        5710 :   if (only_called_at_exit)
    2354                 :           7 :     fprintf (f, " only_called_at_exit");
    2355                 :        5710 :   if (tm_clone)
    2356                 :           0 :     fprintf (f, " tm_clone");
    2357                 :        5710 :   if (calls_comdat_local)
    2358                 :           9 :     fprintf (f, " calls_comdat_local");
    2359                 :        5710 :   if (icf_merged)
    2360                 :          24 :     fprintf (f, " icf_merged");
    2361                 :        5710 :   if (merged_comdat)
    2362                 :           0 :     fprintf (f, " merged_comdat");
    2363                 :        5710 :   if (merged_extern_inline)
    2364                 :           0 :     fprintf (f, " merged_extern_inline");
    2365                 :        5710 :   if (split_part)
    2366                 :          23 :     fprintf (f, " split_part");
    2367                 :        5710 :   if (indirect_call_target)
    2368                 :         206 :     fprintf (f, " indirect_call_target");
    2369                 :        5710 :   if (nonfreeing_fn)
    2370                 :         337 :     fprintf (f, " nonfreeing_fn");
    2371                 :        5710 :   if (DECL_STATIC_CONSTRUCTOR (decl))
    2372                 :          45 :     fprintf (f," static_constructor (priority:%i)", get_init_priority ());
    2373                 :        5710 :   if (DECL_STATIC_DESTRUCTOR (decl))
    2374                 :           7 :     fprintf (f," static_destructor (priority:%i)", get_fini_priority ());
    2375                 :        5710 :   if (frequency == NODE_FREQUENCY_HOT)
    2376                 :          59 :     fprintf (f, " hot");
    2377                 :        5710 :   if (frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
    2378                 :          39 :     fprintf (f, " unlikely_executed");
    2379                 :        5710 :   if (frequency == NODE_FREQUENCY_EXECUTED_ONCE)
    2380                 :         685 :     fprintf (f, " executed_once");
    2381                 :        5710 :   if (opt_for_fn (decl, optimize_size))
    2382                 :         176 :     fprintf (f, " optimize_size");
    2383                 :        5710 :   if (parallelized_function)
    2384                 :           0 :     fprintf (f, " parallelized_function");
    2385                 :        5710 :   if (DECL_IS_MALLOC (decl))
    2386                 :          70 :     fprintf (f, " decl_is_malloc");
    2387                 :        5710 :   if (DECL_IS_OPERATOR_NEW_P (decl))
    2388                 :          35 :     fprintf (f, " %soperator_new",
    2389                 :          35 :              DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
    2390                 :        5710 :   if (DECL_IS_OPERATOR_DELETE_P (decl))
    2391                 :          26 :     fprintf (f, " %soperator_delete",
    2392                 :          26 :              DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
    2393                 :             : 
    2394                 :        5710 :   if (DECL_STATIC_CHAIN (decl))
    2395                 :           6 :     fprintf (f, " static_chain");
    2396                 :             : 
    2397                 :        5710 :   fprintf (f, "\n");
    2398                 :             : 
    2399                 :        5710 :   if (thunk)
    2400                 :             :     {
    2401                 :          43 :       fprintf (f, "  Thunk");
    2402                 :          43 :       thunk_info::get (this)->dump (f);
    2403                 :             :     }
    2404                 :        5667 :   else if (former_thunk_p ())
    2405                 :             :     {
    2406                 :          27 :       fprintf (f, "  Former thunk ");
    2407                 :          27 :       thunk_info::get (this)->dump (f);
    2408                 :             :     }
    2409                 :        5640 :   else gcc_checking_assert (!thunk_info::get (this));
    2410                 :             : 
    2411                 :        5710 :   fprintf (f, "  Called by: ");
    2412                 :             : 
    2413                 :        5710 :   profile_count sum = profile_count::zero ();
    2414                 :       13321 :   for (edge = callers; edge; edge = edge->next_caller)
    2415                 :             :     {
    2416                 :        7611 :       fprintf (f, "%s ", edge->caller->dump_asm_name ());
    2417                 :        7611 :       edge->dump_edge_flags (f);
    2418                 :        7611 :       if (edge->count.initialized_p ())
    2419                 :        7351 :         sum += edge->count.ipa ();
    2420                 :             :     }
    2421                 :             : 
    2422                 :        5710 :   fprintf (f, "\n  Calls: ");
    2423                 :       19775 :   for (edge = callees; edge; edge = edge->next_callee)
    2424                 :             :     {
    2425                 :       14065 :       fprintf (f, "%s ", edge->callee->dump_asm_name ());
    2426                 :       14065 :       edge->dump_edge_flags (f);
    2427                 :             :     }
    2428                 :        5710 :   fprintf (f, "\n");
    2429                 :             : 
    2430                 :        5710 :   if (!body_removed && count.ipa ().initialized_p ())
    2431                 :             :     {
    2432                 :         106 :       bool ok = true;
    2433                 :         106 :       bool min = false;
    2434                 :             :       ipa_ref *ref;
    2435                 :             : 
    2436                 :         106 :       FOR_EACH_ALIAS (this, ref)
    2437                 :           0 :         if (dyn_cast <cgraph_node *> (ref->referring)->count.initialized_p ())
    2438                 :           0 :           sum += dyn_cast <cgraph_node *> (ref->referring)->count.ipa ();
    2439                 :             : 
    2440                 :         106 :       if (inlined_to
    2441                 :         106 :           || (symtab->state < EXPANSION
    2442                 :         106 :               && ultimate_alias_target () == this && only_called_directly_p ()))
    2443                 :           3 :         ok = !count.ipa ().differs_from_p (sum);
    2444                 :         103 :       else if (count.ipa () > profile_count::from_gcov_type (100)
    2445                 :         103 :                && count.ipa () < sum.apply_scale (99, 100))
    2446                 :           0 :         ok = false, min = true;
    2447                 :         106 :       if (!ok)
    2448                 :             :         {
    2449                 :           0 :           fprintf (f, "   Invalid sum of caller counts ");
    2450                 :           0 :           sum.dump (f);
    2451                 :           0 :           if (min)
    2452                 :           0 :             fprintf (f, ", should be at most ");
    2453                 :             :           else
    2454                 :           0 :             fprintf (f, ", should be ");
    2455                 :           0 :           count.ipa ().dump (f);
    2456                 :           0 :           fprintf (f, "\n");
    2457                 :             :         }
    2458                 :             :     }
    2459                 :             : 
    2460                 :        6461 :   for (edge = indirect_calls; edge; edge = edge->next_callee)
    2461                 :             :     {
    2462                 :         751 :       if (edge->indirect_info->polymorphic)
    2463                 :             :         {
    2464                 :         277 :           fprintf (f, "   Polymorphic indirect call of type ");
    2465                 :         277 :           print_generic_expr (f, edge->indirect_info->otr_type, TDF_SLIM);
    2466                 :         277 :           fprintf (f, " token:%i", (int) edge->indirect_info->otr_token);
    2467                 :             :         }
    2468                 :             :       else
    2469                 :         474 :         fprintf (f, "   Indirect call");
    2470                 :         751 :       edge->dump_edge_flags (f);
    2471                 :         751 :       if (edge->indirect_info->param_index != -1)
    2472                 :             :         {
    2473                 :         201 :           fprintf (f, "of param:%i ", edge->indirect_info->param_index);
    2474                 :         201 :           if (edge->indirect_info->agg_contents)
    2475                 :          19 :            fprintf (f, "loaded from %s %s at offset %i ",
    2476                 :          19 :                     edge->indirect_info->member_ptr ? "member ptr" : "aggregate",
    2477                 :          19 :                     edge->indirect_info->by_ref ? "passed by reference" : "",
    2478                 :          19 :                     (int)edge->indirect_info->offset);
    2479                 :         201 :           if (edge->indirect_info->vptr_changed)
    2480                 :          23 :             fprintf (f, "(vptr maybe changed) ");
    2481                 :             :         }
    2482                 :         751 :       fprintf (f, "num speculative call targets: %i\n",
    2483                 :         751 :                edge->indirect_info->num_speculative_call_targets);
    2484                 :         751 :       if (edge->indirect_info->polymorphic)
    2485                 :         277 :         edge->indirect_info->context.dump (f);
    2486                 :             :     }
    2487                 :        5710 : }
    2488                 :             : 
    2489                 :             : /* Dump call graph node to file F in graphviz format.  */
    2490                 :             : 
    2491                 :             : void
    2492                 :           0 : cgraph_node::dump_graphviz (FILE *f)
    2493                 :             : {
    2494                 :           0 :   cgraph_edge *edge;
    2495                 :             : 
    2496                 :           0 :   for (edge = callees; edge; edge = edge->next_callee)
    2497                 :             :     {
    2498                 :           0 :       cgraph_node *callee = edge->callee;
    2499                 :             : 
    2500                 :           0 :       fprintf (f, "\t\"%s\" -> \"%s\"\n", dump_name (), callee->dump_name ());
    2501                 :             :     }
    2502                 :           0 : }
    2503                 :             : 
    2504                 :             : 
    2505                 :             : /* Dump call graph node NODE to stderr.  */
    2506                 :             : 
    2507                 :             : DEBUG_FUNCTION void
    2508                 :           0 : cgraph_node::debug (void)
    2509                 :             : {
    2510                 :           0 :   dump (stderr);
    2511                 :           0 : }
    2512                 :             : 
    2513                 :             : /* Dump the callgraph to file F.  */
    2514                 :             : 
    2515                 :             : void
    2516                 :          77 : cgraph_node::dump_cgraph (FILE *f)
    2517                 :             : {
    2518                 :          77 :   cgraph_node *node;
    2519                 :             : 
    2520                 :          77 :   fprintf (f, "callgraph:\n\n");
    2521                 :         724 :   FOR_EACH_FUNCTION (node)
    2522                 :         285 :     node->dump (f);
    2523                 :          77 : }
    2524                 :             : 
    2525                 :             : /* Return true when the DECL can possibly be inlined.  */
    2526                 :             : 
    2527                 :             : bool
    2528                 :    83913865 : cgraph_function_possibly_inlined_p (tree decl)
    2529                 :             : {
    2530                 :    83913865 :   if (!symtab->global_info_ready)
    2531                 :    76511712 :     return !DECL_UNINLINABLE (decl);
    2532                 :     7402153 :   return DECL_POSSIBLY_INLINED (decl);
    2533                 :             : }
    2534                 :             : 
    2535                 :             : /* Return function availability.  See cgraph.h for description of individual
    2536                 :             :    return values.  */
    2537                 :             : enum availability
    2538                 :   783517230 : cgraph_node::get_availability (symtab_node *ref)
    2539                 :             : {
    2540                 :   783517230 :   if (ref)
    2541                 :             :     {
    2542                 :   554103132 :       cgraph_node *cref = dyn_cast <cgraph_node *> (ref);
    2543                 :   554103132 :       if (cref)
    2544                 :   554103132 :         ref = cref->inlined_to;
    2545                 :             :     }
    2546                 :   783517230 :   enum availability avail;
    2547                 :   783517230 :   if (!analyzed && !in_other_partition)
    2548                 :   471488851 :     avail = AVAIL_NOT_AVAILABLE;
    2549                 :   312028379 :   else if (local)
    2550                 :    87461978 :     avail = AVAIL_LOCAL;
    2551                 :   224566401 :   else if (inlined_to)
    2552                 :     2202499 :     avail = AVAIL_AVAILABLE;
    2553                 :   222363902 :   else if (transparent_alias)
    2554                 :         134 :     ultimate_alias_target (&avail, ref);
    2555                 :   222363768 :   else if (ifunc_resolver
    2556                 :   222363768 :            || lookup_attribute ("noipa", DECL_ATTRIBUTES (decl)))
    2557                 :     3309897 :     avail = AVAIL_INTERPOSABLE;
    2558                 :   219053871 :   else if (!externally_visible)
    2559                 :    28037834 :     avail = AVAIL_AVAILABLE;
    2560                 :             :   /* If this is a reference from symbol itself and there are no aliases, we
    2561                 :             :      may be sure that the symbol was not interposed by something else because
    2562                 :             :      the symbol itself would be unreachable otherwise.
    2563                 :             : 
    2564                 :             :      Also comdat groups are always resolved in groups.  */
    2565                 :       37228 :   else if ((this == ref && !has_aliases_p ())
    2566                 :   191016702 :            || (ref && get_comdat_group ()
    2567                 :     1409289 :                && get_comdat_group () == ref->get_comdat_group ()))
    2568                 :       38814 :     avail = AVAIL_AVAILABLE;
    2569                 :             :   /* Inline functions are safe to be analyzed even if their symbol can
    2570                 :             :      be overwritten at runtime.  It is not meaningful to enforce any sane
    2571                 :             :      behavior on replacing inline function by different body.  */
    2572                 :   190977223 :   else if (DECL_DECLARED_INLINE_P (decl))
    2573                 :    65505994 :     avail = AVAIL_AVAILABLE;
    2574                 :             : 
    2575                 :             :   /* If the function can be overwritten, return OVERWRITABLE.  Take
    2576                 :             :      care at least of two notable extensions - the COMDAT functions
    2577                 :             :      used to share template instantiations in C++ (this is symmetric
    2578                 :             :      to code cp_cannot_inline_tree_fn and probably shall be shared and
    2579                 :             :      the inlinability hooks completely eliminated).  */
    2580                 :             : 
    2581                 :   125471229 :   else if (decl_replaceable_p (decl, semantic_interposition)
    2582                 :   125471229 :            && !DECL_EXTERNAL (decl))
    2583                 :     9275852 :     avail = AVAIL_INTERPOSABLE;
    2584                 :   116195377 :   else avail = AVAIL_AVAILABLE;
    2585                 :             : 
    2586                 :   783517230 :   return avail;
    2587                 :             : }
    2588                 :             : 
    2589                 :             : /* Worker for cgraph_node_can_be_local_p.  */
    2590                 :             : static bool
    2591                 :      843643 : cgraph_node_cannot_be_local_p_1 (cgraph_node *node, void *)
    2592                 :             : {
    2593                 :      843643 :   return !(!node->force_output
    2594                 :      822935 :            && !node->ifunc_resolver
    2595                 :             :            /* Limitation of gas requires us to output targets of symver aliases
    2596                 :             :               as global symbols.  This is binutils PR 25295.  */
    2597                 :      822895 :            && !node->symver
    2598                 :      822895 :            && ((DECL_COMDAT (node->decl)
    2599                 :      353735 :                 && !node->forced_by_abi
    2600                 :      331344 :                 && !node->used_from_object_file_p ()
    2601                 :      331344 :                 && !node->same_comdat_group)
    2602                 :      539953 :                || !node->externally_visible)
    2603                 :      425965 :            && !DECL_STATIC_CONSTRUCTOR (node->decl)
    2604                 :      424217 :            && !DECL_STATIC_DESTRUCTOR (node->decl));
    2605                 :             : }
    2606                 :             : 
    2607                 :             : /* Return true if cgraph_node can be made local for API change.
    2608                 :             :    Extern inline functions and C++ COMDAT functions can be made local
    2609                 :             :    at the expense of possible code size growth if function is used in multiple
    2610                 :             :    compilation units.  */
    2611                 :             : bool
    2612                 :     1149743 : cgraph_node::can_be_local_p (void)
    2613                 :             : {
    2614                 :     1149743 :   return (!address_taken
    2615                 :     1149743 :           && !call_for_symbol_thunks_and_aliases (cgraph_node_cannot_be_local_p_1,
    2616                 :     1149743 :                                                 NULL, true));
    2617                 :             : }
    2618                 :             : 
    2619                 :             : /* Call callback on cgraph_node, thunks and aliases associated to cgraph_node.
    2620                 :             :    When INCLUDE_OVERWRITABLE is false, overwritable symbols are
    2621                 :             :    skipped.  When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
    2622                 :             :    skipped.  */
    2623                 :             : bool
    2624                 :   123692640 : cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
    2625                 :             :                                                    (cgraph_node *, void *),
    2626                 :             :                                                  void *data,
    2627                 :             :                                                  bool include_overwritable,
    2628                 :             :                                                  bool exclude_virtual_thunks)
    2629                 :             : {
    2630                 :   123692640 :   cgraph_edge *e;
    2631                 :   123692640 :   ipa_ref *ref;
    2632                 :   123692640 :   enum availability avail = AVAIL_AVAILABLE;
    2633                 :             : 
    2634                 :   123692640 :   if (include_overwritable
    2635                 :   123692640 :       || (avail = get_availability ()) > AVAIL_INTERPOSABLE)
    2636                 :             :     {
    2637                 :   123681175 :       if (callback (this, data))
    2638                 :             :         return true;
    2639                 :             :     }
    2640                 :   130629304 :   FOR_EACH_ALIAS (this, ref)
    2641                 :             :     {
    2642                 :    12222195 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2643                 :    12222195 :       if (include_overwritable
    2644                 :    12222195 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
    2645                 :    12221953 :         if (alias->call_for_symbol_thunks_and_aliases (callback, data,
    2646                 :             :                                                      include_overwritable,
    2647                 :             :                                                      exclude_virtual_thunks))
    2648                 :             :           return true;
    2649                 :             :     }
    2650                 :   118407109 :   if (avail <= AVAIL_INTERPOSABLE)
    2651                 :             :     return false;
    2652                 :   123831189 :   for (e = callers; e; e = e->next_caller)
    2653                 :     5435545 :     if (e->caller->thunk
    2654                 :        2748 :         && (include_overwritable
    2655                 :         414 :             || e->caller->get_availability () > AVAIL_INTERPOSABLE)
    2656                 :     5438293 :         && !(exclude_virtual_thunks
    2657                 :          22 :              && thunk_info::get (e->caller)->virtual_offset_p))
    2658                 :        2736 :       if (e->caller->call_for_symbol_thunks_and_aliases (callback, data,
    2659                 :             :                                                        include_overwritable,
    2660                 :             :                                                        exclude_virtual_thunks))
    2661                 :             :         return true;
    2662                 :             : 
    2663                 :             :   return false;
    2664                 :             : }
    2665                 :             : 
    2666                 :             : /* Worker to bring NODE local.  */
    2667                 :             : 
    2668                 :             : bool
    2669                 :           0 : cgraph_node::make_local (cgraph_node *node, void *)
    2670                 :             : {
    2671                 :           0 :   gcc_checking_assert (node->can_be_local_p ());
    2672                 :           0 :   if (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
    2673                 :             :     {
    2674                 :           0 :       node->make_decl_local ();
    2675                 :           0 :       node->set_section (NULL);
    2676                 :           0 :       node->set_comdat_group (NULL);
    2677                 :           0 :       node->externally_visible = false;
    2678                 :           0 :       node->forced_by_abi = false;
    2679                 :           0 :       node->local = true;
    2680                 :           0 :       node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
    2681                 :           0 :                            || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
    2682                 :           0 :                            && !flag_incremental_link);
    2683                 :           0 :       node->resolution = LDPR_PREVAILING_DEF_IRONLY;
    2684                 :           0 :       gcc_assert (node->get_availability () == AVAIL_LOCAL);
    2685                 :             :     }
    2686                 :           0 :   return false;
    2687                 :             : }
    2688                 :             : 
    2689                 :             : /* Bring cgraph node local.  */
    2690                 :             : 
    2691                 :             : void
    2692                 :           0 : cgraph_node::make_local (void)
    2693                 :             : {
    2694                 :           0 :   call_for_symbol_thunks_and_aliases (cgraph_node::make_local, NULL, true);
    2695                 :           0 : }
    2696                 :             : 
    2697                 :             : /* Worker to set nothrow flag.  */
    2698                 :             : 
    2699                 :             : static void
    2700                 :      915154 : set_nothrow_flag_1 (cgraph_node *node, bool nothrow, bool non_call,
    2701                 :             :                     bool *changed)
    2702                 :             : {
    2703                 :      915154 :   cgraph_edge *e;
    2704                 :             : 
    2705                 :      915154 :   if (nothrow && !TREE_NOTHROW (node->decl))
    2706                 :             :     {
    2707                 :             :       /* With non-call exceptions we can't say for sure if other function body
    2708                 :             :          was not possibly optimized to still throw.  */
    2709                 :      915129 :       if (!non_call || node->binds_to_current_def_p ())
    2710                 :             :         {
    2711                 :      910316 :           TREE_NOTHROW (node->decl) = true;
    2712                 :      910316 :           *changed = true;
    2713                 :     2240867 :           for (e = node->callers; e; e = e->next_caller)
    2714                 :     1330551 :             e->can_throw_external = false;
    2715                 :             :         }
    2716                 :             :     }
    2717                 :           0 :   else if (!nothrow && TREE_NOTHROW (node->decl))
    2718                 :             :     {
    2719                 :           0 :       TREE_NOTHROW (node->decl) = false;
    2720                 :           0 :       *changed = true;
    2721                 :             :     }
    2722                 :             :   ipa_ref *ref;
    2723                 :      970083 :   FOR_EACH_ALIAS (node, ref)
    2724                 :             :     {
    2725                 :       54929 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2726                 :       54929 :       if (!nothrow || alias->get_availability () > AVAIL_INTERPOSABLE)
    2727                 :       54504 :         set_nothrow_flag_1 (alias, nothrow, non_call, changed);
    2728                 :             :     }
    2729                 :     2282531 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    2730                 :     1367377 :     if (e->caller->thunk
    2731                 :     1367377 :         && (!nothrow || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    2732                 :         135 :       set_nothrow_flag_1 (e->caller, nothrow, non_call, changed);
    2733                 :      915154 : }
    2734                 :             : 
    2735                 :             : /* Set TREE_NOTHROW on NODE's decl and on aliases of NODE
    2736                 :             :    if any to NOTHROW.  */
    2737                 :             : 
    2738                 :             : bool
    2739                 :      872357 : cgraph_node::set_nothrow_flag (bool nothrow)
    2740                 :             : {
    2741                 :      872357 :   bool changed = false;
    2742                 :      872357 :   bool non_call = opt_for_fn (decl, flag_non_call_exceptions);
    2743                 :             : 
    2744                 :      872357 :   if (!nothrow || get_availability () > AVAIL_INTERPOSABLE)
    2745                 :      860408 :     set_nothrow_flag_1 (this, nothrow, non_call, &changed);
    2746                 :             :   else
    2747                 :             :     {
    2748                 :             :       ipa_ref *ref;
    2749                 :             : 
    2750                 :       19280 :       FOR_EACH_ALIAS (this, ref)
    2751                 :             :         {
    2752                 :        7331 :           cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2753                 :        7331 :           if (!nothrow || alias->get_availability () > AVAIL_INTERPOSABLE)
    2754                 :         107 :             set_nothrow_flag_1 (alias, nothrow, non_call, &changed);
    2755                 :             :         }
    2756                 :             :     }
    2757                 :      872357 :   return changed;
    2758                 :             : }
    2759                 :             : 
    2760                 :             : /* Worker to set malloc flag.  */
    2761                 :             : static void
    2762                 :       23227 : set_malloc_flag_1 (cgraph_node *node, bool malloc_p, bool *changed)
    2763                 :             : {
    2764                 :       23227 :   if (malloc_p && !DECL_IS_MALLOC (node->decl))
    2765                 :             :     {
    2766                 :       22801 :       DECL_IS_MALLOC (node->decl) = true;
    2767                 :       22801 :       *changed = true;
    2768                 :             :     }
    2769                 :             : 
    2770                 :             :   ipa_ref *ref;
    2771                 :       23228 :   FOR_EACH_ALIAS (node, ref)
    2772                 :             :     {
    2773                 :           1 :       cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    2774                 :           1 :       if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    2775                 :           1 :         set_malloc_flag_1 (alias, malloc_p, changed);
    2776                 :             :     }
    2777                 :             : 
    2778                 :       51401 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    2779                 :       28174 :     if (e->caller->thunk
    2780                 :       28174 :         && (!malloc_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    2781                 :           0 :       set_malloc_flag_1 (e->caller, malloc_p, changed);
    2782                 :       23227 : }
    2783                 :             : 
    2784                 :             : /* Set DECL_IS_MALLOC on NODE's decl and on NODE's aliases if any.  */
    2785                 :             : 
    2786                 :             : bool
    2787                 :       23226 : cgraph_node::set_malloc_flag (bool malloc_p)
    2788                 :             : {
    2789                 :       23226 :   bool changed = false;
    2790                 :             : 
    2791                 :       23226 :   if (!malloc_p || get_availability () > AVAIL_INTERPOSABLE)
    2792                 :       23226 :     set_malloc_flag_1 (this, malloc_p, &changed);
    2793                 :             :   else
    2794                 :             :     {
    2795                 :             :       ipa_ref *ref;
    2796                 :             : 
    2797                 :           0 :       FOR_EACH_ALIAS (this, ref)
    2798                 :             :         {
    2799                 :           0 :           cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    2800                 :           0 :           if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    2801                 :           0 :             set_malloc_flag_1 (alias, malloc_p, &changed);
    2802                 :             :         }
    2803                 :             :     }
    2804                 :       23226 :   return changed;
    2805                 :             : }
    2806                 :             : 
    2807                 :             : /* Worker to set malloc flag.  */
    2808                 :             : static void
    2809                 :      230112 : add_detected_attribute_1 (cgraph_node *node, const char *attr, bool *changed)
    2810                 :             : {
    2811                 :      230112 :   if (!lookup_attribute (attr, DECL_ATTRIBUTES (node->decl)))
    2812                 :             :     {
    2813                 :      205621 :       DECL_ATTRIBUTES (node->decl) = tree_cons (get_identifier (attr),
    2814                 :      205621 :                                          NULL_TREE, DECL_ATTRIBUTES (node->decl));
    2815                 :      205621 :       *changed = true;
    2816                 :             :     }
    2817                 :             : 
    2818                 :             :   ipa_ref *ref;
    2819                 :      230590 :   FOR_EACH_ALIAS (node, ref)
    2820                 :             :     {
    2821                 :         478 :       cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    2822                 :         478 :       if (alias->get_availability () > AVAIL_INTERPOSABLE)
    2823                 :          69 :         add_detected_attribute_1 (alias, attr, changed);
    2824                 :             :     }
    2825                 :             : 
    2826                 :      737519 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    2827                 :      507407 :     if (e->caller->thunk
    2828                 :      507407 :         && (e->caller->get_availability () > AVAIL_INTERPOSABLE))
    2829                 :          14 :       add_detected_attribute_1 (e->caller, attr, changed);
    2830                 :      230112 : }
    2831                 :             : 
    2832                 :             : /* Add attribyte ATTR to function and its aliases.  */
    2833                 :             : 
    2834                 :             : bool
    2835                 :      233753 : cgraph_node::add_detected_attribute (const char *attr)
    2836                 :             : {
    2837                 :      233753 :   bool changed = false;
    2838                 :             : 
    2839                 :      233753 :   if (get_availability () > AVAIL_INTERPOSABLE)
    2840                 :      230029 :     add_detected_attribute_1 (this, attr, &changed);
    2841                 :             :   else
    2842                 :             :     {
    2843                 :             :       ipa_ref *ref;
    2844                 :             : 
    2845                 :        3748 :       FOR_EACH_ALIAS (this, ref)
    2846                 :             :         {
    2847                 :          24 :           cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    2848                 :          24 :           if (alias->get_availability () > AVAIL_INTERPOSABLE)
    2849                 :           0 :             add_detected_attribute_1 (alias, attr, &changed);
    2850                 :             :         }
    2851                 :             :     }
    2852                 :      233753 :   return changed;
    2853                 :             : }
    2854                 :             : 
    2855                 :             : /* Worker to set noreturng flag.  */
    2856                 :             : static void
    2857                 :       27884 : set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed)
    2858                 :             : {
    2859                 :       27884 :   if (noreturn_p && !TREE_THIS_VOLATILE (node->decl))
    2860                 :             :     {
    2861                 :       27884 :       TREE_THIS_VOLATILE (node->decl) = true;
    2862                 :       27884 :       *changed = true;
    2863                 :             :     }
    2864                 :             : 
    2865                 :             :   ipa_ref *ref;
    2866                 :       28548 :   FOR_EACH_ALIAS (node, ref)
    2867                 :             :     {
    2868                 :         664 :       cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    2869                 :         664 :       if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    2870                 :         664 :         set_noreturn_flag_1 (alias, noreturn_p, changed);
    2871                 :             :     }
    2872                 :             : 
    2873                 :       45001 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    2874                 :       17117 :     if (e->caller->thunk
    2875                 :       17117 :         && (!noreturn_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    2876                 :          20 :       set_noreturn_flag_1 (e->caller, noreturn_p, changed);
    2877                 :       27884 : }
    2878                 :             : 
    2879                 :             : /* Set TREE_THIS_VOLATILE on NODE's decl and on NODE's aliases if any.  */
    2880                 :             : 
    2881                 :             : bool
    2882                 :       27354 : cgraph_node::set_noreturn_flag (bool noreturn_p)
    2883                 :             : {
    2884                 :       27354 :   bool changed = false;
    2885                 :             : 
    2886                 :       27354 :   if (!noreturn_p || get_availability () > AVAIL_INTERPOSABLE)
    2887                 :       27191 :     set_noreturn_flag_1 (this, noreturn_p, &changed);
    2888                 :             :   else
    2889                 :             :     {
    2890                 :             :       ipa_ref *ref;
    2891                 :             : 
    2892                 :         180 :       FOR_EACH_ALIAS (this, ref)
    2893                 :             :         {
    2894                 :          17 :           cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    2895                 :          17 :           if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    2896                 :           9 :             set_noreturn_flag_1 (alias, noreturn_p, &changed);
    2897                 :             :         }
    2898                 :             :     }
    2899                 :       27354 :   return changed;
    2900                 :             : }
    2901                 :             : 
    2902                 :             : /* Worker to set_const_flag.  */
    2903                 :             : 
    2904                 :             : static void
    2905                 :     1061742 : set_const_flag_1 (cgraph_node *node, bool set_const, bool looping,
    2906                 :             :                   bool *changed)
    2907                 :             : {
    2908                 :             :   /* Static constructors and destructors without a side effect can be
    2909                 :             :      optimized out.  */
    2910                 :     1061742 :   if (set_const && !looping)
    2911                 :             :     {
    2912                 :     1055756 :       if (DECL_STATIC_CONSTRUCTOR (node->decl))
    2913                 :             :         {
    2914                 :         239 :           DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
    2915                 :         239 :           *changed = true;
    2916                 :             :         }
    2917                 :     1055756 :       if (DECL_STATIC_DESTRUCTOR (node->decl))
    2918                 :             :         {
    2919                 :           1 :           DECL_STATIC_DESTRUCTOR (node->decl) = 0;
    2920                 :           1 :           *changed = true;
    2921                 :             :         }
    2922                 :             :     }
    2923                 :     1061742 :   if (!set_const)
    2924                 :             :     {
    2925                 :        2193 :       if (TREE_READONLY (node->decl))
    2926                 :             :         {
    2927                 :         159 :           TREE_READONLY (node->decl) = 0;
    2928                 :         159 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    2929                 :         159 :           *changed = true;
    2930                 :             :         }
    2931                 :             :     }
    2932                 :             :   else
    2933                 :             :     {
    2934                 :             :       /* Consider function:
    2935                 :             : 
    2936                 :             :          bool a(int *p)
    2937                 :             :          {
    2938                 :             :            return *p==*p;
    2939                 :             :          }
    2940                 :             : 
    2941                 :             :          During early optimization we will turn this into:
    2942                 :             : 
    2943                 :             :          bool a(int *p)
    2944                 :             :          {
    2945                 :             :            return true;
    2946                 :             :          }
    2947                 :             : 
    2948                 :             :          Now if this function will be detected as CONST however when interposed
    2949                 :             :          it may end up being just pure.  We always must assume the worst
    2950                 :             :          scenario here.  */
    2951                 :     1059549 :       if (TREE_READONLY (node->decl))
    2952                 :             :         {
    2953                 :         731 :           if (!looping && DECL_LOOPING_CONST_OR_PURE_P (node->decl))
    2954                 :             :             {
    2955                 :         420 :               DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    2956                 :         420 :               *changed = true;
    2957                 :             :             }
    2958                 :             :         }
    2959                 :     1058818 :       else if (node->binds_to_current_def_p ())
    2960                 :             :         {
    2961                 :      168898 :           TREE_READONLY (node->decl) = true;
    2962                 :      168898 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
    2963                 :      168898 :           DECL_PURE_P (node->decl) = false;
    2964                 :      168898 :           *changed = true;
    2965                 :             :         }
    2966                 :             :       else
    2967                 :             :         {
    2968                 :      889920 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2969                 :           0 :             fprintf (dump_file, "Dropping state to PURE because function does "
    2970                 :             :                      "not bind to current def.\n");
    2971                 :      889920 :           if (!DECL_PURE_P (node->decl))
    2972                 :             :             {
    2973                 :      427099 :               DECL_PURE_P (node->decl) = true;
    2974                 :      427099 :               DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
    2975                 :      427099 :               *changed = true;
    2976                 :             :             }
    2977                 :      462821 :           else if (!looping && DECL_LOOPING_CONST_OR_PURE_P (node->decl))
    2978                 :             :             {
    2979                 :         143 :               DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    2980                 :         143 :               *changed = true;
    2981                 :             :             }
    2982                 :             :         }
    2983                 :             :     }
    2984                 :             : 
    2985                 :             :   ipa_ref *ref;
    2986                 :     1196055 :   FOR_EACH_ALIAS (node, ref)
    2987                 :             :     {
    2988                 :      134313 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2989                 :      134313 :       if (!set_const || alias->get_availability () > AVAIL_INTERPOSABLE)
    2990                 :      134250 :         set_const_flag_1 (alias, set_const, looping, changed);
    2991                 :             :     }
    2992                 :     1061838 :   for (struct cgraph_node *n = node->simd_clones; n != NULL;
    2993                 :          96 :        n = n->simdclone->next_clone)
    2994                 :          96 :     set_const_flag_1 (n, set_const, looping, changed);
    2995                 :     2777264 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    2996                 :     1715522 :     if (e->caller->thunk
    2997                 :     1715522 :         && (!set_const || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    2998                 :             :       {
    2999                 :             :         /* Virtual thunks access virtual offset in the vtable, so they can
    3000                 :             :            only be pure, never const.  */
    3001                 :         369 :         if (set_const
    3002                 :         369 :             && (thunk_info::get (e->caller)->virtual_offset_p
    3003                 :         238 :                 || !node->binds_to_current_def_p (e->caller)))
    3004                 :         131 :           *changed |= e->caller->set_pure_flag (true, looping);
    3005                 :             :         else
    3006                 :         238 :           set_const_flag_1 (e->caller, set_const, looping, changed);
    3007                 :             :       }
    3008                 :     1061742 : }
    3009                 :             : 
    3010                 :             : /* If SET_CONST is true, mark function, aliases and thunks to be ECF_CONST.
    3011                 :             :    If SET_CONST if false, clear the flag.
    3012                 :             : 
    3013                 :             :    When setting the flag be careful about possible interposition and
    3014                 :             :    do not set the flag for functions that can be interposed and set pure
    3015                 :             :    flag for functions that can bind to other definition.
    3016                 :             : 
    3017                 :             :    Return true if any change was done. */
    3018                 :             : 
    3019                 :             : bool
    3020                 :      952793 : cgraph_node::set_const_flag (bool set_const, bool looping)
    3021                 :             : {
    3022                 :      952793 :   bool changed = false;
    3023                 :      952793 :   if (!set_const || get_availability () > AVAIL_INTERPOSABLE)
    3024                 :      926971 :     set_const_flag_1 (this, set_const, looping, &changed);
    3025                 :             :   else
    3026                 :             :     {
    3027                 :             :       ipa_ref *ref;
    3028                 :             : 
    3029                 :       26693 :       FOR_EACH_ALIAS (this, ref)
    3030                 :             :         {
    3031                 :         871 :           cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    3032                 :         871 :           if (!set_const || alias->get_availability () > AVAIL_INTERPOSABLE)
    3033                 :         187 :             set_const_flag_1 (alias, set_const, looping, &changed);
    3034                 :             :         }
    3035                 :             :     }
    3036                 :      952793 :   return changed;
    3037                 :             : }
    3038                 :             : 
    3039                 :             : /* Info used by set_pure_flag_1.  */
    3040                 :             : 
    3041                 :             : struct set_pure_flag_info
    3042                 :             : {
    3043                 :             :   bool pure;
    3044                 :             :   bool looping;
    3045                 :             :   bool changed;
    3046                 :             : };
    3047                 :             : 
    3048                 :             : /* Worker to set_pure_flag.  */
    3049                 :             : 
    3050                 :             : static bool
    3051                 :      357172 : set_pure_flag_1 (cgraph_node *node, void *data)
    3052                 :             : {
    3053                 :      357172 :   struct set_pure_flag_info *info = (struct set_pure_flag_info *)data;
    3054                 :             :   /* Static constructors and destructors without a side effect can be
    3055                 :             :      optimized out.  */
    3056                 :      357172 :   if (info->pure && !info->looping)
    3057                 :             :     {
    3058                 :      292036 :       if (DECL_STATIC_CONSTRUCTOR (node->decl))
    3059                 :             :         {
    3060                 :           0 :           DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
    3061                 :           0 :           info->changed = true;
    3062                 :             :         }
    3063                 :      292036 :       if (DECL_STATIC_DESTRUCTOR (node->decl))
    3064                 :             :         {
    3065                 :           0 :           DECL_STATIC_DESTRUCTOR (node->decl) = 0;
    3066                 :           0 :           info->changed = true;
    3067                 :             :         }
    3068                 :             :     }
    3069                 :      357172 :   if (info->pure)
    3070                 :             :     {
    3071                 :      354979 :       if (!DECL_PURE_P (node->decl) && !TREE_READONLY (node->decl))
    3072                 :             :         {
    3073                 :      354411 :           DECL_PURE_P (node->decl) = true;
    3074                 :      354411 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = info->looping;
    3075                 :      354411 :           info->changed = true;
    3076                 :             :         }
    3077                 :         568 :       else if (DECL_LOOPING_CONST_OR_PURE_P (node->decl)
    3078                 :         568 :                && !info->looping)
    3079                 :             :         {
    3080                 :         290 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3081                 :         290 :           info->changed = true;
    3082                 :             :         }
    3083                 :             :     }
    3084                 :             :   else
    3085                 :             :     {
    3086                 :        2193 :       if (DECL_PURE_P (node->decl))
    3087                 :             :         {
    3088                 :          75 :           DECL_PURE_P (node->decl) = false;
    3089                 :          75 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3090                 :          75 :           info->changed = true;
    3091                 :             :         }
    3092                 :             :     }
    3093                 :      357172 :   return false;
    3094                 :             : }
    3095                 :             : 
    3096                 :             : /* Set DECL_PURE_P on cgraph_node's decl and on aliases of the node
    3097                 :             :    if any to PURE.
    3098                 :             : 
    3099                 :             :    When setting the flag, be careful about possible interposition.
    3100                 :             :    Return true if any change was done. */
    3101                 :             : 
    3102                 :             : bool
    3103                 :      367787 : cgraph_node::set_pure_flag (bool pure, bool looping)
    3104                 :             : {
    3105                 :      367787 :   struct set_pure_flag_info info = {pure, looping, false};
    3106                 :      367787 :   call_for_symbol_thunks_and_aliases (set_pure_flag_1, &info, !pure, true);
    3107                 :      367787 :   for (struct cgraph_node *n = simd_clones; n != NULL;
    3108                 :           0 :        n = n->simdclone->next_clone)
    3109                 :           0 :     set_pure_flag_1 (n, &info);
    3110                 :      367787 :   return info.changed;
    3111                 :             : }
    3112                 :             : 
    3113                 :             : /* Return true when cgraph_node cannot return or throw and thus
    3114                 :             :    it is safe to ignore its side effects for IPA analysis.  */
    3115                 :             : 
    3116                 :             : bool
    3117                 :    13990232 : cgraph_node::cannot_return_p (void)
    3118                 :             : {
    3119                 :    13990232 :   int flags = flags_from_decl_or_type (decl);
    3120                 :    13990232 :   if (!opt_for_fn (decl, flag_exceptions))
    3121                 :     4608462 :     return (flags & ECF_NORETURN) != 0;
    3122                 :             :   else
    3123                 :     9381770 :     return ((flags & (ECF_NORETURN | ECF_NOTHROW))
    3124                 :     9381770 :              == (ECF_NORETURN | ECF_NOTHROW));
    3125                 :             : }
    3126                 :             : 
    3127                 :             : /* Return true when call of edge cannot lead to return from caller
    3128                 :             :    and thus it is safe to ignore its side effects for IPA analysis
    3129                 :             :    when computing side effects of the caller.
    3130                 :             :    FIXME: We could actually mark all edges that have no reaching
    3131                 :             :    patch to the exit block or throw to get better results.  */
    3132                 :             : bool
    3133                 :     2934634 : cgraph_edge::cannot_lead_to_return_p (void)
    3134                 :             : {
    3135                 :     2934634 :   if (caller->cannot_return_p ())
    3136                 :             :     return true;
    3137                 :     2846224 :   if (indirect_unknown_callee)
    3138                 :             :     {
    3139                 :       94339 :       int flags = indirect_info->ecf_flags;
    3140                 :       94339 :       if (!opt_for_fn (caller->decl, flag_exceptions))
    3141                 :       19283 :         return (flags & ECF_NORETURN) != 0;
    3142                 :             :       else
    3143                 :       75056 :         return ((flags & (ECF_NORETURN | ECF_NOTHROW))
    3144                 :       75056 :                  == (ECF_NORETURN | ECF_NOTHROW));
    3145                 :             :     }
    3146                 :             :   else
    3147                 :     2751885 :     return callee->cannot_return_p ();
    3148                 :             : }
    3149                 :             : 
    3150                 :             : /* Return true if the edge after scaling it profile by SCALE
    3151                 :             :    may be considered hot.  */
    3152                 :             : 
    3153                 :             : bool
    3154                 :     5448706 : cgraph_edge::maybe_hot_p (sreal scale)
    3155                 :             : {
    3156                 :             :   /* Never consider calls in functions optimized for size hot.  */
    3157                 :     5448706 :   if (opt_for_fn (caller->decl, optimize_size))
    3158                 :             :     return false;
    3159                 :             : 
    3160                 :             :   /* If reliable IPA count is available, just use it.  */
    3161                 :     5398090 :   profile_count c = count.ipa ();
    3162                 :     5398090 :   if (c.reliable_p ())
    3163                 :      709595 :     return maybe_hot_count_p (NULL, c * scale);
    3164                 :             : 
    3165                 :             :   /* See if we can determine hotness using caller frequency.  */
    3166                 :     4688495 :   if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
    3167                 :     4685464 :       || (callee
    3168                 :     4015660 :           && callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
    3169                 :             :     return false;
    3170                 :     4681900 :   if (caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
    3171                 :     4681900 :       && (callee
    3172                 :     4012096 :           && callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
    3173                 :             :     return false;
    3174                 :             :   /* ??? This may make sense for hot functions determined by
    3175                 :             :      user attribute, but if function is hot by profile, it may
    3176                 :             :      contains non-hot calls.  In most practical cases this case
    3177                 :             :      is handled by the reliable ipa count above, but i.e. after
    3178                 :             :      inlining function with no profile to function with profile
    3179                 :             :      we get here.. */
    3180                 :     4628675 :   if (caller->frequency == NODE_FREQUENCY_HOT)
    3181                 :             :     return true;
    3182                 :             : 
    3183                 :             :   /* Use IPA count and if it s not available appy local heuristics.  */
    3184                 :     4628673 :   if (c.initialized_p ())
    3185                 :             :     {
    3186                 :             :       /* A special case; AFDO zero means that function may quite possibly
    3187                 :             :          be executed few times per execution.  If scale is large, we still
    3188                 :             :          want to consider the call hot.  */
    3189                 :           0 :       if (c.quality () == AFDO)
    3190                 :           0 :         c = c.force_nonzero ();
    3191                 :           0 :       return maybe_hot_count_p (NULL, c * scale);
    3192                 :             :     }
    3193                 :     4628673 :   if (!count.initialized_p ())
    3194                 :             :     return true;
    3195                 :     3423560 :   cgraph_node *where = caller->inlined_to ? caller->inlined_to : caller;
    3196                 :     3423560 :   if (!where->count.initialized_p ())
    3197                 :             :     return true;
    3198                 :     3423560 :   c = count * scale;
    3199                 :     3423560 :   if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE)
    3200                 :             :     {
    3201                 :       68057 :       if (c * 2 < where->count * 3)
    3202                 :             :         return false;
    3203                 :             :     }
    3204                 :     3355503 :   else if (c * param_hot_bb_frequency_fraction < where->count)
    3205                 :             :     return false;
    3206                 :             :   return true;
    3207                 :             : }
    3208                 :             : 
    3209                 :             : /* Return true if the edge may be considered hot.  */
    3210                 :             : 
    3211                 :             : bool
    3212                 :     2342357 : cgraph_edge::maybe_hot_p ()
    3213                 :             : {
    3214                 :     2342357 :   return maybe_hot_p (1);
    3215                 :             : }
    3216                 :             : 
    3217                 :             : /* Worker for cgraph_can_remove_if_no_direct_calls_p.  */
    3218                 :             : 
    3219                 :             : static bool
    3220                 :      818688 : nonremovable_p (cgraph_node *node, void *)
    3221                 :             : {
    3222                 :      818688 :   return !node->can_remove_if_no_direct_calls_and_refs_p ();
    3223                 :             : }
    3224                 :             : 
    3225                 :             : /* Return true if whole comdat group can be removed if there are no direct
    3226                 :             :    calls to THIS.  */
    3227                 :             : 
    3228                 :             : bool
    3229                 :     1034980 : cgraph_node::can_remove_if_no_direct_calls_p (bool will_inline)
    3230                 :             : {
    3231                 :     1034980 :   struct ipa_ref *ref;
    3232                 :             : 
    3233                 :             :   /* For local symbols or non-comdat group it is the same as
    3234                 :             :      can_remove_if_no_direct_calls_p.  */
    3235                 :     1034980 :   if (!externally_visible || !same_comdat_group)
    3236                 :             :     {
    3237                 :      824753 :       if (DECL_EXTERNAL (decl))
    3238                 :             :         return true;
    3239                 :      824753 :       if (address_taken)
    3240                 :             :         return false;
    3241                 :      791742 :       return !call_for_symbol_and_aliases (nonremovable_p, NULL, true);
    3242                 :             :     }
    3243                 :             : 
    3244                 :      210227 :   if (will_inline && address_taken)
    3245                 :             :     return false;
    3246                 :             : 
    3247                 :             :   /* Otherwise check if we can remove the symbol itself and then verify
    3248                 :             :      that only uses of the comdat groups are direct call to THIS
    3249                 :             :      or its aliases.   */
    3250                 :      210227 :   if (!can_remove_if_no_direct_calls_and_refs_p ())
    3251                 :             :     return false;
    3252                 :             : 
    3253                 :             :   /* Check that all refs come from within the comdat group.  */
    3254                 :      402536 :   for (int i = 0; iterate_referring (i, ref); i++)
    3255                 :      204594 :     if (ref->referring->get_comdat_group () != get_comdat_group ())
    3256                 :             :       return false;
    3257                 :             : 
    3258                 :      197942 :   struct cgraph_node *target = ultimate_alias_target ();
    3259                 :      197942 :   for (cgraph_node *next = dyn_cast<cgraph_node *> (same_comdat_group);
    3260                 :      602838 :        next != this; next = dyn_cast<cgraph_node *> (next->same_comdat_group))
    3261                 :             :     {
    3262                 :      213079 :       if (!externally_visible)
    3263                 :           0 :         continue;
    3264                 :      213079 :       if (!next->alias
    3265                 :      213079 :           && !next->can_remove_if_no_direct_calls_and_refs_p ())
    3266                 :             :         return false;
    3267                 :             : 
    3268                 :             :       /* If we see different symbol than THIS, be sure to check calls.  */
    3269                 :      213079 :       if (next->ultimate_alias_target () != target)
    3270                 :       23841 :         for (cgraph_edge *e = next->callers; e; e = e->next_caller)
    3271                 :        4271 :           if (e->caller->get_comdat_group () != get_comdat_group ()
    3272                 :        4271 :               || will_inline)
    3273                 :             :             return false;
    3274                 :             : 
    3275                 :             :       /* If function is not being inlined, we care only about
    3276                 :             :          references outside of the comdat group.  */
    3277                 :      211597 :       if (!will_inline)
    3278                 :      213455 :         for (int i = 0; next->iterate_referring (i, ref); i++)
    3279                 :       11007 :           if (ref->referring->get_comdat_group () != get_comdat_group ())
    3280                 :             :             return false;
    3281                 :             :     }
    3282                 :             :   return true;
    3283                 :             : }
    3284                 :             : 
    3285                 :             : /* Return true when function cgraph_node can be expected to be removed
    3286                 :             :    from program when direct calls in this compilation unit are removed.
    3287                 :             : 
    3288                 :             :    As a special case COMDAT functions are
    3289                 :             :    cgraph_can_remove_if_no_direct_calls_p while the are not
    3290                 :             :    cgraph_only_called_directly_p (it is possible they are called from other
    3291                 :             :    unit)
    3292                 :             : 
    3293                 :             :    This function behaves as cgraph_only_called_directly_p because eliminating
    3294                 :             :    all uses of COMDAT function does not make it necessarily disappear from
    3295                 :             :    the program unless we are compiling whole program or we do LTO.  In this
    3296                 :             :    case we know we win since dynamic linking will not really discard the
    3297                 :             :    linkonce section.  */
    3298                 :             : 
    3299                 :             : bool
    3300                 :     3167044 : cgraph_node::will_be_removed_from_program_if_no_direct_calls_p
    3301                 :             :          (bool will_inline)
    3302                 :             : {
    3303                 :     3167044 :   gcc_assert (!inlined_to);
    3304                 :     3167044 :   if (DECL_EXTERNAL (decl))
    3305                 :             :     return true;
    3306                 :             : 
    3307                 :     3167044 :   if (!in_lto_p && !flag_whole_program)
    3308                 :             :     {
    3309                 :             :       /* If the symbol is in comdat group, we need to verify that whole comdat
    3310                 :             :          group becomes unreachable.  Technically we could skip references from
    3311                 :             :          within the group, too.  */
    3312                 :     2915335 :       if (!only_called_directly_p ())
    3313                 :             :         return false;
    3314                 :      706210 :       if (same_comdat_group && externally_visible)
    3315                 :             :         {
    3316                 :           0 :           struct cgraph_node *target = ultimate_alias_target ();
    3317                 :             : 
    3318                 :           0 :           if (will_inline && address_taken)
    3319                 :             :             return true;
    3320                 :           0 :           for (cgraph_node *next = dyn_cast<cgraph_node *> (same_comdat_group);
    3321                 :           0 :                next != this;
    3322                 :           0 :                next = dyn_cast<cgraph_node *> (next->same_comdat_group))
    3323                 :             :             {
    3324                 :           0 :               if (!externally_visible)
    3325                 :           0 :                 continue;
    3326                 :           0 :               if (!next->alias
    3327                 :           0 :                   && !next->only_called_directly_p ())
    3328                 :             :                 return false;
    3329                 :             : 
    3330                 :             :               /* If we see different symbol than THIS,
    3331                 :             :                  be sure to check calls.  */
    3332                 :           0 :               if (next->ultimate_alias_target () != target)
    3333                 :           0 :                 for (cgraph_edge *e = next->callers; e; e = e->next_caller)
    3334                 :           0 :                   if (e->caller->get_comdat_group () != get_comdat_group ()
    3335                 :           0 :                       || will_inline)
    3336                 :             :                     return false;
    3337                 :             :             }
    3338                 :             :         }
    3339                 :      706210 :       return true;
    3340                 :             :     }
    3341                 :             :   else
    3342                 :      251709 :     return can_remove_if_no_direct_calls_p (will_inline);
    3343                 :             : }
    3344                 :             : 
    3345                 :             : 
    3346                 :             : /* Worker for cgraph_only_called_directly_p.  */
    3347                 :             : 
    3348                 :             : static bool
    3349                 :    15675838 : cgraph_not_only_called_directly_p_1 (cgraph_node *node, void *)
    3350                 :             : {
    3351                 :    15675838 :   return !node->only_called_directly_or_aliased_p ();
    3352                 :             : }
    3353                 :             : 
    3354                 :             : /* Return true when function cgraph_node and all its aliases are only called
    3355                 :             :    directly.
    3356                 :             :    i.e. it is not externally visible, address was not taken and
    3357                 :             :    it is not used in any other non-standard way.  */
    3358                 :             : 
    3359                 :             : bool
    3360                 :    15608607 : cgraph_node::only_called_directly_p (void)
    3361                 :             : {
    3362                 :    15608607 :   gcc_assert (ultimate_alias_target () == this);
    3363                 :    15608607 :   return !call_for_symbol_and_aliases (cgraph_not_only_called_directly_p_1,
    3364                 :    15608607 :                                        NULL, true);
    3365                 :             : }
    3366                 :             : 
    3367                 :             : 
    3368                 :             : /* Collect all callers of NODE.  Worker for collect_callers_of_node.  */
    3369                 :             : 
    3370                 :             : static bool
    3371                 :      126897 : collect_callers_of_node_1 (cgraph_node *node, void *data)
    3372                 :             : {
    3373                 :      126897 :   vec<cgraph_edge *> *redirect_callers = (vec<cgraph_edge *> *)data;
    3374                 :      126897 :   cgraph_edge *cs;
    3375                 :      126897 :   enum availability avail;
    3376                 :      126897 :   node->ultimate_alias_target (&avail);
    3377                 :             : 
    3378                 :      126897 :   if (avail > AVAIL_INTERPOSABLE)
    3379                 :      434506 :     for (cs = node->callers; cs != NULL; cs = cs->next_caller)
    3380                 :      307609 :       if (!cs->indirect_inlining_edge
    3381                 :      307609 :           && !cs->caller->thunk)
    3382                 :      307569 :         redirect_callers->safe_push (cs);
    3383                 :      126897 :   return false;
    3384                 :             : }
    3385                 :             : 
    3386                 :             : /* Collect all callers of cgraph_node and its aliases that are known to lead to
    3387                 :             :    cgraph_node (i.e. are not overwritable).  */
    3388                 :             : 
    3389                 :             : auto_vec<cgraph_edge *>
    3390                 :      124918 : cgraph_node::collect_callers (void)
    3391                 :             : {
    3392                 :      124918 :   auto_vec<cgraph_edge *> redirect_callers;
    3393                 :      124918 :   call_for_symbol_thunks_and_aliases (collect_callers_of_node_1,
    3394                 :             :                                     &redirect_callers, false);
    3395                 :      124918 :   return redirect_callers;
    3396                 :             : }
    3397                 :             : 
    3398                 :             : 
    3399                 :             : /* Return TRUE if NODE2 a clone of NODE or is equivalent to it.  Return
    3400                 :             :    optimistically true if this cannot be determined.  */
    3401                 :             : 
    3402                 :             : static bool
    3403                 :       33133 : clone_of_p (cgraph_node *node, cgraph_node *node2)
    3404                 :             : {
    3405                 :       33133 :   node = node->ultimate_alias_target ();
    3406                 :       33133 :   node2 = node2->ultimate_alias_target ();
    3407                 :             : 
    3408                 :       33133 :   if (node2->clone_of == node
    3409                 :        2600 :       || node2->former_clone_of == node->decl)
    3410                 :             :     return true;
    3411                 :             : 
    3412                 :        2662 :   if (!node->thunk && !node->former_thunk_p ())
    3413                 :             :     {
    3414                 :             :       while (node2
    3415                 :        7613 :              && node->decl != node2->decl
    3416                 :       12689 :              && node->decl != node2->former_clone_of)
    3417                 :        5075 :         node2 = node2->clone_of;
    3418                 :        2538 :       return node2 != NULL;
    3419                 :             :     }
    3420                 :             : 
    3421                 :             :   /* There are no virtual clones of thunks so check former_clone_of or if we
    3422                 :             :      might have skipped thunks because this adjustments are no longer
    3423                 :             :      necessary.  */
    3424                 :          62 :   while (node->thunk || node->former_thunk_p ())
    3425                 :             :     {
    3426                 :          62 :       if (!thunk_info::get (node)->this_adjusting)
    3427                 :             :         return false;
    3428                 :             :       /* In case of instrumented expanded thunks, which can have multiple calls
    3429                 :             :          in them, we do not know how to continue and just have to be
    3430                 :             :          optimistic.  The same applies if all calls have already been inlined
    3431                 :             :          into the thunk.  */
    3432                 :          62 :       if (!node->callees || node->callees->next_callee)
    3433                 :             :         return true;
    3434                 :          59 :       node = node->callees->callee->ultimate_alias_target ();
    3435                 :             : 
    3436                 :          59 :       clone_info *info = clone_info::get (node2);
    3437                 :          59 :       if (!info || !info->param_adjustments
    3438                 :         118 :           || info->param_adjustments->first_param_intact_p ())
    3439                 :           0 :         return false;
    3440                 :          59 :       if (node2->former_clone_of == node->decl
    3441                 :          59 :           || node2->former_clone_of == node->former_clone_of)
    3442                 :             :         return true;
    3443                 :             : 
    3444                 :             :       cgraph_node *n2 = node2;
    3445                 :           0 :       while (n2 && node->decl != n2->decl)
    3446                 :           0 :         n2 = n2->clone_of;
    3447                 :           0 :       if (n2)
    3448                 :             :         return true;
    3449                 :             :     }
    3450                 :             : 
    3451                 :             :   return false;
    3452                 :             : }
    3453                 :             : 
    3454                 :             : /* Verify edge count and frequency.  */
    3455                 :             : 
    3456                 :             : bool
    3457                 :   194681715 : cgraph_edge::verify_count ()
    3458                 :             : {
    3459                 :   194681715 :   bool error_found = false;
    3460                 :   194681715 :   if (!count.verify ())
    3461                 :             :     {
    3462                 :           0 :       error ("caller edge count invalid");
    3463                 :           0 :       error_found = true;
    3464                 :             :     }
    3465                 :   194681715 :   return error_found;
    3466                 :             : }
    3467                 :             : 
    3468                 :             : /* Switch to THIS_CFUN if needed and print STMT to stderr.  */
    3469                 :             : static void
    3470                 :           0 : cgraph_debug_gimple_stmt (function *this_cfun, gimple *stmt)
    3471                 :             : {
    3472                 :           0 :   bool fndecl_was_null = false;
    3473                 :             :   /* debug_gimple_stmt needs correct cfun */
    3474                 :           0 :   if (cfun != this_cfun)
    3475                 :           0 :     set_cfun (this_cfun);
    3476                 :             :   /* ...and an actual current_function_decl */
    3477                 :           0 :   if (!current_function_decl)
    3478                 :             :     {
    3479                 :           0 :       current_function_decl = this_cfun->decl;
    3480                 :           0 :       fndecl_was_null = true;
    3481                 :             :     }
    3482                 :           0 :   debug_gimple_stmt (stmt);
    3483                 :           0 :   if (fndecl_was_null)
    3484                 :           0 :     current_function_decl = NULL;
    3485                 :           0 : }
    3486                 :             : 
    3487                 :             : /* Verify that call graph edge corresponds to DECL from the associated
    3488                 :             :    statement.  Return true if the verification should fail.  */
    3489                 :             : 
    3490                 :             : bool
    3491                 :    96486791 : cgraph_edge::verify_corresponds_to_fndecl (tree decl)
    3492                 :             : {
    3493                 :    96486791 :   cgraph_node *node;
    3494                 :             : 
    3495                 :    96486791 :   if (!decl || callee->inlined_to)
    3496                 :             :     return false;
    3497                 :    92767571 :   if (symtab->state == LTO_STREAMING)
    3498                 :             :     return false;
    3499                 :    92767571 :   node = cgraph_node::get (decl);
    3500                 :             : 
    3501                 :             :   /* We do not know if a node from a different partition is an alias or what it
    3502                 :             :      aliases and therefore cannot do the former_clone_of check reliably.  When
    3503                 :             :      body_removed is set, we have lost all information about what was alias or
    3504                 :             :      thunk of and also cannot proceed.  */
    3505                 :    92767571 :   if (!node
    3506                 :    92671367 :       || node->body_removed
    3507                 :    91935164 :       || node->in_other_partition
    3508                 :    91935161 :       || callee->icf_merged
    3509                 :    91841487 :       || callee->in_other_partition)
    3510                 :             :     return false;
    3511                 :             : 
    3512                 :    91841487 :   node = node->ultimate_alias_target ();
    3513                 :             : 
    3514                 :             :   /* Optimizers can redirect unreachable calls or calls triggering undefined
    3515                 :             :      behavior to __builtin_unreachable or __builtin_unreachable trap.  */
    3516                 :             : 
    3517                 :    91841487 :   if (fndecl_built_in_p (callee->decl, BUILT_IN_UNREACHABLE,
    3518                 :             :                                        BUILT_IN_UNREACHABLE_TRAP))
    3519                 :             :     return false;
    3520                 :             : 
    3521                 :    89149899 :   if (callee->former_clone_of != node->decl
    3522                 :    89147160 :       && (node != callee->ultimate_alias_target ())
    3523                 :    89183032 :       && !clone_of_p (node, callee))
    3524                 :             :     return true;
    3525                 :             :   else
    3526                 :    89149899 :     return false;
    3527                 :             : }
    3528                 :             : 
    3529                 :             : /* Disable warnings about missing quoting in GCC diagnostics for
    3530                 :             :    the verification errors.  Their format strings don't follow GCC
    3531                 :             :    diagnostic conventions and the calls are ultimately followed by
    3532                 :             :    one to internal_error.  */
    3533                 :             : #if __GNUC__ >= 10
    3534                 :             : #  pragma GCC diagnostic push
    3535                 :             : #  pragma GCC diagnostic ignored "-Wformat-diag"
    3536                 :             : #endif
    3537                 :             : 
    3538                 :             : /* Verify consistency of speculative call in NODE corresponding to STMT
    3539                 :             :    and LTO_STMT_UID.  If INDIRECT is set, assume that it is the indirect
    3540                 :             :    edge of call sequence. Return true if error is found.
    3541                 :             : 
    3542                 :             :    This function is called to every component of indirect call (direct edges,
    3543                 :             :    indirect edge and refs).  To save duplicated work, do full testing only
    3544                 :             :    in that case.  */
    3545                 :             : static bool
    3546                 :      179560 : verify_speculative_call (struct cgraph_node *node, gimple *stmt,
    3547                 :             :                          unsigned int lto_stmt_uid,
    3548                 :             :                          struct cgraph_edge *indirect)
    3549                 :             : {
    3550                 :      179560 :   if (indirect == NULL)
    3551                 :             :     {
    3552                 :      155678 :       for (indirect = node->indirect_calls; indirect;
    3553                 :       35956 :            indirect = indirect->next_callee)
    3554                 :      155678 :         if (indirect->call_stmt == stmt
    3555                 :      119840 :             && indirect->lto_stmt_uid == lto_stmt_uid)
    3556                 :             :           break;
    3557                 :      119722 :       if (!indirect)
    3558                 :             :         {
    3559                 :           0 :           error ("missing indirect call in speculative call sequence");
    3560                 :           0 :           return true;
    3561                 :             :         }
    3562                 :      119722 :       if (!indirect->speculative)
    3563                 :             :         {
    3564                 :           0 :           error ("indirect call in speculative call sequence has no "
    3565                 :             :                  "speculative flag");
    3566                 :           0 :           return true;
    3567                 :             :         }
    3568                 :             :       return false;
    3569                 :             :     }
    3570                 :             : 
    3571                 :             :   /* Maximal number of targets.  We probably will never want to have more than
    3572                 :             :      this.  */
    3573                 :             :   const unsigned int num = 256;
    3574                 :             :   cgraph_edge *direct_calls[num];
    3575                 :             :   ipa_ref *refs[num];
    3576                 :             : 
    3577                 :    15378366 :   for (unsigned int i = 0; i < num; i++)
    3578                 :             :     {
    3579                 :    15318528 :       direct_calls[i] = NULL;
    3580                 :    15318528 :       refs[i] = NULL;
    3581                 :             :     }
    3582                 :             : 
    3583                 :       59838 :   cgraph_edge *first_call = NULL;
    3584                 :       59838 :   cgraph_edge *prev_call = NULL;
    3585                 :             : 
    3586                 :      338176 :   for (cgraph_edge *direct = node->callees; direct;
    3587                 :      278338 :        direct = direct->next_callee)
    3588                 :      278338 :     if (direct->call_stmt == stmt && direct->lto_stmt_uid == lto_stmt_uid)
    3589                 :             :       {
    3590                 :       59861 :         if (!first_call)
    3591                 :       59838 :           first_call = direct;
    3592                 :       59861 :         if (prev_call && direct != prev_call->next_callee)
    3593                 :             :           {
    3594                 :           0 :             error ("speculative edges are not adjacent");
    3595                 :           0 :             return true;
    3596                 :             :           }
    3597                 :       59861 :         prev_call = direct;
    3598                 :       59861 :         if (!direct->speculative)
    3599                 :             :           {
    3600                 :           0 :             error ("direct call to %s in speculative call sequence has no "
    3601                 :           0 :                    "speculative flag", direct->callee->dump_name ());
    3602                 :           0 :             return true;
    3603                 :             :           }
    3604                 :       59861 :         if (direct->speculative_id >= num)
    3605                 :             :           {
    3606                 :           0 :             error ("direct call to %s in speculative call sequence has "
    3607                 :             :                    "speculative_id %i out of range",
    3608                 :           0 :                    direct->callee->dump_name (), direct->speculative_id);
    3609                 :           0 :             return true;
    3610                 :             :           }
    3611                 :       59861 :         if (direct_calls[direct->speculative_id])
    3612                 :             :           {
    3613                 :           0 :             error ("duplicate direct call to %s in speculative call sequence "
    3614                 :             :                    "with speculative_id %i",
    3615                 :           0 :                    direct->callee->dump_name (), direct->speculative_id);
    3616                 :           0 :             return true;
    3617                 :             :           }
    3618                 :       59861 :         direct_calls[direct->speculative_id] = direct;
    3619                 :             :       }
    3620                 :             : 
    3621                 :       59838 :   if (first_call->call_stmt
    3622                 :       59838 :       && first_call != node->get_edge (first_call->call_stmt))
    3623                 :             :     {
    3624                 :           0 :       error ("call stmt hash does not point to first direct edge of "
    3625                 :             :              "speculative call sequence");
    3626                 :           0 :       return true;
    3627                 :             :     }
    3628                 :             : 
    3629                 :             :   ipa_ref *ref;
    3630                 :      185147 :   for (int i = 0; node->iterate_reference (i, ref); i++)
    3631                 :      125309 :     if (ref->speculative
    3632                 :       84411 :         && ref->stmt == stmt && ref->lto_stmt_uid == lto_stmt_uid)
    3633                 :             :       {
    3634                 :       59861 :         if (ref->speculative_id >= num)
    3635                 :             :           {
    3636                 :           0 :             error ("direct call to %s in speculative call sequence has "
    3637                 :             :                    "speculative_id %i out of range",
    3638                 :           0 :                    ref->referred->dump_name (), ref->speculative_id);
    3639                 :           0 :             return true;
    3640                 :             :           }
    3641                 :       59861 :         if (refs[ref->speculative_id])
    3642                 :             :           {
    3643                 :           0 :             error ("duplicate reference %s in speculative call sequence "
    3644                 :             :                    "with speculative_id %i",
    3645                 :           0 :                    ref->referred->dump_name (), ref->speculative_id);
    3646                 :           0 :             return true;
    3647                 :             :           }
    3648                 :       59861 :         refs[ref->speculative_id] = ref;
    3649                 :             :       }
    3650                 :             : 
    3651                 :             :   int num_targets = 0;
    3652                 :    15378366 :   for (unsigned int i = 0 ; i < num ; i++)
    3653                 :             :     {
    3654                 :    15318528 :       if (refs[i] && !direct_calls[i])
    3655                 :             :         {
    3656                 :           0 :           error ("missing direct call for speculation %i", i);
    3657                 :           0 :           return true;
    3658                 :             :         }
    3659                 :    15318528 :       if (!refs[i] && direct_calls[i])
    3660                 :             :         {
    3661                 :           0 :           error ("missing ref for speculation %i", i);
    3662                 :           0 :           return true;
    3663                 :             :         }
    3664                 :    15318528 :       if (refs[i] != NULL)
    3665                 :       59861 :         num_targets++;
    3666                 :             :     }
    3667                 :             : 
    3668                 :       59838 :   if (num_targets != indirect->num_speculative_call_targets_p ())
    3669                 :             :     {
    3670                 :           0 :       error ("number of speculative targets %i mismatched with "
    3671                 :             :              "num_speculative_call_targets %i",
    3672                 :             :              num_targets,
    3673                 :             :              indirect->num_speculative_call_targets_p ());
    3674                 :           0 :       return true;
    3675                 :             :     }
    3676                 :             :   return false;
    3677                 :             : }
    3678                 :             : 
    3679                 :             : /* Verify cgraph nodes of given cgraph node.  */
    3680                 :             : DEBUG_FUNCTION void
    3681                 :    51644960 : cgraph_node::verify_node (void)
    3682                 :             : {
    3683                 :    51644960 :   cgraph_edge *e;
    3684                 :    51644960 :   function *this_cfun = DECL_STRUCT_FUNCTION (decl);
    3685                 :    51644960 :   basic_block this_block;
    3686                 :    51644960 :   gimple_stmt_iterator gsi;
    3687                 :    51644960 :   bool error_found = false;
    3688                 :    51644960 :   int i;
    3689                 :    51644960 :   ipa_ref *ref = NULL;
    3690                 :             : 
    3691                 :    51644960 :   if (seen_error ())
    3692                 :    51644960 :     return;
    3693                 :             : 
    3694                 :    51644960 :   timevar_push (TV_CGRAPH_VERIFY);
    3695                 :    51644960 :   error_found |= verify_base ();
    3696                 :   155733427 :   for (e = callees; e; e = e->next_callee)
    3697                 :   104088467 :     if (e->aux)
    3698                 :             :       {
    3699                 :           0 :         error ("aux field set for edge %s->%s",
    3700                 :           0 :                identifier_to_locale (e->caller->name ()),
    3701                 :           0 :                identifier_to_locale (e->callee->name ()));
    3702                 :           0 :         error_found = true;
    3703                 :             :       }
    3704                 :    51644960 :   if (!count.verify ())
    3705                 :             :     {
    3706                 :           0 :       error ("cgraph count invalid");
    3707                 :           0 :       error_found = true;
    3708                 :             :     }
    3709                 :    51644960 :   if (inlined_to && same_comdat_group)
    3710                 :             :     {
    3711                 :           0 :       error ("inline clone in same comdat group list");
    3712                 :           0 :       error_found = true;
    3713                 :             :     }
    3714                 :    51644960 :   if (inlined_to && !count.compatible_p (inlined_to->count))
    3715                 :             :     {
    3716                 :           0 :       error ("inline clone count is not compatible");
    3717                 :           0 :       count.debug ();
    3718                 :           0 :       inlined_to->count.debug ();
    3719                 :           0 :       error_found = true;
    3720                 :             :     }
    3721                 :    51644960 :   if (tp_first_run < 0)
    3722                 :             :     {
    3723                 :           0 :       error ("tp_first_run must be non-negative");
    3724                 :           0 :       error_found = true;
    3725                 :             :     }
    3726                 :    51644960 :   if (!definition && !in_other_partition && local)
    3727                 :             :     {
    3728                 :           0 :       error ("local symbols must be defined");
    3729                 :           0 :       error_found = true;
    3730                 :             :     }
    3731                 :    51644960 :   if (inlined_to && externally_visible)
    3732                 :             :     {
    3733                 :           0 :       error ("externally visible inline clone");
    3734                 :           0 :       error_found = true;
    3735                 :             :     }
    3736                 :    51644960 :   if (inlined_to && address_taken)
    3737                 :             :     {
    3738                 :           0 :       error ("inline clone with address taken");
    3739                 :           0 :       error_found = true;
    3740                 :             :     }
    3741                 :    51644960 :   if (inlined_to && force_output)
    3742                 :             :     {
    3743                 :           0 :       error ("inline clone is forced to output");
    3744                 :           0 :       error_found = true;
    3745                 :             :     }
    3746                 :    51644960 :   if (symtab->state != LTO_STREAMING)
    3747                 :             :     {
    3748                 :    51536314 :       if (calls_comdat_local && !same_comdat_group)
    3749                 :             :         {
    3750                 :           0 :           error ("calls_comdat_local is set outside of a comdat group");
    3751                 :           0 :           error_found = true;
    3752                 :             :         }
    3753                 :    51536314 :       if (!inlined_to && calls_comdat_local != check_calls_comdat_local_p ())
    3754                 :             :         {
    3755                 :           0 :           error ("invalid calls_comdat_local flag");
    3756                 :           0 :           error_found = true;
    3757                 :             :         }
    3758                 :             :     }
    3759                 :    51644960 :   if (DECL_IS_MALLOC (decl)
    3760                 :    51644960 :       && !POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
    3761                 :             :     {
    3762                 :           0 :       error ("malloc attribute should be used for a function that "
    3763                 :             :              "returns a pointer");
    3764                 :           0 :       error_found = true;
    3765                 :             :     }
    3766                 :    51644960 :   if (definition
    3767                 :    34832892 :       && externally_visible
    3768                 :             :       /* For aliases in lto1 free_lang_data doesn't guarantee preservation
    3769                 :             :          of opt_for_fn (decl, flag_semantic_interposition).  See PR105399.  */
    3770                 :    18960825 :       && (!alias || !in_lto_p)
    3771                 :    51644960 :       && semantic_interposition
    3772                 :    18957907 :          != opt_for_fn (decl, flag_semantic_interposition))
    3773                 :             :     {
    3774                 :           0 :       error ("semantic interposition mismatch");
    3775                 :           0 :       error_found = true;
    3776                 :             :     }
    3777                 :    54020075 :   for (e = indirect_calls; e; e = e->next_callee)
    3778                 :             :     {
    3779                 :     2375115 :       if (e->aux)
    3780                 :             :         {
    3781                 :           0 :           error ("aux field set for indirect edge from %s",
    3782                 :           0 :                  identifier_to_locale (e->caller->name ()));
    3783                 :           0 :           error_found = true;
    3784                 :             :         }
    3785                 :     2375115 :       if (!e->count.compatible_p (count))
    3786                 :             :         {
    3787                 :           0 :           error ("edge count is not compatible with function count");
    3788                 :           0 :           e->count.debug ();
    3789                 :           0 :           count.debug ();
    3790                 :           0 :           error_found = true;
    3791                 :             :         }
    3792                 :     2375115 :       if (inlined_to && !e->count.compatible_p (inlined_to->count))
    3793                 :             :         {
    3794                 :           0 :           error ("edge count is not compatible with inlined to function count");
    3795                 :           0 :           e->count.debug ();
    3796                 :           0 :           count.debug ();
    3797                 :           0 :           error_found = true;
    3798                 :             :         }
    3799                 :     2375115 :       if (!e->indirect_unknown_callee
    3800                 :     2375115 :           || !e->indirect_info)
    3801                 :             :         {
    3802                 :           0 :           error ("An indirect edge from %s is not marked as indirect or has "
    3803                 :             :                  "associated indirect_info, the corresponding statement is: ",
    3804                 :           0 :                  identifier_to_locale (e->caller->name ()));
    3805                 :           0 :           cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    3806                 :           0 :           error_found = true;
    3807                 :             :         }
    3808                 :     2375115 :       if (e->call_stmt && e->lto_stmt_uid)
    3809                 :             :         {
    3810                 :           0 :           error ("edge has both call_stmt and lto_stmt_uid set");
    3811                 :           0 :           error_found = true;
    3812                 :             :         }
    3813                 :             :     }
    3814                 :    51644960 :   bool check_comdat = comdat_local_p ();
    3815                 :   139863093 :   for (e = callers; e; e = e->next_caller)
    3816                 :             :     {
    3817                 :    88218133 :       if (e->verify_count ())
    3818                 :           0 :         error_found = true;
    3819                 :    88218133 :       if (check_comdat
    3820                 :    88218133 :           && !in_same_comdat_group_p (e->caller))
    3821                 :             :         {
    3822                 :           0 :           error ("comdat-local function called by %s outside its comdat",
    3823                 :             :                  identifier_to_locale (e->caller->name ()));
    3824                 :           0 :           error_found = true;
    3825                 :             :         }
    3826                 :    88218133 :       if (!e->inline_failed)
    3827                 :             :         {
    3828                 :     8149143 :           if (inlined_to
    3829                 :     8149143 :               != (e->caller->inlined_to
    3830                 :     8149143 :                   ? e->caller->inlined_to : e->caller))
    3831                 :             :             {
    3832                 :           0 :               error ("inlined_to pointer is wrong");
    3833                 :           0 :               error_found = true;
    3834                 :             :             }
    3835                 :     8149143 :           if (callers->next_caller)
    3836                 :             :             {
    3837                 :           0 :               error ("multiple inline callers");
    3838                 :           0 :               error_found = true;
    3839                 :             :             }
    3840                 :             :         }
    3841                 :             :       else
    3842                 :    80068990 :         if (inlined_to)
    3843                 :             :           {
    3844                 :           0 :             error ("inlined_to pointer set for noninline callers");
    3845                 :           0 :             error_found = true;
    3846                 :             :           }
    3847                 :             :     }
    3848                 :   155733427 :   for (e = callees; e; e = e->next_callee)
    3849                 :             :     {
    3850                 :   104088467 :       if (e->verify_count ())
    3851                 :           0 :         error_found = true;
    3852                 :   104088467 :       if (!e->count.compatible_p (count))
    3853                 :             :         {
    3854                 :           0 :           error ("edge count is not compatible with function count");
    3855                 :           0 :           e->count.debug ();
    3856                 :           0 :           count.debug ();
    3857                 :           0 :           error_found = true;
    3858                 :             :         }
    3859                 :   104088467 :       if (gimple_has_body_p (e->caller->decl)
    3860                 :    98146143 :           && !e->caller->inlined_to
    3861                 :    89706912 :           && !e->speculative
    3862                 :             :           /* Optimized out calls are redirected to __builtin_unreachable.  */
    3863                 :    89687219 :           && (e->count.nonzero_p ()
    3864                 :    51329253 :               || ! e->callee->decl
    3865                 :    51329253 :               || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    3866                 :             :                                      BUILT_IN_UNREACHABLE_TRAP))
    3867                 :             :           && count
    3868                 :    88081420 :               == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
    3869                 :   192161925 :           && (!e->count.ipa_p ()
    3870                 :    40273238 :               && e->count.differs_from_p (gimple_bb (e->call_stmt)->count)))
    3871                 :             :         {
    3872                 :           0 :           error ("caller edge count does not match BB count");
    3873                 :           0 :           fprintf (stderr, "edge count: ");
    3874                 :           0 :           e->count.dump (stderr);
    3875                 :           0 :           fprintf (stderr, "\n bb count: ");
    3876                 :           0 :           gimple_bb (e->call_stmt)->count.dump (stderr);
    3877                 :           0 :           fprintf (stderr, "\n");
    3878                 :           0 :           error_found = true;
    3879                 :             :         }
    3880                 :   104088467 :       if (e->call_stmt && e->lto_stmt_uid)
    3881                 :             :         {
    3882                 :           0 :           error ("edge has both call_stmt and lto_stmt_uid set");
    3883                 :           0 :           error_found = true;
    3884                 :             :         }
    3885                 :   104088467 :       if (e->speculative
    3886                 :   104088467 :           && verify_speculative_call (e->caller, e->call_stmt, e->lto_stmt_uid,
    3887                 :             :                                       NULL))
    3888                 :             :         error_found = true;
    3889                 :             :     }
    3890                 :    54020075 :   for (e = indirect_calls; e; e = e->next_callee)
    3891                 :             :     {
    3892                 :     2375115 :       if (e->verify_count ())
    3893                 :           0 :         error_found = true;
    3894                 :     2375115 :       if (gimple_has_body_p (e->caller->decl)
    3895                 :     2322100 :           && !e->caller->inlined_to
    3896                 :     2073616 :           && !e->speculative
    3897                 :     2053929 :           && e->count.ipa_p ()
    3898                 :             :           && count
    3899                 :      754347 :               == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
    3900                 :     3129458 :           && (!e->count.ipa_p ()
    3901                 :           0 :               && e->count.differs_from_p (gimple_bb (e->call_stmt)->count)))
    3902                 :             :         {
    3903                 :           0 :           error ("indirect call count does not match BB count");
    3904                 :           0 :           fprintf (stderr, "edge count: ");
    3905                 :           0 :           e->count.dump (stderr);
    3906                 :           0 :           fprintf (stderr, "\n bb count: ");
    3907                 :           0 :           gimple_bb (e->call_stmt)->count.dump (stderr);
    3908                 :           0 :           fprintf (stderr, "\n");
    3909                 :           0 :           error_found = true;
    3910                 :             :         }
    3911                 :     2375115 :       if (e->speculative
    3912                 :     2375115 :           && verify_speculative_call (e->caller, e->call_stmt, e->lto_stmt_uid,
    3913                 :             :                                       e))
    3914                 :             :         error_found = true;
    3915                 :             :     }
    3916                 :   116782499 :   for (i = 0; iterate_reference (i, ref); i++)
    3917                 :             :     {
    3918                 :    65137539 :       if (ref->stmt && ref->lto_stmt_uid)
    3919                 :             :         {
    3920                 :           0 :           error ("reference has both stmt and lto_stmt_uid set");
    3921                 :           0 :           error_found = true;
    3922                 :             :         }
    3923                 :    65137539 :       if (ref->speculative
    3924                 :    65137539 :           && verify_speculative_call (this, ref->stmt,
    3925                 :             :                                       ref->lto_stmt_uid, NULL))
    3926                 :             :         error_found = true;
    3927                 :             :     }
    3928                 :             : 
    3929                 :    51644960 :   if (!callers && inlined_to)
    3930                 :             :     {
    3931                 :           0 :       error ("inlined_to pointer is set but no predecessors found");
    3932                 :           0 :       error_found = true;
    3933                 :             :     }
    3934                 :    51644960 :   if (inlined_to == this)
    3935                 :             :     {
    3936                 :           0 :       error ("inlined_to pointer refers to itself");
    3937                 :           0 :       error_found = true;
    3938                 :             :     }
    3939                 :             : 
    3940                 :    51644960 :   if (clone_of)
    3941                 :             :     {
    3942                 :     5884206 :       cgraph_node *first_clone = clone_of->clones;
    3943                 :     5884206 :       if (first_clone != this)
    3944                 :             :         {
    3945                 :     2987849 :           if (prev_sibling_clone->clone_of != clone_of)
    3946                 :             :             {
    3947                 :           0 :               error ("cgraph_node has wrong clone_of");
    3948                 :           0 :               error_found = true;
    3949                 :             :             }
    3950                 :             :         }
    3951                 :             :     }
    3952                 :    51644960 :   if (clones)
    3953                 :             :     {
    3954                 :             :       cgraph_node *n;
    3955                 :     8270035 :       for (n = clones; n; n = n->next_sibling_clone)
    3956                 :     6671165 :         if (n->clone_of != this)
    3957                 :             :           break;
    3958                 :     1598870 :       if (n)
    3959                 :             :         {
    3960                 :           0 :           error ("cgraph_node has wrong clone list");
    3961                 :           0 :           error_found = true;
    3962                 :             :         }
    3963                 :             :     }
    3964                 :    51644960 :   if ((prev_sibling_clone || next_sibling_clone) && !clone_of)
    3965                 :             :     {
    3966                 :           0 :        error ("cgraph_node is in clone list but it is not clone");
    3967                 :           0 :        error_found = true;
    3968                 :             :     }
    3969                 :    51644960 :   if (!prev_sibling_clone && clone_of && clone_of->clones != this)
    3970                 :             :     {
    3971                 :           0 :       error ("cgraph_node has wrong prev_clone pointer");
    3972                 :           0 :       error_found = true;
    3973                 :             :     }
    3974                 :    51644960 :   if (prev_sibling_clone && prev_sibling_clone->next_sibling_clone != this)
    3975                 :             :     {
    3976                 :           0 :       error ("double linked list of clones corrupted");
    3977                 :           0 :       error_found = true;
    3978                 :             :     }
    3979                 :             : 
    3980                 :    51644960 :   if (analyzed && alias)
    3981                 :             :     {
    3982                 :     1442728 :       bool ref_found = false;
    3983                 :     1442728 :       int i;
    3984                 :     1442728 :       ipa_ref *ref = NULL;
    3985                 :             : 
    3986                 :     1442728 :       if (callees)
    3987                 :             :         {
    3988                 :           0 :           error ("Alias has call edges");
    3989                 :           0 :           error_found = true;
    3990                 :             :         }
    3991                 :     2885456 :       for (i = 0; iterate_reference (i, ref); i++)
    3992                 :     1442728 :         if (ref->use != IPA_REF_ALIAS)
    3993                 :             :           {
    3994                 :           0 :             error ("Alias has non-alias reference");
    3995                 :           0 :             error_found = true;
    3996                 :             :           }
    3997                 :     1442728 :         else if (ref_found)
    3998                 :             :           {
    3999                 :           0 :             error ("Alias has more than one alias reference");
    4000                 :           0 :             error_found = true;
    4001                 :             :           }
    4002                 :             :         else
    4003                 :             :           ref_found = true;
    4004                 :     1442728 :       if (!ref_found)
    4005                 :             :         {
    4006                 :           0 :           error ("Analyzed alias has no reference");
    4007                 :           0 :           error_found = true;
    4008                 :             :         }
    4009                 :             :     }
    4010                 :             : 
    4011                 :    51644960 :   if (analyzed && thunk)
    4012                 :             :     {
    4013                 :       22078 :       if (!callees)
    4014                 :             :         {
    4015                 :           0 :           error ("No edge out of thunk node");
    4016                 :           0 :           error_found = true;
    4017                 :             :         }
    4018                 :       22078 :       else if (callees->next_callee)
    4019                 :             :         {
    4020                 :           0 :           error ("More than one edge out of thunk node");
    4021                 :           0 :           error_found = true;
    4022                 :             :         }
    4023                 :       22078 :       if (gimple_has_body_p (decl) && !inlined_to)
    4024                 :             :         {
    4025                 :           0 :           error ("Thunk is not supposed to have body");
    4026                 :           0 :           error_found = true;
    4027                 :             :         }
    4028                 :             :     }
    4029                 :    34808855 :   else if (analyzed && gimple_has_body_p (decl)
    4030                 :    30064337 :            && !TREE_ASM_WRITTEN (decl)
    4031                 :    30064337 :            && (!DECL_EXTERNAL (decl) || inlined_to)
    4032                 :    80815911 :            && !flag_wpa)
    4033                 :             :     {
    4034                 :    29166720 :       if ((this_cfun->curr_properties & PROP_assumptions_done) != 0)
    4035                 :             :         ;
    4036                 :    29166612 :       else if (this_cfun->cfg)
    4037                 :             :         {
    4038                 :    29166612 :           hash_set<gimple *> stmts;
    4039                 :             : 
    4040                 :             :           /* Reach the trees by walking over the CFG, and note the
    4041                 :             :              enclosing basic-blocks in the call edges.  */
    4042                 :   242724497 :           FOR_EACH_BB_FN (this_block, this_cfun)
    4043                 :             :             {
    4044                 :   213557885 :               for (gsi = gsi_start_phis (this_block);
    4045                 :   258756979 :                    !gsi_end_p (gsi); gsi_next (&gsi))
    4046                 :    45199094 :                 stmts.add (gsi_stmt (gsi));
    4047                 :   427115770 :               for (gsi = gsi_start_bb (this_block);
    4048                 :  1287713173 :                    !gsi_end_p (gsi);
    4049                 :  1074155288 :                    gsi_next (&gsi))
    4050                 :             :                 {
    4051                 :  1074155288 :                   gimple *stmt = gsi_stmt (gsi);
    4052                 :  1074155288 :                   stmts.add (stmt);
    4053                 :  1074155288 :                   if (is_gimple_call (stmt))
    4054                 :             :                     {
    4055                 :   102201839 :                       cgraph_edge *e = get_edge (stmt);
    4056                 :   102201839 :                       tree decl = gimple_call_fndecl (stmt);
    4057                 :   102201839 :                       if (e)
    4058                 :             :                         {
    4059                 :    98727110 :                           if (e->aux)
    4060                 :             :                             {
    4061                 :           0 :                               error ("shared call_stmt:");
    4062                 :           0 :                               cgraph_debug_gimple_stmt (this_cfun, stmt);
    4063                 :           0 :                               error_found = true;
    4064                 :             :                             }
    4065                 :    98727110 :                           if (!e->indirect_unknown_callee)
    4066                 :             :                             {
    4067                 :    96486791 :                               if (e->verify_corresponds_to_fndecl (decl))
    4068                 :             :                                 {
    4069                 :           0 :                                   error ("edge points to wrong declaration:");
    4070                 :           0 :                                   debug_tree (e->callee->decl);
    4071                 :           0 :                                   fprintf (stderr," Instead of:");
    4072                 :           0 :                                   debug_tree (decl);
    4073                 :           0 :                                   error_found = true;
    4074                 :             :                                 }
    4075                 :             :                             }
    4076                 :     2240319 :                           else if (decl)
    4077                 :             :                             {
    4078                 :           0 :                               error ("an indirect edge with unknown callee "
    4079                 :             :                                      "corresponding to a call_stmt with "
    4080                 :             :                                      "a known declaration:");
    4081                 :           0 :                               error_found = true;
    4082                 :           0 :                               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4083                 :             :                             }
    4084                 :    98727110 :                           e->aux = (void *)1;
    4085                 :             :                         }
    4086                 :     3474729 :                       else if (decl)
    4087                 :             :                         {
    4088                 :           0 :                           error ("missing callgraph edge for call stmt:");
    4089                 :           0 :                           cgraph_debug_gimple_stmt (this_cfun, stmt);
    4090                 :           0 :                           error_found = true;
    4091                 :             :                         }
    4092                 :             :                     }
    4093                 :             :                 }
    4094                 :             :               }
    4095                 :    98664056 :             for (i = 0; iterate_reference (i, ref); i++)
    4096                 :    60632484 :               if (ref->stmt && !stmts.contains (ref->stmt))
    4097                 :             :                 {
    4098                 :           0 :                   error ("reference to dead statement");
    4099                 :           0 :                   cgraph_debug_gimple_stmt (this_cfun, ref->stmt);
    4100                 :           0 :                   error_found = true;
    4101                 :             :                 }
    4102                 :    29166612 :         }
    4103                 :             :       else
    4104                 :             :         /* No CFG available?!  */
    4105                 :           0 :         gcc_unreachable ();
    4106                 :             : 
    4107                 :   125653518 :       for (e = callees; e; e = e->next_callee)
    4108                 :             :         {
    4109                 :    96486798 :           if (!e->aux && !e->speculative)
    4110                 :             :             {
    4111                 :           0 :               error ("edge %s->%s has no corresponding call_stmt",
    4112                 :           0 :                      identifier_to_locale (e->caller->name ()),
    4113                 :           0 :                      identifier_to_locale (e->callee->name ()));
    4114                 :           0 :               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4115                 :           0 :               error_found = true;
    4116                 :             :             }
    4117                 :    96486798 :           e->aux = 0;
    4118                 :             :         }
    4119                 :    31463691 :       for (e = indirect_calls; e; e = e->next_callee)
    4120                 :             :         {
    4121                 :     2296971 :           if (!e->aux && !e->speculative)
    4122                 :             :             {
    4123                 :           0 :               error ("an indirect edge from %s has no corresponding call_stmt",
    4124                 :           0 :                      identifier_to_locale (e->caller->name ()));
    4125                 :           0 :               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4126                 :           0 :               error_found = true;
    4127                 :             :             }
    4128                 :     2296971 :           e->aux = 0;
    4129                 :             :         }
    4130                 :             :     }
    4131                 :             : 
    4132                 :    51644960 :   if (nested_function_info *info = nested_function_info::get (this))
    4133                 :             :     {
    4134                 :           0 :       if (info->nested != NULL)
    4135                 :             :         {
    4136                 :           0 :           for (cgraph_node *n = info->nested; n != NULL;
    4137                 :           0 :                n = next_nested_function (n))
    4138                 :             :             {
    4139                 :           0 :               nested_function_info *ninfo = nested_function_info::get (n);
    4140                 :           0 :               if (ninfo->origin == NULL)
    4141                 :             :                 {
    4142                 :           0 :                   error ("missing origin for a node in a nested list");
    4143                 :           0 :                   error_found = true;
    4144                 :             :                 }
    4145                 :           0 :               else if (ninfo->origin != this)
    4146                 :             :                 {
    4147                 :           0 :                   error ("origin points to a different parent");
    4148                 :           0 :                   error_found = true;
    4149                 :           0 :                   break;
    4150                 :             :                 }
    4151                 :             :             }
    4152                 :             :         }
    4153                 :           0 :       if (info->next_nested != NULL && info->origin == NULL)
    4154                 :             :         {
    4155                 :           0 :           error ("missing origin for a node in a nested list");
    4156                 :           0 :           error_found = true;
    4157                 :             :         }
    4158                 :             :     }
    4159                 :             : 
    4160                 :    51644960 :   if (error_found)
    4161                 :             :     {
    4162                 :           0 :       dump (stderr);
    4163                 :           0 :       internal_error ("verify_cgraph_node failed");
    4164                 :             :     }
    4165                 :    51644960 :   timevar_pop (TV_CGRAPH_VERIFY);
    4166                 :             : }
    4167                 :             : 
    4168                 :             : /* Verify whole cgraph structure.  */
    4169                 :             : DEBUG_FUNCTION void
    4170                 :         854 : cgraph_node::verify_cgraph_nodes (void)
    4171                 :             : {
    4172                 :         854 :   cgraph_node *node;
    4173                 :             : 
    4174                 :         854 :   if (seen_error ())
    4175                 :             :     return;
    4176                 :             : 
    4177                 :       10430 :   FOR_EACH_FUNCTION (node)
    4178                 :        4385 :     node->verify ();
    4179                 :             : }
    4180                 :             : 
    4181                 :             : #if __GNUC__ >= 10
    4182                 :             : #  pragma GCC diagnostic pop
    4183                 :             : #endif
    4184                 :             : 
    4185                 :             : /* Walk the alias chain to return the function cgraph_node is alias of.
    4186                 :             :    Walk through thunks, too.
    4187                 :             :    When AVAILABILITY is non-NULL, get minimal availability in the chain.
    4188                 :             :    When REF is non-NULL, assume that reference happens in symbol REF
    4189                 :             :    when determining the availability.  */
    4190                 :             : 
    4191                 :             : cgraph_node *
    4192                 :   129423508 : cgraph_node::function_symbol (enum availability *availability,
    4193                 :             :                               struct symtab_node *ref)
    4194                 :             : {
    4195                 :   129423508 :   cgraph_node *node = ultimate_alias_target (availability, ref);
    4196                 :             : 
    4197                 :   258851363 :   while (node->thunk)
    4198                 :             :     {
    4199                 :        4347 :       enum availability a;
    4200                 :             : 
    4201                 :        4347 :       ref = node;
    4202                 :        4347 :       node = node->callees->callee;
    4203                 :        7898 :       node = node->ultimate_alias_target (availability ? &a : NULL, ref);
    4204                 :        4347 :       if (availability && a < *availability)
    4205                 :          38 :         *availability = a;
    4206                 :             :     }
    4207                 :   129423508 :   return node;
    4208                 :             : }
    4209                 :             : 
    4210                 :             : /* Walk the alias chain to return the function cgraph_node is alias of.
    4211                 :             :    Walk through non virtual thunks, too.  Thus we return either a function
    4212                 :             :    or a virtual thunk node.
    4213                 :             :    When AVAILABILITY is non-NULL, get minimal availability in the chain.
    4214                 :             :    When REF is non-NULL, assume that reference happens in symbol REF
    4215                 :             :    when determining the availability.  */
    4216                 :             : 
    4217                 :             : cgraph_node *
    4218                 :    32637515 : cgraph_node::function_or_virtual_thunk_symbol
    4219                 :             :                                 (enum availability *availability,
    4220                 :             :                                  struct symtab_node *ref)
    4221                 :             : {
    4222                 :    32637515 :   cgraph_node *node = ultimate_alias_target (availability, ref);
    4223                 :             : 
    4224                 :    65275973 :   while (node->thunk && !thunk_info::get (node)->virtual_offset_p)
    4225                 :             :     {
    4226                 :         943 :       enum availability a;
    4227                 :             : 
    4228                 :         943 :       ref = node;
    4229                 :         943 :       node = node->callees->callee;
    4230                 :         943 :       node = node->ultimate_alias_target (availability ? &a : NULL, ref);
    4231                 :         943 :       if (availability && a < *availability)
    4232                 :         311 :         *availability = a;
    4233                 :             :     }
    4234                 :    32637515 :   return node;
    4235                 :             : }
    4236                 :             : 
    4237                 :             : /* When doing LTO, read cgraph_node's body from disk if it is not already
    4238                 :             :    present.  Also perform any necessary clone materializations.  */
    4239                 :             : 
    4240                 :             : bool
    4241                 :     6119391 : cgraph_node::get_untransformed_body ()
    4242                 :             : {
    4243                 :     6119391 :   lto_file_decl_data *file_data;
    4244                 :     6119391 :   const char *data, *name;
    4245                 :     6119391 :   size_t len;
    4246                 :     6119391 :   tree decl = this->decl;
    4247                 :             : 
    4248                 :             :   /* See if there is clone to be materialized.
    4249                 :             :      (inline clones does not need materialization, but we can be seeing
    4250                 :             :       an inline clone of real clone).  */
    4251                 :     6119391 :   cgraph_node *p = this;
    4252                 :     8770006 :   for (cgraph_node *c = clone_of; c; c = c->clone_of)
    4253                 :             :     {
    4254                 :     2650615 :       if (c->decl != decl)
    4255                 :      124048 :         p->materialize_clone ();
    4256                 :     2650615 :       p = c;
    4257                 :             :     }
    4258                 :             : 
    4259                 :             :   /* Check if body is already there.  Either we have gimple body or
    4260                 :             :      the function is thunk and in that case we set DECL_ARGUMENTS.  */
    4261                 :     6119391 :   if (DECL_ARGUMENTS (decl) || gimple_has_body_p (decl))
    4262                 :     6036062 :     return false;
    4263                 :             : 
    4264                 :      166658 :   gcc_assert (in_lto_p && !DECL_RESULT (decl));
    4265                 :             : 
    4266                 :       83329 :   timevar_push (TV_IPA_LTO_GIMPLE_IN);
    4267                 :             : 
    4268                 :       83329 :   file_data = lto_file_data;
    4269                 :       83329 :   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    4270                 :             : 
    4271                 :             :   /* We may have renamed the declaration, e.g., a static function.  */
    4272                 :       83329 :   name = lto_get_decl_name_mapping (file_data, name);
    4273                 :       83329 :   struct lto_in_decl_state *decl_state
    4274                 :       83329 :          = lto_get_function_in_decl_state (file_data, decl);
    4275                 :             : 
    4276                 :       83329 :   cgraph_node *origin = this;
    4277                 :      166827 :   while (origin->clone_of)
    4278                 :             :     origin = origin->clone_of;
    4279                 :             : 
    4280                 :       83329 :   int stream_order = origin->order - file_data->order_base;
    4281                 :      166658 :   data = lto_get_section_data (file_data, LTO_section_function_body,
    4282                 :             :                                name, stream_order, &len,
    4283                 :       83329 :                                decl_state->compressed);
    4284                 :       83329 :   if (!data)
    4285                 :           0 :     fatal_error (input_location, "%s: section %s.%d is missing",
    4286                 :             :                  file_data->file_name, name, stream_order);
    4287                 :             : 
    4288                 :       83329 :   gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
    4289                 :             : 
    4290                 :       83329 :   if (!quiet_flag)
    4291                 :           0 :     fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
    4292                 :       83329 :   lto_input_function_body (file_data, this, data);
    4293                 :       83329 :   lto_stats.num_function_bodies++;
    4294                 :       83329 :   lto_free_section_data (file_data, LTO_section_function_body, name,
    4295                 :       83329 :                          data, len, decl_state->compressed);
    4296                 :       83329 :   lto_free_function_in_decl_state_for_node (this);
    4297                 :             :   /* Keep lto file data so ipa-inline-analysis knows about cross module
    4298                 :             :      inlining.  */
    4299                 :             : 
    4300                 :       83329 :   timevar_pop (TV_IPA_LTO_GIMPLE_IN);
    4301                 :             : 
    4302                 :       83329 :   return true;
    4303                 :             : }
    4304                 :             : 
    4305                 :             : /* Prepare function body.  When doing LTO, read cgraph_node's body from disk
    4306                 :             :    if it is not already present.  When some IPA transformations are scheduled,
    4307                 :             :    apply them.  */
    4308                 :             : 
    4309                 :             : bool
    4310                 :       28546 : cgraph_node::get_body (void)
    4311                 :             : {
    4312                 :       28546 :   bool updated;
    4313                 :             : 
    4314                 :       28546 :   updated = get_untransformed_body ();
    4315                 :             : 
    4316                 :             :   /* Getting transformed body makes no sense for inline clones;
    4317                 :             :      we should never use this on real clones because they are materialized
    4318                 :             :      early.
    4319                 :             :      TODO: Materializing clones here will likely lead to smaller LTRANS
    4320                 :             :      footprint. */
    4321                 :       28546 :   gcc_assert (!inlined_to && !clone_of);
    4322                 :       28546 :   if (ipa_transforms_to_apply.exists ())
    4323                 :             :     {
    4324                 :       12238 :       opt_pass *saved_current_pass = current_pass;
    4325                 :       12238 :       FILE *saved_dump_file = dump_file;
    4326                 :       12238 :       const char *saved_dump_file_name = dump_file_name;
    4327                 :       12238 :       dump_flags_t saved_dump_flags = dump_flags;
    4328                 :       12238 :       dump_file_name = NULL;
    4329                 :       12238 :       set_dump_file (NULL);
    4330                 :             : 
    4331                 :       12238 :       push_cfun (DECL_STRUCT_FUNCTION (decl));
    4332                 :             : 
    4333                 :       12238 :       update_ssa (TODO_update_ssa_only_virtuals);
    4334                 :       12238 :       execute_all_ipa_transforms (true);
    4335                 :       12238 :       cgraph_edge::rebuild_edges ();
    4336                 :       12238 :       free_dominance_info (CDI_DOMINATORS);
    4337                 :       12238 :       free_dominance_info (CDI_POST_DOMINATORS);
    4338                 :       12238 :       pop_cfun ();
    4339                 :       12238 :       updated = true;
    4340                 :             : 
    4341                 :       12238 :       current_pass = saved_current_pass;
    4342                 :       12238 :       set_dump_file (saved_dump_file);
    4343                 :       12238 :       dump_file_name = saved_dump_file_name;
    4344                 :       12238 :       dump_flags = saved_dump_flags;
    4345                 :             :     }
    4346                 :       28546 :   return updated;
    4347                 :             : }
    4348                 :             : 
    4349                 :             : /* Return the DECL_STRUCT_FUNCTION of the function.  */
    4350                 :             : 
    4351                 :             : struct function *
    4352                 :      218693 : cgraph_node::get_fun () const
    4353                 :             : {
    4354                 :      218693 :   const cgraph_node *node = this;
    4355                 :      218693 :   struct function *fun = DECL_STRUCT_FUNCTION (node->decl);
    4356                 :             : 
    4357                 :      218693 :   while (!fun && node->clone_of)
    4358                 :             :     {
    4359                 :           0 :       node = node->clone_of;
    4360                 :           0 :       fun = DECL_STRUCT_FUNCTION (node->decl);
    4361                 :             :     }
    4362                 :             : 
    4363                 :      218693 :   return fun;
    4364                 :             : }
    4365                 :             : 
    4366                 :             : /* Reset all state within cgraph.cc so that we can rerun the compiler
    4367                 :             :    within the same process.  For use by toplev::finalize.  */
    4368                 :             : 
    4369                 :             : void
    4370                 :      255947 : cgraph_cc_finalize (void)
    4371                 :             : {
    4372                 :      255947 :   nested_function_info::release ();
    4373                 :      255947 :   thunk_info::release ();
    4374                 :      255947 :   clone_info::release ();
    4375                 :      255947 :   symtab = NULL;
    4376                 :             : 
    4377                 :      255947 :   x_cgraph_nodes_queue = NULL;
    4378                 :             : 
    4379                 :      255947 :   cgraph_fnver_htab = NULL;
    4380                 :      255947 :   version_info_node = NULL;
    4381                 :      255947 : }
    4382                 :             : 
    4383                 :             : /* A worker for call_for_symbol_and_aliases.  */
    4384                 :             : 
    4385                 :             : bool
    4386                 :      731976 : cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
    4387                 :             :                                                               void *),
    4388                 :             :                                             void *data,
    4389                 :             :                                             bool include_overwritable)
    4390                 :             : {
    4391                 :      731976 :   ipa_ref *ref;
    4392                 :     1417112 :   FOR_EACH_ALIAS (this, ref)
    4393                 :             :     {
    4394                 :      784174 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    4395                 :      784174 :       if (include_overwritable
    4396                 :      784174 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
    4397                 :      784174 :         if (alias->call_for_symbol_and_aliases (callback, data,
    4398                 :             :                                                 include_overwritable))
    4399                 :             :           return true;
    4400                 :             :     }
    4401                 :             :   return false;
    4402                 :             : }
    4403                 :             : 
    4404                 :             : /* Return true if NODE has thunk.  */
    4405                 :             : 
    4406                 :             : bool
    4407                 :       39101 : cgraph_node::has_thunk_p (cgraph_node *node, void *)
    4408                 :             : {
    4409                 :       73252 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    4410                 :       34151 :     if (e->caller->thunk)
    4411                 :             :       return true;
    4412                 :             :   return false;
    4413                 :             : }
    4414                 :             : 
    4415                 :             : /* Expected frequency of executions within the function.  */
    4416                 :             : 
    4417                 :             : sreal
    4418                 :   200841468 : cgraph_edge::sreal_frequency ()
    4419                 :             : {
    4420                 :   200841468 :   return count.to_sreal_scale (caller->inlined_to
    4421                 :   200841468 :                                ? caller->inlined_to->count
    4422                 :   200841468 :                                : caller->count);
    4423                 :             : }
    4424                 :             : 
    4425                 :             : 
    4426                 :             : /* During LTO stream in this can be used to check whether call can possibly
    4427                 :             :    be internal to the current translation unit.  */
    4428                 :             : 
    4429                 :             : bool
    4430                 :      476308 : cgraph_edge::possibly_call_in_translation_unit_p (void)
    4431                 :             : {
    4432                 :      476308 :   gcc_checking_assert (in_lto_p && caller->prevailing_p ());
    4433                 :             : 
    4434                 :             :   /* While incremental linking we may end up getting function body later.  */
    4435                 :      476308 :   if (flag_incremental_link == INCREMENTAL_LINK_LTO)
    4436                 :             :     return true;
    4437                 :             : 
    4438                 :             :   /* We may be smarter here and avoid streaming in indirect calls we can't
    4439                 :             :      track, but that would require arranging streaming the indirect call
    4440                 :             :      summary first.  */
    4441                 :      476079 :   if (!callee)
    4442                 :             :     return true;
    4443                 :             : 
    4444                 :             :   /* If callee is local to the original translation unit, it will be
    4445                 :             :      defined.  */
    4446                 :      473375 :   if (!TREE_PUBLIC (callee->decl) && !DECL_EXTERNAL (callee->decl))
    4447                 :             :     return true;
    4448                 :             : 
    4449                 :             :   /* Otherwise we need to lookup prevailing symbol (symbol table is not merged,
    4450                 :             :      yet) and see if it is a definition.  In fact we may also resolve aliases,
    4451                 :             :      but that is probably not too important.  */
    4452                 :      477590 :   symtab_node *node = callee;
    4453                 :      477590 :   for (int n = 10; node->previous_sharing_asm_name && n ; n--)
    4454                 :       10096 :     node = node->previous_sharing_asm_name;
    4455                 :      467494 :   if (node->previous_sharing_asm_name)
    4456                 :         234 :     node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (callee->decl));
    4457                 :      467494 :   gcc_assert (TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
    4458                 :      467494 :   return node->get_availability () >= AVAIL_INTERPOSABLE;
    4459                 :             : }
    4460                 :             : 
    4461                 :             : /* Return num_speculative_targets of this edge.  */
    4462                 :             : 
    4463                 :             : int
    4464                 :       88651 : cgraph_edge::num_speculative_call_targets_p (void)
    4465                 :             : {
    4466                 :       88651 :   return indirect_info ? indirect_info->num_speculative_call_targets : 0;
    4467                 :             : }
    4468                 :             : 
    4469                 :             : /* Check if function calls comdat local.  This is used to recompute
    4470                 :             :    calls_comdat_local flag after function transformations.  */
    4471                 :             : bool
    4472                 :    48451481 : cgraph_node::check_calls_comdat_local_p ()
    4473                 :             : {
    4474                 :   155214810 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
    4475                 :     3697804 :     if (e->inline_failed
    4476                 :   115336434 :         ? e->callee->comdat_local_p ()
    4477                 :     3697804 :         : e->callee->check_calls_comdat_local_p ())
    4478                 :       50432 :       return true;
    4479                 :             :   return false;
    4480                 :             : }
    4481                 :             : 
    4482                 :             : /* Return true if this node represents a former, i.e. an expanded, thunk.  */
    4483                 :             : 
    4484                 :             : bool
    4485                 :     4921250 : cgraph_node::former_thunk_p (void)
    4486                 :             : {
    4487                 :     4921250 :   if (thunk)
    4488                 :             :     return false;
    4489                 :     4921250 :   thunk_info *i = thunk_info::get (this);
    4490                 :     4921250 :   if (!i)
    4491                 :             :     return false;
    4492                 :          73 :   gcc_checking_assert (i->fixed_offset || i->virtual_offset_p
    4493                 :             :                        || i->indirect_offset);
    4494                 :             :   return true;
    4495                 :             : }
    4496                 :             : 
    4497                 :             : /* A stashed copy of "symtab" for use by selftest::symbol_table_test.
    4498                 :             :    This needs to be a global so that it can be a GC root, and thus
    4499                 :             :    prevent the stashed copy from being garbage-collected if the GC runs
    4500                 :             :    during a symbol_table_test.  */
    4501                 :             : 
    4502                 :             : symbol_table *saved_symtab;
    4503                 :             : 
    4504                 :             : #if CHECKING_P
    4505                 :             : 
    4506                 :             : namespace selftest {
    4507                 :             : 
    4508                 :             : /* class selftest::symbol_table_test.  */
    4509                 :             : 
    4510                 :             : /* Constructor.  Store the old value of symtab, and create a new one.  */
    4511                 :             : 
    4512                 :          64 : symbol_table_test::symbol_table_test ()
    4513                 :             : {
    4514                 :          64 :   gcc_assert (saved_symtab == NULL);
    4515                 :          64 :   saved_symtab = symtab;
    4516                 :          64 :   symtab = new (ggc_alloc<symbol_table> ()) symbol_table ();
    4517                 :          64 : }
    4518                 :             : 
    4519                 :             : /* Destructor.  Restore the old value of symtab.  */
    4520                 :             : 
    4521                 :          64 : symbol_table_test::~symbol_table_test ()
    4522                 :             : {
    4523                 :          64 :   gcc_assert (saved_symtab != NULL);
    4524                 :          64 :   symtab = saved_symtab;
    4525                 :          64 :   saved_symtab = NULL;
    4526                 :          64 : }
    4527                 :             : 
    4528                 :             : /* Verify that symbol_table_test works.  */
    4529                 :             : 
    4530                 :             : static void
    4531                 :           4 : test_symbol_table_test ()
    4532                 :             : {
    4533                 :             :   /* Simulate running two selftests involving symbol tables.  */
    4534                 :          12 :   for (int i = 0; i < 2; i++)
    4535                 :             :     {
    4536                 :           8 :       symbol_table_test stt;
    4537                 :           8 :       tree test_decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
    4538                 :             :                                    get_identifier ("test_decl"),
    4539                 :             :                                    build_function_type_list (void_type_node,
    4540                 :             :                                                              NULL_TREE));
    4541                 :           8 :       cgraph_node *node = cgraph_node::get_create (test_decl);
    4542                 :           8 :       gcc_assert (node);
    4543                 :             : 
    4544                 :             :       /* Verify that the node has order 0 on both iterations,
    4545                 :             :          and thus that nodes have predictable dump names in selftests.  */
    4546                 :           8 :       ASSERT_EQ (node->order, 0);
    4547                 :           8 :       ASSERT_STREQ (node->dump_name (), "test_decl/1");
    4548                 :           8 :     }
    4549                 :           4 : }
    4550                 :             : 
    4551                 :             : /* Run all of the selftests within this file.  */
    4552                 :             : 
    4553                 :             : void
    4554                 :           4 : cgraph_cc_tests ()
    4555                 :             : {
    4556                 :           4 :   test_symbol_table_test ();
    4557                 :           4 : }
    4558                 :             : 
    4559                 :             : } // namespace selftest
    4560                 :             : 
    4561                 :             : #endif /* CHECKING_P */
    4562                 :             : 
    4563                 :             : #include "gt-cgraph.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.