LCOV - code coverage report
Current view: top level - gcc - cgraph.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 82.0 % 2346 1924
Test Date: 2026-02-28 14:20:25 Functions: 92.6 % 136 126
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Callgraph handling code.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              :    Contributed by Jan Hubicka
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : /*  This 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              : #include "attr-callback.h"
      73              : 
      74              : /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this.  */
      75              : #include "tree-pass.h"
      76              : 
      77              : /* Queue of cgraph nodes scheduled to be lowered.  */
      78              : symtab_node *x_cgraph_nodes_queue;
      79              : #define cgraph_nodes_queue ((cgraph_node *)x_cgraph_nodes_queue)
      80              : 
      81              : /* Symbol table global context.  */
      82              : symbol_table *symtab;
      83              : 
      84              : /* List of hooks triggered on cgraph_edge events.  */
      85              : struct cgraph_edge_hook_list {
      86              :   cgraph_edge_hook hook;
      87              :   void *data;
      88              :   struct cgraph_edge_hook_list *next;
      89              : };
      90              : 
      91              : /* List of hooks triggered on cgraph_node events.  */
      92              : struct cgraph_node_hook_list {
      93              :   cgraph_node_hook hook;
      94              :   void *data;
      95              :   struct cgraph_node_hook_list *next;
      96              : };
      97              : 
      98              : /* List of hooks triggered on events involving two cgraph_edges.  */
      99              : struct cgraph_2edge_hook_list {
     100              :   cgraph_2edge_hook hook;
     101              :   void *data;
     102              :   struct cgraph_2edge_hook_list *next;
     103              : };
     104              : 
     105              : /* List of hooks triggered on events involving two cgraph_nodes.  */
     106              : struct cgraph_2node_hook_list {
     107              :   cgraph_2node_hook hook;
     108              :   void *data;
     109              :   struct cgraph_2node_hook_list *next;
     110              : };
     111              : 
     112              : /* Hash descriptor for cgraph_function_version_info.  */
     113              : 
     114              : struct function_version_hasher : ggc_ptr_hash<cgraph_function_version_info>
     115              : {
     116              :   static hashval_t hash (cgraph_function_version_info *);
     117              :   static bool equal (cgraph_function_version_info *,
     118              :                      cgraph_function_version_info *);
     119              : };
     120              : 
     121              : /* Map a cgraph_node to cgraph_function_version_info using this htab.
     122              :    The cgraph_function_version_info has a THIS_NODE field that is the
     123              :    corresponding cgraph_node..  */
     124              : 
     125              : static GTY(()) hash_table<function_version_hasher> *cgraph_fnver_htab = NULL;
     126              : 
     127              : /* Hash function for cgraph_fnver_htab.  */
     128              : hashval_t
     129       290189 : function_version_hasher::hash (cgraph_function_version_info *ptr)
     130              : {
     131       290189 :   int uid = ptr->this_node->get_uid ();
     132       290189 :   return (hashval_t)(uid);
     133              : }
     134              : 
     135              : /* eq function for cgraph_fnver_htab.  */
     136              : bool
     137       263184 : function_version_hasher::equal (cgraph_function_version_info *n1,
     138              :                                 cgraph_function_version_info *n2)
     139              : {
     140       263184 :   return n1->this_node->get_uid () == n2->this_node->get_uid ();
     141              : }
     142              : 
     143              : /* Mark as GC root all allocated nodes.  */
     144              : static GTY(()) struct cgraph_function_version_info *
     145              :   version_info_node = NULL;
     146              : 
     147              : /* Return true if NODE's address can be compared.  */
     148              : 
     149              : bool
     150      5016391 : symtab_node::address_can_be_compared_p ()
     151              : {
     152              :   /* Address of virtual tables and functions is never compared.  */
     153      5016391 :   if (DECL_VIRTUAL_P (decl))
     154              :     return false;
     155              :   /* Address of C++ cdtors is never compared.  */
     156      4925411 :   if (is_a <cgraph_node *> (this)
     157       543403 :       && (DECL_CXX_CONSTRUCTOR_P (decl)
     158       539116 :           || DECL_CXX_DESTRUCTOR_P (decl)))
     159              :     return false;
     160              :   /* Constant pool symbols addresses are never compared.
     161              :      flag_merge_constants permits us to assume the same on readonly vars.  */
     162      4919760 :   if (is_a <varpool_node *> (this)
     163      4382008 :       && (DECL_IN_CONSTANT_POOL (decl)
     164      4382005 :           || ((flag_merge_constants >= 2 || DECL_MERGEABLE (decl))
     165         2072 :               && TREE_READONLY (decl) && !TREE_THIS_VOLATILE (decl))))
     166         2068 :     return false;
     167              :   return true;
     168              : }
     169              : 
     170              : /* Get the cgraph_function_version_info node corresponding to node.  */
     171              : cgraph_function_version_info *
     172    131918787 : cgraph_node::function_version (void)
     173              : {
     174    131918787 :   cgraph_function_version_info key;
     175    131918787 :   key.this_node = this;
     176              : 
     177    131918787 :   if (cgraph_fnver_htab == NULL)
     178              :     return NULL;
     179              : 
     180        46460 :   return cgraph_fnver_htab->find (&key);
     181              : }
     182              : 
     183              : /* If profile is IPA, turn it into local one.  */
     184              : void
     185            0 : cgraph_node::make_profile_local ()
     186              : {
     187            0 :   if (!count.ipa ().initialized_p ())
     188              :     return;
     189            0 :   if (!(count == profile_count::zero ()))
     190            0 :     count = count.guessed_local ();
     191            0 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
     192              :     {
     193            0 :       if (!e->inline_failed)
     194            0 :         e->callee->make_profile_local ();
     195            0 :       if (!(e->count == profile_count::zero ()))
     196            0 :         e->count = e->count.guessed_local ();
     197              :     }
     198            0 :   for (cgraph_edge *e = indirect_calls; e; e = e->next_callee)
     199            0 :     if (!(e->count == profile_count::zero ()))
     200            0 :       e->count = e->count.guessed_local ();
     201              : }
     202              : 
     203              : /* Turn profile to global0.  Walk into inlined functions.
     204              :    QUALITY must be GUESSED_GLOBAL0, GUESSED_GLOBAL0_ADJUSTED
     205              :    or GUESSED_GLOBAL0_AFDO  */
     206              : void
     207            5 : cgraph_node::make_profile_global0 (profile_quality quality)
     208              : {
     209            5 :   if (count == profile_count::zero ())
     210              :     ;
     211            5 :   else if (quality == GUESSED_GLOBAL0)
     212              :     {
     213            5 :       if (count.quality () == GUESSED_GLOBAL0)
     214              :         return;
     215            5 :       count = count.global0 ();
     216              :     }
     217            0 :   else if (quality == GUESSED_GLOBAL0_ADJUSTED)
     218              :     {
     219            0 :       if (count.quality () == GUESSED_GLOBAL0
     220            0 :           || count.quality () == GUESSED_GLOBAL0_ADJUSTED)
     221              :         return;
     222            0 :       count = count.global0adjusted ();
     223              :     }
     224            0 :   else if (quality == GUESSED_GLOBAL0_AFDO)
     225              :     {
     226            0 :       if (count.quality () == GUESSED_GLOBAL0
     227            0 :           || count.quality () == GUESSED_GLOBAL0_ADJUSTED
     228            0 :           || count.quality () == GUESSED_GLOBAL0_AFDO)
     229              :         return;
     230            0 :       count = count.global0afdo ();
     231              :     }
     232              :   else
     233            0 :     gcc_unreachable ();
     234            6 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
     235              :     {
     236            1 :       if (!e->inline_failed)
     237            0 :         e->callee->make_profile_global0 (quality);
     238            1 :       if (e->count == profile_count::zero ())
     239              :         ;
     240            1 :       else if (quality == GUESSED_GLOBAL0)
     241            1 :         e->count = e->count.global0 ();
     242            0 :       else if (quality == GUESSED_GLOBAL0_ADJUSTED)
     243            0 :         e->count = e->count.global0adjusted ();
     244            0 :       else if (quality == GUESSED_GLOBAL0_AFDO)
     245            0 :         e->count = e->count.global0afdo ();
     246              :       else
     247            0 :         gcc_unreachable ();
     248              :     }
     249            5 :   for (cgraph_edge *e = indirect_calls; e; e = e->next_callee)
     250            0 :     if (e->count == profile_count::zero ())
     251              :       ;
     252            0 :     else if (quality == GUESSED_GLOBAL0)
     253            0 :       e->count = e->count.global0 ();
     254            0 :     else if (quality == GUESSED_GLOBAL0_ADJUSTED)
     255            0 :       e->count = e->count.global0adjusted ();
     256            0 :     else if (quality == GUESSED_GLOBAL0_AFDO)
     257            0 :       e->count = e->count.global0afdo ();
     258              :     else
     259            0 :       gcc_unreachable ();
     260              : }
     261              : 
     262              : /* Scale profile by NUM/DEN.  Walk into inlined functions.  */
     263              : 
     264              : void
     265      1578605 : cgraph_node::apply_scale (profile_count num, profile_count den)
     266              : {
     267      1699378 :   if (num == den && !(num == profile_count::zero ()))
     268       119412 :     return;
     269              : 
     270      2736321 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
     271              :     {
     272      1277128 :       if (!e->inline_failed)
     273       169799 :         e->callee->apply_scale (num, den);
     274      1277128 :       e->count = e->count.apply_scale (num, den);
     275              :     }
     276      1486706 :   for (cgraph_edge *e = indirect_calls; e; e = e->next_callee)
     277        27513 :     e->count = e->count.apply_scale (num, den);
     278      1459193 :   count = count.apply_scale (num, den);
     279              : }
     280              : 
     281              : /* Scale profile to given IPA_COUNT.
     282              :    IPA_COUNT should pass ipa_p () with a single exception.
     283              :    It can be also GUESSED_LOCAL in case we want to
     284              :    drop any IPA info about the profile.  */
     285              : 
     286              : void
     287           30 : cgraph_node::scale_profile_to (profile_count ipa_count)
     288              : {
     289              :   /* If we do not know the adjustment, it is better to keep profile
     290              :      as it is.  */
     291           30 :   if (!ipa_count.initialized_p ()
     292           30 :       || ipa_count == count)
     293           10 :     return;
     294              :   /* ipa-cp converts value to guessed-local in case it believes
     295              :      that we lost track of IPA profile.  */
     296           25 :   if (ipa_count.quality () == GUESSED_LOCAL)
     297              :     {
     298            0 :       make_profile_local ();
     299            0 :       return;
     300              :     }
     301           25 :   if (ipa_count == profile_count::zero ())
     302              :     {
     303            5 :       make_profile_global0 (GUESSED_GLOBAL0);
     304            5 :       return;
     305              :     }
     306           20 :   if (ipa_count == profile_count::adjusted_zero ())
     307              :     {
     308            0 :       make_profile_global0 (GUESSED_GLOBAL0_ADJUSTED);
     309            0 :       return;
     310              :     }
     311           40 :   gcc_assert (ipa_count.ipa () == ipa_count
     312              :               && !inlined_to);
     313           20 :   profile_count num = count.combine_with_ipa_count (ipa_count);
     314           20 :   profile_count den = count;
     315           20 :   profile_count::adjust_for_ipa_scaling (&num, &den);
     316              : }
     317              : 
     318              : /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
     319              :    corresponding to cgraph_node NODE.  */
     320              : cgraph_function_version_info *
     321         1526 : cgraph_node::insert_new_function_version (void)
     322              : {
     323         1526 :   version_info_node = NULL;
     324         1526 :   version_info_node = ggc_cleared_alloc<cgraph_function_version_info> ();
     325         1526 :   version_info_node->this_node = this;
     326         1526 :   version_info_node->assembler_name = DECL_ASSEMBLER_NAME (this->decl);
     327              : 
     328         1526 :   if (cgraph_fnver_htab == NULL)
     329          197 :     cgraph_fnver_htab = hash_table<function_version_hasher>::create_ggc (2);
     330              : 
     331         1526 :   *cgraph_fnver_htab->find_slot (version_info_node, INSERT)
     332         1526 :     = version_info_node;
     333         1526 :   return version_info_node;
     334              : }
     335              : 
     336              : /* Remove the cgraph_function_version_info node given by DECL_V.  */
     337              : void
     338    112339513 : cgraph_node::delete_function_version (cgraph_function_version_info *decl_v)
     339              : {
     340    112339513 :   if (decl_v == NULL)
     341              :     return;
     342              : 
     343          268 :   if (version_info_node == decl_v)
     344          205 :     version_info_node = NULL;
     345              : 
     346          268 :   if (decl_v->prev != NULL)
     347          162 :     decl_v->prev->next = decl_v->next;
     348              : 
     349          268 :   if (decl_v->next != NULL)
     350          226 :     decl_v->next->prev = decl_v->prev;
     351              : 
     352          268 :   if (cgraph_fnver_htab != NULL)
     353          268 :     cgraph_fnver_htab->remove_elt (decl_v);
     354              : }
     355              : 
     356              : /* Remove the cgraph_function_version_info and cgraph_node for DECL.  This
     357              :    DECL is a duplicate declaration.  */
     358              : void
     359          258 : cgraph_node::delete_function_version_by_decl (tree decl)
     360              : {
     361          258 :   cgraph_node *decl_node = cgraph_node::get (decl);
     362              : 
     363          258 :   if (decl_node == NULL)
     364              :     return;
     365              : 
     366          204 :   delete_function_version (decl_node->function_version ());
     367              : 
     368          204 :   decl_node->remove ();
     369              : }
     370              : 
     371              : /* Add decl to the structure of semantically identical function versions.
     372              :    The node is inserted at the point maintaining the priority ordering on the
     373              :    versions.  */
     374              : void
     375         8944 : cgraph_node::add_function_version (cgraph_function_version_info *fn_v,
     376              :                                    tree decl)
     377              : {
     378         8944 :   cgraph_node *decl_node = cgraph_node::get_create (decl);
     379         8944 :   cgraph_function_version_info *decl_v = NULL;
     380              : 
     381         8944 :   gcc_assert (decl_node != NULL);
     382              : 
     383         8944 :   decl_v = decl_node->function_version ();
     384              : 
     385              :   /* If the nodes are already linked, skip.  */
     386         8944 :   if (decl_v != NULL && (decl_v->next || decl_v->prev))
     387              :     return;
     388              : 
     389          175 :   if (decl_v == NULL)
     390          175 :     decl_v = decl_node->insert_new_function_version ();
     391              : 
     392          175 :   gcc_assert (decl_v);
     393         1060 :   gcc_assert (fn_v);
     394              : 
     395              :   /* Go to start of the FMV structure.  */
     396         5542 :   while (fn_v->prev)
     397              :     fn_v = fn_v->prev;
     398              : 
     399         1060 :   cgraph_function_version_info *insert_point_before = NULL;
     400         1060 :   cgraph_function_version_info *insert_point_after = fn_v;
     401              : 
     402              :   /* Find the insertion point for the new version to maintain ordering.
     403              :      The default node must always go at the beginning.  */
     404         1060 :   if (!is_function_default_version (decl))
     405              :     while (insert_point_after
     406        10053 :            && (targetm.compare_version_priority
     407         4835 :                  (decl, insert_point_after->this_node->decl) > 0
     408          699 :                || is_function_default_version
     409          699 :                     (insert_point_after->this_node->decl)
     410          578 :                || lookup_attribute
     411          578 :                     ("target_clones",
     412          578 :                      DECL_ATTRIBUTES (insert_point_after->this_node->decl))))
     413              :       {
     414         4257 :         insert_point_before = insert_point_after;
     415         4257 :         insert_point_after = insert_point_after->next;
     416              :       }
     417              : 
     418         1060 :   decl_v->prev = insert_point_before;
     419         1060 :   decl_v->next= insert_point_after;
     420              : 
     421         1060 :   if (insert_point_before)
     422          925 :     insert_point_before->next = decl_v;
     423         1060 :   if (insert_point_after)
     424          677 :     insert_point_after->prev = decl_v;
     425              : }
     426              : 
     427              : /* Initialize callgraph dump file.  */
     428              : 
     429              : void
     430       299030 : symbol_table::initialize (void)
     431              : {
     432       299030 :   if (!dump_file)
     433       299028 :     dump_file = dump_begin (TDI_cgraph, NULL);
     434              : 
     435       299030 :   if (!ipa_clones_dump_file)
     436       299030 :     ipa_clones_dump_file = dump_begin (TDI_clones, NULL);
     437       299030 : }
     438              : 
     439              : /* Allocate new callgraph node and insert it into basic data structures.  */
     440              : 
     441              : cgraph_node *
     442    116071793 : symbol_table::create_empty (void)
     443              : {
     444    116071793 :   cgraph_count++;
     445    116071793 :   return new (ggc_alloc<cgraph_node> ()) cgraph_node ();
     446              : }
     447              : 
     448              : /* Register HOOK to be called with DATA on each removed edge.  */
     449              : cgraph_edge_hook_list *
     450      1891482 : symbol_table::add_edge_removal_hook (cgraph_edge_hook hook, void *data)
     451              : {
     452      1891482 :   cgraph_edge_hook_list *entry;
     453      3782964 :   cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
     454              : 
     455      1891482 :   entry = (cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
     456      1891482 :   entry->hook = hook;
     457      1891482 :   entry->data = data;
     458      1891482 :   entry->next = NULL;
     459      6556158 :   while (*ptr)
     460      4664676 :     ptr = &(*ptr)->next;
     461      1891482 :   *ptr = entry;
     462      1891482 :   return entry;
     463              : }
     464              : 
     465              : /* Remove ENTRY from the list of hooks called on removing edges.  */
     466              : void
     467      1891468 : symbol_table::remove_edge_removal_hook (cgraph_edge_hook_list *entry)
     468              : {
     469      1891468 :   cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
     470              : 
     471      5164071 :   while (*ptr != entry)
     472      3272603 :     ptr = &(*ptr)->next;
     473      1891468 :   *ptr = entry->next;
     474      1891468 :   free (entry);
     475      1891468 : }
     476              : 
     477              : /* Call all edge removal hooks.  */
     478              : void
     479     44275174 : symbol_table::call_edge_removal_hooks (cgraph_edge *e)
     480              : {
     481     44275174 :   cgraph_edge_hook_list *entry = m_first_edge_removal_hook;
     482     72397913 :   while (entry)
     483              :   {
     484     28122739 :     entry->hook (e, entry->data);
     485     28122739 :     entry = entry->next;
     486              :   }
     487     44275174 : }
     488              : 
     489              : /* Register HOOK to be called with DATA on each removed node.  */
     490              : cgraph_node_hook_list *
     491      7932915 : symbol_table::add_cgraph_removal_hook (cgraph_node_hook hook, void *data)
     492              : {
     493      7932915 :   cgraph_node_hook_list *entry;
     494     15865830 :   cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
     495              : 
     496      7932915 :   entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
     497      7932915 :   entry->hook = hook;
     498      7932915 :   entry->data = data;
     499      7932915 :   entry->next = NULL;
     500     41318656 :   while (*ptr)
     501     33385741 :     ptr = &(*ptr)->next;
     502      7932915 :   *ptr = entry;
     503      7932915 :   return entry;
     504              : }
     505              : 
     506              : /* Remove ENTRY from the list of hooks called on removing nodes.  */
     507              : void
     508      7823907 : symbol_table::remove_cgraph_removal_hook (cgraph_node_hook_list *entry)
     509              : {
     510      7823907 :   cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
     511              : 
     512     36783337 :   while (*ptr != entry)
     513     28959430 :     ptr = &(*ptr)->next;
     514      7823907 :   *ptr = entry->next;
     515      7823907 :   free (entry);
     516      7823907 : }
     517              : 
     518              : /* Call all node removal hooks.  */
     519              : void
     520    112372018 : symbol_table::call_cgraph_removal_hooks (cgraph_node *node)
     521              : {
     522    112372018 :   cgraph_node_hook_list *entry = m_first_cgraph_removal_hook;
     523    156054371 :   while (entry)
     524              :   {
     525     43682353 :     entry->hook (node, entry->data);
     526     43682353 :     entry = entry->next;
     527              :   }
     528    112372018 : }
     529              : 
     530              : /* Call all node removal hooks.  */
     531              : void
     532       116579 : symbol_table::call_cgraph_insertion_hooks (cgraph_node *node)
     533              : {
     534       116579 :   cgraph_node_hook_list *entry = m_first_cgraph_insertion_hook;
     535       350033 :   while (entry)
     536              :   {
     537       233454 :     entry->hook (node, entry->data);
     538       233454 :     entry = entry->next;
     539              :   }
     540       116579 : }
     541              : 
     542              : 
     543              : /* Register HOOK to be called with DATA on each inserted node.  */
     544              : cgraph_node_hook_list *
     545      8413079 : symbol_table::add_cgraph_insertion_hook (cgraph_node_hook hook, void *data)
     546              : {
     547      8413079 :   cgraph_node_hook_list *entry;
     548     16826158 :   cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
     549              : 
     550      8413079 :   entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
     551      8413079 :   entry->hook = hook;
     552      8413079 :   entry->data = data;
     553      8413079 :   entry->next = NULL;
     554     24955297 :   while (*ptr)
     555     16542218 :     ptr = &(*ptr)->next;
     556      8413079 :   *ptr = entry;
     557      8413079 :   return entry;
     558              : }
     559              : 
     560              : /* Remove ENTRY from the list of hooks called on inserted nodes.  */
     561              : void
     562      8266578 : symbol_table::remove_cgraph_insertion_hook (cgraph_node_hook_list *entry)
     563              : {
     564      8266578 :   cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
     565              : 
     566     22829882 :   while (*ptr != entry)
     567     14563304 :     ptr = &(*ptr)->next;
     568      8266578 :   *ptr = entry->next;
     569      8266578 :   free (entry);
     570      8266578 : }
     571              : 
     572              : /* Register HOOK to be called with DATA on each duplicated edge.  */
     573              : cgraph_2edge_hook_list *
     574      1661423 : symbol_table::add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
     575              : {
     576      1661423 :   cgraph_2edge_hook_list *entry;
     577      3322846 :   cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
     578              : 
     579      1661423 :   entry = (cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
     580      1661423 :   entry->hook = hook;
     581      1661423 :   entry->data = data;
     582      1661423 :   entry->next = NULL;
     583      5345548 :   while (*ptr)
     584      3684125 :     ptr = &(*ptr)->next;
     585      1661423 :   *ptr = entry;
     586      1661423 :   return entry;
     587              : }
     588              : 
     589              : /* Remove ENTRY from the list of hooks called on duplicating edges.  */
     590              : void
     591      1661409 : symbol_table::remove_edge_duplication_hook (cgraph_2edge_hook_list *entry)
     592              : {
     593      1661409 :   cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
     594              : 
     595      3953461 :   while (*ptr != entry)
     596      2292052 :     ptr = &(*ptr)->next;
     597      1661409 :   *ptr = entry->next;
     598      1661409 :   free (entry);
     599      1661409 : }
     600              : 
     601              : /* Call all edge duplication hooks.  */
     602              : void
     603      7070738 : symbol_table::call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2)
     604              : {
     605      7070738 :   cgraph_2edge_hook_list *entry = m_first_edge_duplicated_hook;
     606     21076903 :   while (entry)
     607              :   {
     608     14006165 :     entry->hook (cs1, cs2, entry->data);
     609     14006165 :     entry = entry->next;
     610              :   }
     611      7070738 : }
     612              : 
     613              : /* Register HOOK to be called with DATA on each duplicated node.  */
     614              : cgraph_2node_hook_list *
     615      7792040 : symbol_table::add_cgraph_duplication_hook (cgraph_2node_hook hook, void *data)
     616              : {
     617      7792040 :   cgraph_2node_hook_list *entry;
     618     15584080 :   cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
     619              : 
     620      7792040 :   entry = (cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
     621      7792040 :   entry->hook = hook;
     622      7792040 :   entry->data = data;
     623      7792040 :   entry->next = NULL;
     624     38437394 :   while (*ptr)
     625     30645354 :     ptr = &(*ptr)->next;
     626      7792040 :   *ptr = entry;
     627      7792040 :   return entry;
     628              : }
     629              : 
     630              : /* Remove ENTRY from the list of hooks called on duplicating nodes.  */
     631              : void
     632      7696149 : symbol_table::remove_cgraph_duplication_hook (cgraph_2node_hook_list *entry)
     633              : {
     634      7696149 :   cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
     635              : 
     636     34860161 :   while (*ptr != entry)
     637     27164012 :     ptr = &(*ptr)->next;
     638      7696149 :   *ptr = entry->next;
     639      7696149 :   free (entry);
     640      7696149 : }
     641              : 
     642              : /* Call all node duplication hooks.  */
     643              : void
     644      3058401 : symbol_table::call_cgraph_duplication_hooks (cgraph_node *node,
     645              :                                              cgraph_node *node2)
     646              : {
     647      3058401 :   cgraph_2node_hook_list *entry = m_first_cgraph_duplicated_hook;
     648     21642291 :   while (entry)
     649              :   {
     650     18583890 :     entry->hook (node, node2, entry->data);
     651     18583890 :     entry = entry->next;
     652              :   }
     653      3058401 : }
     654              : 
     655              : /* Return cgraph node assigned to DECL.  Create new one when needed.  */
     656              : 
     657              : cgraph_node *
     658    112818789 : cgraph_node::create (tree decl)
     659              : {
     660    112818789 :   cgraph_node *node = symtab->create_empty ();
     661    112818789 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
     662              : 
     663    112818789 :   node->decl = decl;
     664    112818789 :   node->semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
     665              : 
     666    112759224 :   if ((flag_openacc || flag_openmp)
     667    113086112 :       && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
     668              :     {
     669         8433 :       node->offloadable = 1;
     670         8433 :       if (ENABLE_OFFLOADING)
     671              :         g->have_offload = true;
     672              :     }
     673              : 
     674    112818789 :   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     675          118 :     node->ifunc_resolver = true;
     676              : 
     677    112818789 :   node->register_symbol ();
     678    112818789 :   maybe_record_nested_function (node);
     679              : 
     680    112818789 :   return node;
     681              : }
     682              : 
     683              : /* Try to find a call graph node for declaration DECL and if it does not exist
     684              :    or if it corresponds to an inline clone, create a new one.  */
     685              : 
     686              : cgraph_node *
     687    625129775 : cgraph_node::get_create (tree decl)
     688              : {
     689    625129775 :   cgraph_node *first_clone = cgraph_node::get (decl);
     690              : 
     691    625129775 :   if (first_clone && !first_clone->inlined_to)
     692              :     return first_clone;
     693              : 
     694    112755124 :   cgraph_node *node = cgraph_node::create (decl);
     695    112755124 :   if (first_clone)
     696              :     {
     697            6 :       first_clone->clone_of = node;
     698            6 :       node->clones = first_clone;
     699            6 :       node->order = first_clone->order;
     700            6 :       symtab->symtab_prevail_in_asm_name_hash (node);
     701            6 :       node->decl->decl_with_vis.symtab_node = node;
     702            6 :       if (dump_file && symtab->state != PARSING)
     703            2 :         fprintf (dump_file, "Introduced new external node "
     704              :                  "(%s) and turned into root of the clone tree.\n",
     705              :                  node->dump_name ());
     706              :     }
     707    112755118 :   else if (dump_file && symtab->state != PARSING)
     708         1165 :     fprintf (dump_file, "Introduced new external node "
     709              :              "(%s).\n", node->dump_name ());
     710              :   return node;
     711              : }
     712              : 
     713              : /* Mark ALIAS as an alias to DECL.  DECL_NODE is cgraph node representing
     714              :    the function body is associated with
     715              :    (not necessarily cgraph_node (DECL)).  */
     716              : 
     717              : cgraph_node *
     718      8667295 : cgraph_node::create_alias (tree alias, tree target)
     719              : {
     720      8667295 :   cgraph_node *alias_node;
     721              : 
     722      8667295 :   gcc_assert (TREE_CODE (target) == FUNCTION_DECL
     723              :               || TREE_CODE (target) == IDENTIFIER_NODE);
     724      8667295 :   gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
     725      8667295 :   alias_node = cgraph_node::get_create (alias);
     726      8667295 :   gcc_assert (!alias_node->definition);
     727      8667295 :   alias_node->alias_target = target;
     728      8667295 :   alias_node->definition = true;
     729      8667295 :   alias_node->alias = true;
     730      8667295 :   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     731           47 :     alias_node->transparent_alias = alias_node->weakref = true;
     732      8667295 :   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
     733          313 :     alias_node->ifunc_resolver = true;
     734      8667295 :   return alias_node;
     735              : }
     736              : 
     737              : /* Attempt to mark ALIAS as an alias to DECL.  Return alias node if successful
     738              :    and NULL otherwise.
     739              :    Same body aliases are output whenever the body of DECL is output,
     740              :    and cgraph_node::get (ALIAS) transparently returns
     741              :    cgraph_node::get (DECL).  */
     742              : 
     743              : cgraph_node *
     744      8647661 : cgraph_node::create_same_body_alias (tree alias, tree decl)
     745              : {
     746      8647661 :   cgraph_node *n;
     747              : 
     748              :   /* If aliases aren't supported by the assembler, fail.  */
     749      8647661 :   if (!TARGET_SUPPORTS_ALIASES)
     750              :     return NULL;
     751              : 
     752              :   /* Langhooks can create same body aliases of symbols not defined.
     753              :      Those are useless. Drop them on the floor.  */
     754      8647661 :   if (symtab->global_info_ready)
     755              :     return NULL;
     756              : 
     757      8647661 :   n = cgraph_node::create_alias (alias, decl);
     758      8647661 :   n->cpp_implicit_alias = true;
     759      8647661 :   if (symtab->cpp_implicit_aliases_done)
     760      4514893 :     n->resolve_alias (cgraph_node::get (decl));
     761              :   return n;
     762              : }
     763              : 
     764              : /* Add thunk alias into callgraph.  The alias declaration is ALIAS and it
     765              :    aliases DECL with an adjustments made into the first parameter.
     766              :    See comments in struct cgraph_thunk_info for detail on the parameters.  */
     767              : 
     768              : cgraph_node *
     769         4357 : cgraph_node::create_thunk (tree alias, tree, bool this_adjusting,
     770              :                            HOST_WIDE_INT fixed_offset,
     771              :                            HOST_WIDE_INT virtual_value,
     772              :                            HOST_WIDE_INT indirect_offset,
     773              :                            tree virtual_offset,
     774              :                            tree real_alias)
     775              : {
     776         4357 :   cgraph_node *node;
     777              : 
     778         4357 :   node = cgraph_node::get (alias);
     779         4357 :   if (node)
     780         3631 :     node->reset ();
     781              :   else
     782          726 :     node = cgraph_node::create (alias);
     783              : 
     784              :   /* Make sure that if VIRTUAL_OFFSET is in sync with VIRTUAL_VALUE.  */
     785         4357 :   gcc_checking_assert (virtual_offset
     786              :                        ? virtual_value == wi::to_wide (virtual_offset)
     787              :                        : virtual_value == 0);
     788              : 
     789         4357 :   node->thunk = true;
     790         4357 :   node->definition = true;
     791              : 
     792         4357 :   thunk_info *i;
     793         4357 :   thunk_info local_info;
     794         4357 :   if (symtab->state < CONSTRUCTION)
     795              :     i = &local_info;
     796              :   else
     797            0 :     i = thunk_info::get_create (node);
     798         4357 :   i->fixed_offset = fixed_offset;
     799         4357 :   i->virtual_value = virtual_value;
     800         4357 :   i->indirect_offset = indirect_offset;
     801         4357 :   i->alias = real_alias;
     802         4357 :   i->this_adjusting = this_adjusting;
     803         4357 :   i->virtual_offset_p = virtual_offset != NULL;
     804         4357 :   if (symtab->state < CONSTRUCTION)
     805         4357 :     i->register_early (node);
     806              : 
     807         4357 :   return node;
     808              : }
     809              : 
     810              : /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
     811              :    Return NULL if there's no such node.  */
     812              : 
     813              : cgraph_node *
     814            0 : cgraph_node::get_for_asmname (tree asmname)
     815              : {
     816              :   /* We do not want to look at inline clones.  */
     817            0 :   for (symtab_node *node = symtab_node::get_for_asmname (asmname);
     818            0 :        node;
     819            0 :        node = node->next_sharing_asm_name)
     820              :     {
     821            0 :       cgraph_node *cn = dyn_cast <cgraph_node *> (node);
     822            0 :       if (cn && !cn->inlined_to)
     823              :         return cn;
     824              :     }
     825              :   return NULL;
     826              : }
     827              : 
     828              : /* Returns a hash value for X (which really is a cgraph_edge).  */
     829              : 
     830              : hashval_t
     831    224263123 : cgraph_edge_hasher::hash (cgraph_edge *e)
     832              : {
     833              :   /* This is a really poor hash function, but it is what htab_hash_pointer
     834              :      uses.  */
     835    224263123 :   return (hashval_t) ((intptr_t)e->call_stmt >> 3);
     836              : }
     837              : 
     838              : /* Returns a hash value for X (which really is a cgraph_edge).  */
     839              : 
     840              : hashval_t
     841     44340047 : cgraph_edge_hasher::hash (gimple *call_stmt)
     842              : {
     843              :   /* This is a really poor hash function, but it is what htab_hash_pointer
     844              :      uses.  */
     845     44340047 :   return (hashval_t) ((intptr_t)call_stmt >> 3);
     846              : }
     847              : 
     848              : /* Return nonzero if the call_stmt of cgraph_edge X is stmt *Y.  */
     849              : 
     850              : inline bool
     851    274086934 : cgraph_edge_hasher::equal (cgraph_edge *x, gimple *y)
     852              : {
     853    274086934 :   return x->call_stmt == y;
     854              : }
     855              : 
     856              : /* Add call graph edge E to call site hash of its caller.  */
     857              : 
     858              : static inline void
     859         4434 : cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
     860              : {
     861         4434 :   gimple *call = e->call_stmt;
     862         4434 :   *e->caller->call_site_hash->find_slot_with_hash
     863         4434 :       (call, cgraph_edge_hasher::hash (call), INSERT) = e;
     864         4434 : }
     865              : 
     866              : /* Add call graph edge E to call site hash of its caller.  */
     867              : 
     868              : static inline void
     869      8414841 : cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
     870              : {
     871              :   /* There are two speculative edges for every statement (one direct,
     872              :      one indirect); always hash the direct one.  */
     873      8414841 :   if (e->speculative && e->indirect_unknown_callee)
     874              :     return;
     875              :   /* We always want to hash the carrying edge of a callback, not the edges
     876              :      pointing to the callbacks themselves, as their call statement doesn't
     877              :      exist.  */
     878      8414827 :   if (e->callback)
     879              :     return;
     880      8414815 :   cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
     881      8414815 :       (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt), INSERT);
     882      8414815 :   if (*slot)
     883              :     {
     884         4512 :       cgraph_edge *edge = (cgraph_edge *) *slot;
     885         4512 :       gcc_assert (edge->speculative || edge->has_callback);
     886         4512 :       if (edge->has_callback)
     887              :         /* If the slot is already occupied, then the hashed edge is the
     888              :            callback-carrying edge, which is desired behavior.  In some cases,
     889              :            the callback flag of E is not set yet and so the early exit above is
     890              :            not taken.  */
     891              :         return;
     892         4420 :       if (e->callee && (!e->prev_callee
     893            4 :                         || !e->prev_callee->speculative
     894            4 :                         || e->prev_callee->call_stmt != e->call_stmt))
     895          705 :         *slot = e;
     896         4420 :       return;
     897              :     }
     898      8410303 :   gcc_assert (!*slot || e->speculative);
     899      8410303 :   *slot = e;
     900              : }
     901              : 
     902              : /* Return the callgraph edge representing the GIMPLE_CALL statement
     903              :    CALL_STMT.  */
     904              : 
     905              : cgraph_edge *
     906    207141106 : cgraph_node::get_edge (gimple *call_stmt)
     907              : {
     908    207141106 :   cgraph_edge *e, *e2;
     909    207141106 :   int n = 0;
     910              : 
     911    207141106 :   if (call_site_hash)
     912     34759661 :     return call_site_hash->find_with_hash
     913     34759661 :         (call_stmt, cgraph_edge_hasher::hash (call_stmt));
     914              : 
     915              :   /* This loop may turn out to be performance problem.  In such case adding
     916              :      hashtables into call nodes with very many edges is probably best
     917              :      solution.  It is not good idea to add pointer into CALL_EXPR itself
     918              :      because we want to make possible having multiple cgraph nodes representing
     919              :      different clones of the same body before the body is actually cloned.  */
     920   1671972704 :   for (e = callees; e; e = e->next_callee)
     921              :     {
     922   1625457867 :       if (e->call_stmt == call_stmt)
     923              :         break;
     924   1499591259 :       n++;
     925              :     }
     926              : 
     927    172381445 :   if (!e)
     928     60134408 :     for (e = indirect_calls; e; e = e->next_callee)
     929              :       {
     930     16511925 :         if (e->call_stmt == call_stmt)
     931              :           break;
     932     13619571 :         n++;
     933              :       }
     934              : 
     935              :   /* We want to work with the callback-carrying edge whenever possible.  When it
     936              :      comes to callback edges, a call statement might have multiple callback
     937              :      edges attached to it.  These can be easily obtained from the carrying edge
     938              :      instead.  */
     939    172381445 :   if (e && e->callback)
     940        55470 :     e = e->get_callback_carrying_edge ();
     941              : 
     942    172381445 :   if (n > 100)
     943              :     {
     944        30660 :       call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc (120);
     945      3146195 :       for (e2 = callees; e2; e2 = e2->next_callee)
     946      3115535 :         cgraph_add_edge_to_call_site_hash (e2);
     947       116069 :       for (e2 = indirect_calls; e2; e2 = e2->next_callee)
     948        85409 :         cgraph_add_edge_to_call_site_hash (e2);
     949              :     }
     950              : 
     951              :   return e;
     952              : }
     953              : 
     954              : /* Change field call_stmt of edge E to NEW_STMT.  If UPDATE_DERIVED_EDGES and E
     955              :    is any component of speculative edge, then update all components.
     956              :    speculations can be resolved in the process and edge can be removed and
     957              :    deallocated.  if update_derived_edges and e is a part of a callback pair,
     958              :    update all associated edges and return their carrying edge.  return the edge
     959              :    that now represents the call.  */
     960              : 
     961              : cgraph_edge *
     962      2908530 : cgraph_edge::set_call_stmt (cgraph_edge *e, gcall *new_stmt,
     963              :                             bool update_derived_edges)
     964              : {
     965      2908530 :   tree decl;
     966              : 
     967      2908530 :   cgraph_node *new_direct_callee = NULL;
     968      2876217 :   if ((e->indirect_unknown_callee || e->speculative)
     969      2956573 :       && (decl = gimple_call_fndecl (new_stmt)))
     970              :     {
     971              :       /* Constant propagation and especially inlining can turn an indirect call
     972              :          into a direct one.  */
     973            0 :       new_direct_callee = cgraph_node::get (decl);
     974            0 :       gcc_checking_assert (new_direct_callee);
     975              :     }
     976              : 
     977              :   /* Speculative edges has three component, update all of them
     978              :      when asked to.  */
     979      2908530 :   if (update_derived_edges && e->speculative
     980              :       /* If we are about to resolve the speculation by calling make_direct
     981              :          below, do not bother going over all the speculative edges now.  */
     982         6990 :       && !new_direct_callee)
     983              :     {
     984         6990 :       cgraph_edge *direct, *indirect, *next;
     985         6990 :       ipa_ref *ref;
     986         6990 :       bool e_indirect = e->indirect_unknown_callee;
     987         6990 :       int n = 0;
     988              : 
     989         6990 :       direct = e->first_speculative_call_target ();
     990         6990 :       indirect = e->speculative_call_indirect_edge ();
     991              : 
     992         6990 :       gcall *old_stmt = direct->call_stmt;
     993        15730 :       for (cgraph_edge *d = direct; d; d = next)
     994              :         {
     995         8740 :           next = d->next_speculative_call_target ();
     996         8740 :           cgraph_edge *d2 = set_call_stmt (d, new_stmt, false);
     997         8740 :           gcc_assert (d2 == d);
     998         8740 :           n++;
     999              :         }
    1000         6990 :       gcc_checking_assert (indirect->num_speculative_call_targets_p () == n);
    1001        20494 :       for (unsigned int i = 0; e->caller->iterate_reference (i, ref); i++)
    1002        13504 :         if (ref->speculative && ref->stmt == old_stmt)
    1003              :           {
    1004         8740 :             ref->stmt = new_stmt;
    1005         8740 :             n--;
    1006              :           }
    1007              : 
    1008         6990 :       indirect = set_call_stmt (indirect, new_stmt, false);
    1009         6990 :       return e_indirect ? indirect : direct;
    1010              :     }
    1011              : 
    1012      2901540 :   if (new_direct_callee)
    1013            0 :     e = make_direct (e, new_direct_callee);
    1014              : 
    1015              :   /* When updating a callback or a callback-carrying edge, update every edge
    1016              :      involved.  */
    1017      2901540 :   if (update_derived_edges && (e->callback || e->has_callback))
    1018              :     {
    1019          791 :       cgraph_edge *current, *next, *carrying;
    1020          791 :       carrying = e->has_callback ? e : e->get_callback_carrying_edge ();
    1021              : 
    1022          791 :       current = e->first_callback_edge ();
    1023          791 :       if (current)
    1024              :         {
    1025          106 :           for (cgraph_edge *d = current; d; d = next)
    1026              :             {
    1027           53 :               next = d->next_callback_edge ();
    1028           53 :               cgraph_edge *d2 = set_call_stmt (d, new_stmt, false);
    1029           53 :               gcc_assert (d2 == d);
    1030              :             }
    1031              :         }
    1032          791 :       carrying = set_call_stmt (carrying, new_stmt, false);
    1033          791 :       return carrying;
    1034              :     }
    1035              : 
    1036              :   /* Only direct speculative edges go to call_site_hash.  */
    1037      2900749 :   if (e->caller->call_site_hash
    1038       569171 :       && (!e->speculative || !e->indirect_unknown_callee)
    1039              :       /* It is possible that edge was previously speculative.  In this case
    1040              :          we have different value in call stmt hash which needs preserving.  */
    1041      3469920 :       && e->caller->get_edge (e->call_stmt) == e)
    1042       564735 :     e->caller->call_site_hash->remove_elt_with_hash
    1043       564735 :       (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt));
    1044              : 
    1045      2900749 :   e->call_stmt = new_stmt;
    1046              : 
    1047      2900749 :   function *fun = DECL_STRUCT_FUNCTION (e->caller->decl);
    1048      2900749 :   e->can_throw_external = stmt_can_throw_external (fun, new_stmt);
    1049              :   /* Update call stite hash.  For speculative calls we only record the first
    1050              :      direct edge.  */
    1051      2900749 :   if (e->caller->call_site_hash
    1052       569171 :       && (!e->speculative
    1053            0 :           || (e->callee
    1054            0 :               && (!e->prev_callee || !e->prev_callee->speculative
    1055            0 :                   || e->prev_callee->call_stmt != e->call_stmt))
    1056            0 :           || (e->speculative && !e->callee)))
    1057       569171 :     cgraph_add_edge_to_call_site_hash (e);
    1058              :   return e;
    1059              : }
    1060              : 
    1061              : /* Allocate a cgraph_edge structure and fill it with data according to the
    1062              :    parameters of which only CALLEE can be NULL (when creating an indirect call
    1063              :    edge).  CLONING_P should be set if properties that are copied from an
    1064              :    original edge should not be calculated.  */
    1065              : 
    1066              : cgraph_edge *
    1067     44709340 : symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
    1068              :                            gcall *call_stmt, profile_count count,
    1069              :                            bool indir_unknown_callee, bool cloning_p)
    1070              : {
    1071     44709340 :   cgraph_edge *edge;
    1072              : 
    1073              :   /* LTO does not actually have access to the call_stmt since these
    1074              :      have not been loaded yet.  */
    1075     44709340 :   if (call_stmt)
    1076              :     {
    1077              :       /* This is a rather expensive check possibly triggering
    1078              :          construction of call stmt hashtable.  */
    1079     43851564 :       cgraph_edge *e;
    1080     43851564 :       gcc_checking_assert (!(e = caller->get_edge (call_stmt))
    1081              :                            || e->speculative || e->has_callback || e->callback);
    1082              : 
    1083     43851564 :       gcc_assert (is_gimple_call (call_stmt));
    1084              :     }
    1085              : 
    1086     44709340 :   edge = ggc_alloc<cgraph_edge> ();
    1087     44709340 :   edge->m_summary_id = -1;
    1088     44709340 :   edges_count++;
    1089              : 
    1090     44709340 :   ++edges_max_uid;
    1091     44709340 :   gcc_assert (edges_max_uid != 0);
    1092     44709340 :   edge->m_uid = edges_max_uid;
    1093     44709340 :   edge->aux = NULL;
    1094     44709340 :   edge->caller = caller;
    1095     44709340 :   edge->callee = callee;
    1096     44709340 :   edge->prev_caller = NULL;
    1097     44709340 :   edge->next_caller = NULL;
    1098     44709340 :   edge->prev_callee = NULL;
    1099     44709340 :   edge->next_callee = NULL;
    1100     44709340 :   edge->lto_stmt_uid = 0;
    1101     44709340 :   edge->speculative_id = 0;
    1102              : 
    1103     44709340 :   edge->count = count;
    1104     44709340 :   edge->call_stmt = call_stmt;
    1105     44709340 :   edge->indirect_info = NULL;
    1106     44709340 :   edge->indirect_inlining_edge = 0;
    1107     44709340 :   edge->speculative = false;
    1108     44709340 :   edge->has_callback = false;
    1109     44709340 :   edge->callback = false;
    1110     44709340 :   edge->callback_id = 0;
    1111     44709340 :   edge->indirect_unknown_callee = indir_unknown_callee;
    1112     44709340 :   if (call_stmt && caller->call_site_hash)
    1113      4644726 :     cgraph_add_edge_to_call_site_hash (edge);
    1114              : 
    1115     44709340 :   if (cloning_p)
    1116              :     return edge;
    1117              : 
    1118     37653720 :   edge->can_throw_external
    1119     37653720 :     = call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl),
    1120              :                                            call_stmt) : false;
    1121     37653720 :   edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
    1122     37653720 :   edge->call_stmt_cannot_inline_p = false;
    1123              : 
    1124     37653720 :   if (opt_for_fn (edge->caller->decl, flag_devirtualize)
    1125     37653720 :       && call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
    1126     29546768 :     edge->in_polymorphic_cdtor
    1127     29546768 :       = decl_maybe_in_construction_p (NULL, NULL, call_stmt,
    1128              :                                       caller->decl);
    1129              :   else
    1130      8106952 :     edge->in_polymorphic_cdtor = caller->thunk;
    1131              : 
    1132     36985506 :   if (callee && symtab->state != LTO_STREAMING
    1133     74042056 :       && edge->callee->comdat_local_p ())
    1134         6763 :     edge->caller->calls_comdat_local = true;
    1135              : 
    1136              :   return edge;
    1137              : }
    1138              : 
    1139              : /* Create edge from a given function to CALLEE in the cgraph.  CLONING_P should
    1140              :    be set if properties that are copied from an original edge should not be
    1141              :    calculated.  */
    1142              : 
    1143              : cgraph_edge *
    1144     43865166 : cgraph_node::create_edge (cgraph_node *callee,
    1145              :                           gcall *call_stmt, profile_count count, bool cloning_p)
    1146              : {
    1147     43865166 :   cgraph_edge *edge = symtab->create_edge (this, callee, call_stmt, count,
    1148              :                                            false, cloning_p);
    1149              : 
    1150     43865166 :   if (!cloning_p)
    1151     36985506 :     initialize_inline_failed (edge);
    1152              : 
    1153     43865166 :   edge->next_caller = callee->callers;
    1154     43865166 :   if (callee->callers)
    1155     34212564 :     callee->callers->prev_caller = edge;
    1156     43865166 :   edge->next_callee = callees;
    1157     43865166 :   if (callees)
    1158     34041337 :     callees->prev_callee = edge;
    1159     43865166 :   callees = edge;
    1160     43865166 :   callee->callers = edge;
    1161              : 
    1162     43865166 :   return edge;
    1163              : }
    1164              : 
    1165              : /* Create an indirect edge to a (yet-)undetermined callee.  CALL_STMT is the
    1166              :    corresponding statement, if available, ECF_FLAGS and COUNT are corresponding
    1167              :    gimple call flags and profiling count respectively.  CLONING_P should be set
    1168              :    if properties that are copied from an original edge should not be
    1169              :    calculated.  */
    1170              : 
    1171              : cgraph_edge *
    1172       844174 : cgraph_node::create_indirect_edge (gcall *call_stmt, int ecf_flags,
    1173              :                                    profile_count count, bool cloning_p)
    1174              : {
    1175       844174 :   cgraph_edge *edge = symtab->create_edge (this, NULL, call_stmt, count, true,
    1176              :                                            cloning_p);
    1177              : 
    1178       844174 :   if (!cloning_p)
    1179              :     {
    1180       668214 :       initialize_inline_failed (edge);
    1181              : 
    1182       668214 :       tree target = NULL_TREE;
    1183       668214 :       if (call_stmt)
    1184       668214 :         target = gimple_call_fn (call_stmt);
    1185       668214 :       if (target && virtual_method_call_p (target))
    1186              :         {
    1187        96557 :           ipa_polymorphic_call_context context (decl, target, call_stmt);
    1188        96557 :           HOST_WIDE_INT token = tree_to_shwi (OBJ_TYPE_REF_TOKEN (target));
    1189        96557 :           tree type = obj_type_ref_class (target);
    1190        96557 :           edge->indirect_info
    1191        96557 :             = (new (ggc_alloc<cgraph_polymorphic_indirect_info> ())
    1192              :                cgraph_polymorphic_indirect_info (ecf_flags, context, token,
    1193        96557 :                                                  type));
    1194              :         }
    1195       571657 :       else if (target && TREE_CODE (target) == SSA_NAME)
    1196       564775 :         edge->indirect_info
    1197       564775 :           = (new (ggc_alloc<cgraph_simple_indirect_info> ())
    1198       564775 :              cgraph_simple_indirect_info (ecf_flags));
    1199              :       else
    1200         6882 :         edge->indirect_info
    1201         6882 :           = (new (ggc_alloc<cgraph_indirect_call_info> ())
    1202         6882 :              cgraph_indirect_call_info(CIIK_UNSPECIFIED, ecf_flags));
    1203              :     }
    1204              : 
    1205       844174 :   edge->next_callee = indirect_calls;
    1206       844174 :   if (indirect_calls)
    1207       407833 :     indirect_calls->prev_callee = edge;
    1208       844174 :   indirect_calls = edge;
    1209              : 
    1210       844174 :   return edge;
    1211              : }
    1212              : 
    1213              : /* Remove the edge from the list of the callees of the caller.  */
    1214              : 
    1215              : void
    1216      4468979 : cgraph_edge::remove_caller (void)
    1217              : {
    1218      4468979 :   if (prev_callee)
    1219      3671056 :     prev_callee->next_callee = next_callee;
    1220      4468979 :   if (next_callee)
    1221      3067786 :     next_callee->prev_callee = prev_callee;
    1222      4468979 :   if (!prev_callee)
    1223              :     {
    1224       797923 :       if (indirect_unknown_callee)
    1225         1313 :         caller->indirect_calls = next_callee;
    1226              :       else
    1227       796610 :         caller->callees = next_callee;
    1228              :     }
    1229      4468979 :   if (caller->call_site_hash
    1230      4468979 :       && this == caller->get_edge (call_stmt))
    1231       596402 :     caller->call_site_hash->remove_elt_with_hash
    1232       596402 :         (call_stmt, cgraph_edge_hasher::hash (call_stmt));
    1233      4468979 : }
    1234              : 
    1235              : /* Put the edge onto the free list.  */
    1236              : 
    1237              : void
    1238     44275174 : symbol_table::free_edge (cgraph_edge *e)
    1239              : {
    1240     44275174 :   edges_count--;
    1241     44275174 :   if (e->m_summary_id != -1)
    1242     20808948 :     edge_released_summary_ids.safe_push (e->m_summary_id);
    1243              : 
    1244     44275174 :   if (e->indirect_info)
    1245       836774 :     ggc_free (e->indirect_info);
    1246     44275174 :   ggc_free (e);
    1247     44275174 : }
    1248              : 
    1249              : /* Remove the edge in the cgraph.  */
    1250              : 
    1251              : void
    1252       114067 : cgraph_edge::remove (cgraph_edge *edge)
    1253              : {
    1254              :   /* Call all edge removal hooks.  */
    1255       114067 :   symtab->call_edge_removal_hooks (edge);
    1256              : 
    1257       114067 :   if (!edge->indirect_unknown_callee)
    1258              :     /* Remove from callers list of the callee.  */
    1259       111359 :     edge->remove_callee ();
    1260              : 
    1261              :   /* Remove from callees list of the callers.  */
    1262       114067 :   edge->remove_caller ();
    1263              : 
    1264              :   /* Put the edge onto the free list.  */
    1265       114067 :   symtab->free_edge (edge);
    1266       114067 : }
    1267              : 
    1268              : /* Returns the next speculative_id based on currently in use
    1269              :    for the given statement for the edge.
    1270              :    Returns 0 if no speculative edges exist for this statement. */
    1271              : 
    1272              : int
    1273        17506 : cgraph_edge::get_next_speculative_id ()
    1274              : {
    1275        17506 :   int max_id = -1;
    1276        17506 :   cgraph_edge *e;
    1277              : 
    1278              :   /* Iterate through all edges leaving this caller */
    1279       259403 :   for (e = caller->callees; e; e = e->next_callee)
    1280              :     {
    1281              :       /* Match the specific GIMPLE statement and check the
    1282              :          speculative flag */
    1283       241897 :       if (e->call_stmt == call_stmt
    1284           22 :           && e->lto_stmt_uid == lto_stmt_uid
    1285            0 :           && e->speculative)
    1286              :         {
    1287            0 :           if (e->speculative_id > max_id)
    1288       241897 :             max_id = e->speculative_id;
    1289              :         }
    1290              :     }
    1291              : 
    1292        17506 :   return max_id + 1;
    1293              : }
    1294              : 
    1295              : 
    1296              : /* Turn edge into speculative call calling N2. Update
    1297              :    the profile so the direct call is taken COUNT times
    1298              :    with FREQUENCY.
    1299              : 
    1300              :    At clone materialization time, the indirect call E will
    1301              :    be expanded as:
    1302              : 
    1303              :    if (call_dest == N2)
    1304              :      n2 ();
    1305              :    else
    1306              :      call call_dest
    1307              : 
    1308              :    At this time the function just creates the direct call,
    1309              :    the reference representing the if conditional and attaches
    1310              :    them all to the original indirect call statement.
    1311              : 
    1312              :    speculative_id is used to link direct calls with their corresponding
    1313              :    IPA_REF_ADDR references when representing speculative calls.
    1314              : 
    1315              :    Return direct edge created.  */
    1316              : 
    1317              : cgraph_edge *
    1318        17448 : cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count,
    1319              :                                unsigned int speculative_id)
    1320              : {
    1321        17448 :   cgraph_node *n = caller;
    1322        17448 :   ipa_ref *ref = NULL;
    1323        17448 :   cgraph_edge *e2;
    1324              : 
    1325        17448 :   if (dump_file)
    1326           29 :     fprintf (dump_file, "Indirect call -> speculative call %s => %s\n",
    1327              :              n->dump_name (), n2->dump_name ());
    1328        17448 :   speculative = true;
    1329        17448 :   e2 = n->create_edge (n2, call_stmt, direct_count);
    1330        17448 :   initialize_inline_failed (e2);
    1331        17448 :   e2->speculative = true;
    1332        17448 :   if (TREE_NOTHROW (n2->decl))
    1333        10235 :     e2->can_throw_external = false;
    1334              :   else
    1335         7213 :     e2->can_throw_external = can_throw_external;
    1336        17448 :   e2->lto_stmt_uid = lto_stmt_uid;
    1337        17448 :   e2->speculative_id = speculative_id;
    1338        17448 :   e2->in_polymorphic_cdtor = in_polymorphic_cdtor;
    1339        17448 :   indirect_info->num_speculative_call_targets++;
    1340        17448 :   count -= e2->count;
    1341        17448 :   symtab->call_edge_duplication_hooks (this, e2);
    1342        17448 :   ref = n->create_reference (n2, IPA_REF_ADDR, call_stmt);
    1343        17448 :   ref->lto_stmt_uid = lto_stmt_uid;
    1344        17448 :   ref->speculative_id = speculative_id;
    1345        17448 :   ref->speculative = speculative;
    1346        17448 :   n2->mark_address_taken ();
    1347        17448 :   return e2;
    1348              : }
    1349              : 
    1350              : /* Create a callback edge calling N2.  Callback edges
    1351              :    never get turned into actual calls, they are just used
    1352              :    as clues and allow for optimizing functions which do not
    1353              :    have any callsites during compile time, e.g. functions
    1354              :    passed to standard library functions.
    1355              : 
    1356              :    The edge will be attached to the same call statement as
    1357              :    the callback-carrying edge, which is the instance this method
    1358              :    is called on.
    1359              : 
    1360              :    callback_id is used to pair the returned edge with the attribute that
    1361              :    originated it.
    1362              : 
    1363              :    Return the resulting callback edge.  */
    1364              : 
    1365              : cgraph_edge *
    1366        15069 : cgraph_edge::make_callback (cgraph_node *n2, unsigned int callback_id)
    1367              : {
    1368        15069 :   cgraph_node *n = caller;
    1369        15069 :   cgraph_edge *e2;
    1370              : 
    1371        15069 :   has_callback = true;
    1372        15069 :   e2 = n->create_edge (n2, call_stmt, count);
    1373        15069 :   if (dump_file)
    1374            3 :     fprintf (
    1375              :       dump_file,
    1376              :       "Created callback edge %s -> %s belonging to carrying edge %s -> %s\n",
    1377            3 :       e2->caller->dump_name (), e2->callee->dump_name (), caller->dump_name (),
    1378            3 :       callee->dump_name ());
    1379        15069 :   e2->inline_failed = CIF_CALLBACK_EDGE;
    1380        15069 :   e2->callback = true;
    1381        15069 :   e2->callback_id = callback_id;
    1382        15069 :   if (TREE_NOTHROW (n2->decl))
    1383        14818 :     e2->can_throw_external = false;
    1384              :   else
    1385          251 :     e2->can_throw_external = can_throw_external;
    1386        15069 :   e2->lto_stmt_uid = lto_stmt_uid;
    1387        15069 :   n2->mark_address_taken ();
    1388        15069 :   return e2;
    1389              : }
    1390              : 
    1391              : /* Returns the callback_carrying edge of a callback edge on which
    1392              :    it is called on or NULL when no such edge can be found.
    1393              : 
    1394              :    An edge is taken to be the callback-carrying if it has it's has_callback
    1395              :    flag set and the edges share their call statements.  */
    1396              : 
    1397              : cgraph_edge *
    1398        82997 : cgraph_edge::get_callback_carrying_edge ()
    1399              : {
    1400        82997 :   gcc_checking_assert (callback);
    1401        82997 :   cgraph_edge *e;
    1402       654319 :   for (e = caller->callees; e; e = e->next_callee)
    1403              :     {
    1404       654112 :       if (e->has_callback && e->call_stmt == call_stmt
    1405        82790 :           && e->lto_stmt_uid == lto_stmt_uid)
    1406              :         break;
    1407              :     }
    1408        82997 :   return e;
    1409              : }
    1410              : 
    1411              : /* Returns the first callback edge in the list of callees of the caller node.
    1412              :    Note that the edges might be in arbitrary order.  Must be called on a
    1413              :    callback or callback-carrying edge.  */
    1414              : 
    1415              : cgraph_edge *
    1416        47556 : cgraph_edge::first_callback_edge ()
    1417              : {
    1418        47556 :   gcc_checking_assert (has_callback || callback);
    1419        47556 :   cgraph_edge *e = NULL;
    1420       217552 :   for (e = caller->callees; e; e = e->next_callee)
    1421              :     {
    1422       201266 :       if (e->callback && e->call_stmt == call_stmt
    1423        31270 :           && e->lto_stmt_uid == lto_stmt_uid)
    1424              :         break;
    1425              :     }
    1426        47556 :   return e;
    1427              : }
    1428              : 
    1429              : /* Given a callback edge, returns the next callback edge belonging to the same
    1430              :    carrying edge.  Must be called on a callback edge, not the callback-carrying
    1431              :    edge.  */
    1432              : 
    1433              : cgraph_edge *
    1434        31270 : cgraph_edge::next_callback_edge ()
    1435              : {
    1436        31270 :   gcc_checking_assert (callback);
    1437        31270 :   cgraph_edge *e = NULL;
    1438       321410 :   for (e = next_callee; e; e = e->next_callee)
    1439              :     {
    1440       290140 :       if (e->callback && e->call_stmt == call_stmt
    1441            0 :           && e->lto_stmt_uid == lto_stmt_uid)
    1442              :         break;
    1443              :     }
    1444        31270 :   return e;
    1445              : }
    1446              : 
    1447              : /* When called on a callback-carrying edge, removes all of its attached callback
    1448              :    edges and sets has_callback to FALSE.  */
    1449              : 
    1450              : void
    1451            1 : cgraph_edge::purge_callback_edges ()
    1452              : {
    1453            1 :   gcc_checking_assert (has_callback);
    1454            1 :   cgraph_edge *e, *next;
    1455            2 :   for (e = first_callback_edge (); e; e = next)
    1456              :     {
    1457            1 :       next = e->next_callback_edge ();
    1458            1 :       cgraph_edge::remove (e);
    1459              :     }
    1460            1 :   has_callback = false;
    1461            1 : }
    1462              : 
    1463              : /* Speculative call consists of an indirect edge and one or more
    1464              :    direct edge+ref pairs.
    1465              : 
    1466              :    Given an edge which is part of speculative call, return the first
    1467              :    direct call edge in the speculative call sequence.  */
    1468              : 
    1469              : cgraph_edge *
    1470        47508 : cgraph_edge::first_speculative_call_target ()
    1471              : {
    1472        47508 :   cgraph_edge *e = this;
    1473              : 
    1474        47508 :   gcc_checking_assert (e->speculative);
    1475        47508 :   if (e->callee)
    1476              :     {
    1477        13828 :       while (e->prev_callee && e->prev_callee->speculative
    1478         1361 :              && e->prev_callee->call_stmt == e->call_stmt
    1479        38554 :              && e->prev_callee->lto_stmt_uid == e->lto_stmt_uid)
    1480              :         e = e->prev_callee;
    1481              :       return e;
    1482              :     }
    1483              :   /* Call stmt site hash always points to the first target of the
    1484              :      speculative call sequence.  */
    1485         8954 :   if (e->call_stmt)
    1486         8934 :     return e->caller->get_edge (e->call_stmt);
    1487           27 :   for (cgraph_edge *e2 = e->caller->callees; true; e2 = e2->next_callee)
    1488           27 :     if (e2->speculative
    1489           20 :         && e->call_stmt == e2->call_stmt
    1490           20 :         && e->lto_stmt_uid == e2->lto_stmt_uid)
    1491              :       return e2;
    1492              : }
    1493              : 
    1494              : /* We always maintain first direct edge in the call site hash, if one
    1495              :    exists.  E is going to be removed.  See if it is first one and update
    1496              :    hash accordingly.  INDIRECT is the indirect edge of speculative call.
    1497              :    We assume that INDIRECT->num_speculative_call_targets_p () is already
    1498              :    updated for removal of E.  */
    1499              : static void
    1500        37974 : update_call_stmt_hash_for_removing_direct_edge (cgraph_edge *e,
    1501              :                                                 cgraph_edge *indirect)
    1502              : {
    1503        37974 :   if (e->caller->call_site_hash)
    1504              :     {
    1505         4434 :       if (e->caller->get_edge (e->call_stmt) != e)
    1506              :         ;
    1507         4434 :       else if (!indirect->num_speculative_call_targets_p ())
    1508         3946 :         cgraph_update_edge_in_call_site_hash (indirect);
    1509              :       else
    1510              :         {
    1511          488 :           gcc_checking_assert (e->next_callee && e->next_callee->speculative
    1512              :                                && e->next_callee->call_stmt == e->call_stmt);
    1513          488 :           cgraph_update_edge_in_call_site_hash (e->next_callee);
    1514              :         }
    1515              :     }
    1516        37974 : }
    1517              : 
    1518              : /* Speculative call EDGE turned out to be direct call to CALLEE_DECL.  Remove
    1519              :    the speculative call sequence and return edge representing the call, the
    1520              :    original EDGE can be removed and deallocated.  Return the edge that now
    1521              :    represents the call.
    1522              : 
    1523              :    For "speculative" indirect call that contains multiple "speculative"
    1524              :    targets (i.e. edge->indirect_info->num_speculative_call_targets > 1),
    1525              :    decrease the count and only remove current direct edge.
    1526              : 
    1527              :    If no speculative direct call left to the speculative indirect call, remove
    1528              :    the speculative of both the indirect call and corresponding direct edge.
    1529              : 
    1530              :    It is up to caller to iteratively resolve each "speculative" direct call and
    1531              :    redirect the call as appropriate.  */
    1532              : 
    1533              : cgraph_edge *
    1534         6410 : cgraph_edge::resolve_speculation (cgraph_edge *edge, tree callee_decl)
    1535              : {
    1536         6410 :   cgraph_edge *e2;
    1537         6410 :   ipa_ref *ref;
    1538              : 
    1539         6410 :   gcc_assert (edge->speculative && (!callee_decl || edge->callee));
    1540         6410 :   if (!edge->callee)
    1541            0 :     e2 = edge->first_speculative_call_target ();
    1542              :   else
    1543              :     e2 = edge;
    1544         6410 :   ref = e2->speculative_call_target_ref ();
    1545         6410 :   edge = edge->speculative_call_indirect_edge ();
    1546         6410 :   symtab_node *callee;
    1547         6410 :   if (!callee_decl
    1548         1232 :       || !(callee = symtab_node::get (callee_decl))
    1549         7642 :       || !ref->referred->semantically_equivalent_p (callee))
    1550              :     {
    1551         5492 :       if (dump_file)
    1552              :         {
    1553           78 :           if (callee_decl)
    1554              :             {
    1555            0 :               fprintf (dump_file, "Speculative indirect call %s => %s has "
    1556              :                        "turned out to have contradicting known target ",
    1557            0 :                        edge->caller->dump_name (),
    1558            0 :                        e2->callee->dump_name ());
    1559            0 :               print_generic_expr (dump_file, callee_decl);
    1560            0 :               fprintf (dump_file, "\n");
    1561              :             }
    1562              :           else
    1563              :             {
    1564           78 :               fprintf (dump_file, "Removing speculative call %s => %s\n",
    1565           78 :                        edge->caller->dump_name (),
    1566           78 :                        e2->callee->dump_name ());
    1567              :             }
    1568              :         }
    1569              :     }
    1570              :   else
    1571              :     {
    1572          918 :       cgraph_edge *tmp = edge;
    1573          918 :       if (dump_file)
    1574           99 :         fprintf (dump_file, "Speculative call turned into direct call.\n");
    1575              :       edge = e2;
    1576              :       e2 = tmp;
    1577              :       /* FIXME:  If EDGE is inlined, we should scale up the frequencies
    1578              :          and counts in the functions inlined through it.  */
    1579              :     }
    1580         6410 :   edge->count += e2->count;
    1581         6410 :   if (edge->num_speculative_call_targets_p ())
    1582              :     {
    1583              :       /* The indirect edge has multiple speculative targets, don't remove
    1584              :          speculative until all related direct edges are resolved.  */
    1585         5492 :       edge->indirect_info->num_speculative_call_targets--;
    1586         5492 :       if (!edge->indirect_info->num_speculative_call_targets)
    1587          963 :         edge->speculative = false;
    1588              :     }
    1589              :   else
    1590          918 :     edge->speculative = false;
    1591         6410 :   e2->speculative = false;
    1592         6410 :   update_call_stmt_hash_for_removing_direct_edge (e2, edge);
    1593         6410 :   ref->remove_reference ();
    1594         6410 :   if (e2->indirect_unknown_callee || e2->inline_failed)
    1595         5798 :     remove (e2);
    1596              :   else
    1597          612 :     e2->callee->remove_symbol_and_inline_clones ();
    1598         6410 :   return edge;
    1599              : }
    1600              : 
    1601              : /* Return edge corresponding to speculative call to a given target.
    1602              :    NULL if speculative call does not have one.  */
    1603              : 
    1604              : cgraph_edge *
    1605            0 : cgraph_edge::speculative_call_for_target (cgraph_node *target)
    1606              : {
    1607            0 :   for (cgraph_edge *direct = first_speculative_call_target ();
    1608            0 :        direct;
    1609            0 :        direct = direct->next_speculative_call_target ())
    1610            0 :     if (direct->speculative_call_target_ref ()
    1611            0 :         ->referred->semantically_equivalent_p (target))
    1612              :       return direct;
    1613              :   return NULL;
    1614              : }
    1615              : 
    1616              : /* Make an indirect or speculative EDGE with an unknown callee an ordinary edge
    1617              :    leading to CALLEE.  Speculations can be resolved in the process and EDGE can
    1618              :    be removed and deallocated.  Return the edge that now represents the
    1619              :    call.  */
    1620              : 
    1621              : cgraph_edge *
    1622         4777 : cgraph_edge::make_direct (cgraph_edge *edge, cgraph_node *callee)
    1623              : {
    1624         4777 :   gcc_assert (edge->indirect_unknown_callee || edge->speculative);
    1625              : 
    1626              :   /* If we are redirecting speculative call, make it non-speculative.  */
    1627         4777 :   if (edge->speculative)
    1628              :     {
    1629         1057 :       cgraph_edge *found = NULL;
    1630         1057 :       cgraph_edge *direct, *next;
    1631              : 
    1632         1057 :       edge = edge->speculative_call_indirect_edge ();
    1633              : 
    1634              :       /* Look all speculative targets and remove all but one corresponding
    1635              :          to callee (if it exists).  */
    1636         1057 :       for (direct = edge->first_speculative_call_target ();
    1637         2633 :            direct;
    1638              :            direct = next)
    1639              :         {
    1640         1576 :           next = direct->next_speculative_call_target ();
    1641              : 
    1642              :           /* Compare ref not direct->callee.  Direct edge is possibly
    1643              :              inlined or redirected.  */
    1644         1576 :           if (!direct->speculative_call_target_ref ()
    1645         1576 :                ->referred->semantically_equivalent_p (callee)
    1646         1576 :               || found)
    1647          658 :             edge = direct->resolve_speculation (direct, NULL);
    1648              :           else
    1649              :             found = direct;
    1650              :         }
    1651              : 
    1652              :       /* On successful speculation just remove the indirect edge and
    1653              :          return the pre existing direct edge.
    1654              :          It is important to not remove it and redirect because the direct
    1655              :          edge may be inlined or redirected.  */
    1656         1057 :       if (found)
    1657              :         {
    1658          918 :           cgraph_edge *e2 = resolve_speculation (found, callee->decl);
    1659          918 :           gcc_checking_assert (!found->speculative && e2 == found);
    1660              :           return found;
    1661              :         }
    1662          139 :       gcc_checking_assert (!edge->speculative);
    1663              :     }
    1664              : 
    1665         3859 :   edge->indirect_unknown_callee = 0;
    1666         3859 :   ggc_free (edge->indirect_info);
    1667         3859 :   edge->indirect_info = NULL;
    1668              : 
    1669              :   /* Get the edge out of the indirect edge list. */
    1670         3859 :   if (edge->prev_callee)
    1671          102 :     edge->prev_callee->next_callee = edge->next_callee;
    1672         3859 :   if (edge->next_callee)
    1673          500 :     edge->next_callee->prev_callee = edge->prev_callee;
    1674         3859 :   if (!edge->prev_callee)
    1675         3757 :     edge->caller->indirect_calls = edge->next_callee;
    1676              : 
    1677              :   /* Put it into the normal callee list */
    1678         3859 :   edge->prev_callee = NULL;
    1679         3859 :   edge->next_callee = edge->caller->callees;
    1680         3859 :   if (edge->caller->callees)
    1681         2487 :     edge->caller->callees->prev_callee = edge;
    1682         3859 :   edge->caller->callees = edge;
    1683              : 
    1684              :   /* Insert to callers list of the new callee.  */
    1685         3859 :   edge->set_callee (callee);
    1686              : 
    1687              :   /* We need to re-determine the inlining status of the edge.  */
    1688         3859 :   initialize_inline_failed (edge);
    1689         3859 :   return edge;
    1690              : }
    1691              : 
    1692              : /* Redirect callee of the edge to N.  The function does not update underlying
    1693              :    call expression.  */
    1694              : 
    1695              : void
    1696      4335661 : cgraph_edge::redirect_callee (cgraph_node *n)
    1697              : {
    1698      4335661 :   bool loc = callee->comdat_local_p ();
    1699      4335661 :   cgraph_node *old_callee = callee;
    1700              : 
    1701              :   /* Remove from callers list of the current callee.  */
    1702      4335661 :   remove_callee ();
    1703              : 
    1704              :   /* Insert to callers list of the new callee.  */
    1705      4335661 :   set_callee (n);
    1706              : 
    1707      4335661 :   if (callback)
    1708              :     {
    1709              :       /* When redirecting a callback callee, redirect its ref as well.  */
    1710          272 :       ipa_ref *old_ref = caller->find_reference (old_callee, call_stmt,
    1711          272 :                                                  lto_stmt_uid, IPA_REF_ADDR);
    1712          272 :       gcc_checking_assert(old_ref);
    1713          272 :       old_ref->remove_reference ();
    1714          272 :       ipa_ref *new_ref = caller->create_reference (n, IPA_REF_ADDR, call_stmt);
    1715          272 :       new_ref->lto_stmt_uid = lto_stmt_uid;
    1716              :       /* If the last reference to OLD_CALLEE has been redirected, unset
    1717              :          address_taken.  old_ref is only used as a placeholder when looking for
    1718              :          a different reference.  */
    1719          272 :       if (!old_callee->iterate_referring (0, old_ref))
    1720          226 :         old_callee->address_taken = 0;
    1721          272 :       n->mark_address_taken ();
    1722              :     }
    1723              : 
    1724      4335661 :   if (!inline_failed)
    1725              :     return;
    1726       708296 :   if (!loc && n->comdat_local_p ())
    1727              :     {
    1728           56 :       cgraph_node *to = caller->inlined_to ? caller->inlined_to : caller;
    1729           56 :       to->calls_comdat_local = true;
    1730              :     }
    1731       708240 :   else if (loc && !n->comdat_local_p ())
    1732              :     {
    1733           94 :       cgraph_node *to = caller->inlined_to ? caller->inlined_to : caller;
    1734           94 :       gcc_checking_assert (to->calls_comdat_local);
    1735           94 :       to->calls_comdat_local = to->check_calls_comdat_local_p ();
    1736              :     }
    1737              : }
    1738              : 
    1739              : /* If necessary, change the function declaration in the call statement
    1740              :    associated with E so that it corresponds to the edge callee.  Speculations
    1741              :    can be resolved in the process and EDGE can be removed and deallocated.
    1742              : 
    1743              :    The edge could be one of speculative direct call generated from speculative
    1744              :    indirect call.  In this circumstance, decrease the speculative targets
    1745              :    count (i.e. num_speculative_call_targets) and redirect call stmt to the
    1746              :    corresponding i-th target.  If no speculative direct call left to the
    1747              :    speculative indirect call, remove "speculative" of the indirect call and
    1748              :    also redirect stmt to it's final direct target.
    1749              : 
    1750              :    When called from within tree-inline, KILLED_SSAs has to contain the pointer
    1751              :    to killed_new_ssa_names within the copy_body_data structure and SSAs
    1752              :    discovered to be useless (if LHS is removed) will be added to it, otherwise
    1753              :    it needs to be NULL.
    1754              : 
    1755              :    It is up to caller to iteratively transform each "speculative"
    1756              :    direct call as appropriate.  */
    1757              : 
    1758              : gimple *
    1759      9746671 : cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e,
    1760              :                                            hash_set <tree> *killed_ssas)
    1761              : {
    1762      9746671 :   tree decl = gimple_call_fndecl (e->call_stmt);
    1763      9746671 :   gcall *new_stmt;
    1764              : 
    1765      9746671 :   if (e->speculative)
    1766              :     {
    1767              :       /* If there already is an direct call (i.e. as a result of inliner's
    1768              :          substitution), forget about speculating.  */
    1769        31564 :       if (decl)
    1770            0 :         e = make_direct (e->speculative_call_indirect_edge (),
    1771              :                          cgraph_node::get (decl));
    1772              :       else
    1773              :         {
    1774              :           /* Be sure we redirect all speculative targets before poking
    1775              :              about indirect edge.  */
    1776        31564 :           gcc_checking_assert (e->callee);
    1777        31564 :           cgraph_edge *indirect = e->speculative_call_indirect_edge ();
    1778        31564 :           gcall *new_stmt;
    1779        31564 :           ipa_ref *ref;
    1780              : 
    1781              :           /* Expand speculation into GIMPLE code.  */
    1782        31564 :           if (dump_file)
    1783              :             {
    1784          150 :               fprintf (dump_file,
    1785              :                        "Expanding speculative call of %s -> %s count: ",
    1786           75 :                        e->caller->dump_name (),
    1787              :                        e->callee->dump_name ());
    1788           75 :               e->count.dump (dump_file);
    1789           75 :               fprintf (dump_file, "\n");
    1790              :             }
    1791        31564 :           push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
    1792              : 
    1793        31564 :           profile_count all = indirect->count;
    1794        31564 :           for (cgraph_edge *e2 = e->first_speculative_call_target ();
    1795        71505 :                e2;
    1796        39941 :                e2 = e2->next_speculative_call_target ())
    1797        39941 :             all = all + e2->count;
    1798        31564 :           profile_probability prob = e->count.probability_in (all);
    1799        31564 :           if (!prob.initialized_p ())
    1800          166 :             prob = profile_probability::even ();
    1801        31564 :           ref = e->speculative_call_target_ref ();
    1802        63128 :           new_stmt = gimple_ic (e->call_stmt,
    1803              :                                 dyn_cast<cgraph_node *> (ref->referred),
    1804              :                                 prob);
    1805        31564 :           e->speculative = false;
    1806        31564 :           if (indirect->num_speculative_call_targets_p ())
    1807              :             {
    1808              :               /* The indirect edge has multiple speculative targets, don't
    1809              :                  remove speculative until all related direct edges are
    1810              :                  redirected.  */
    1811        31564 :               indirect->indirect_info->num_speculative_call_targets--;
    1812        31564 :               if (!indirect->indirect_info->num_speculative_call_targets)
    1813        24980 :                 indirect->speculative = false;
    1814              :             }
    1815              :           else
    1816            0 :             indirect->speculative = false;
    1817              :           /* Indirect edges are not both in the call site hash.
    1818              :              get it updated.  */
    1819        31564 :           update_call_stmt_hash_for_removing_direct_edge (e, indirect);
    1820        31564 :           cgraph_edge::set_call_stmt (e, new_stmt, false);
    1821        31564 :           e->count = gimple_bb (e->call_stmt)->count;
    1822              : 
    1823              :           /* Once we are done with expanding the sequence, update also indirect
    1824              :              call probability.  Until then the basic block accounts for the
    1825              :              sum of indirect edge and all non-expanded speculations.  */
    1826        31564 :           if (!indirect->speculative)
    1827        24980 :             indirect->count = gimple_bb (indirect->call_stmt)->count;
    1828        31564 :           ref->speculative = false;
    1829        31564 :           ref->stmt = NULL;
    1830        31564 :           pop_cfun ();
    1831              :           /* Continue redirecting E to proper target.  */
    1832              :         }
    1833              :     }
    1834              : 
    1835              : 
    1836      9746671 :   if (e->indirect_unknown_callee
    1837      9658850 :       || decl == e->callee->decl)
    1838      8663019 :     return e->call_stmt;
    1839              : 
    1840              :   /* When redirecting a callback edge, all we need to do is replace
    1841              :      the original address with the address of the function we are
    1842              :      redirecting to.  */
    1843      1083652 :   if (e->callback)
    1844              :     {
    1845         3425 :       cgraph_edge *carrying = e->get_callback_carrying_edge ();
    1846         3425 :       if (!callback_is_special_cased (carrying->callee->decl, e->call_stmt)
    1847         6082 :           && !lookup_attribute (CALLBACK_ATTR_IDENT,
    1848         2657 :                                 DECL_ATTRIBUTES (carrying->callee->decl)))
    1849              :         /* Callback attribute is removed if the dispatching function changes
    1850              :            signature, as the indices wouldn't be correct anymore.  These edges
    1851              :            will get cleaned up later, ignore their redirection for now.  */
    1852            0 :         return e->call_stmt;
    1853         3425 :       int fn_idx = callback_fetch_fn_position (e, carrying);
    1854         3425 :       tree previous_arg = gimple_call_arg (e->call_stmt, fn_idx);
    1855         3425 :       location_t loc = EXPR_LOCATION (previous_arg);
    1856         3425 :       tree new_addr = build_fold_addr_expr_loc (loc, e->callee->decl);
    1857         3425 :       gimple_call_set_arg (e->call_stmt, fn_idx, new_addr);
    1858         3425 :       return e->call_stmt;
    1859              :     }
    1860              : 
    1861      1080227 :   if (decl && ipa_saved_clone_sources)
    1862              :     {
    1863       886633 :       tree *p = ipa_saved_clone_sources->get (e->callee);
    1864       886633 :       if (p && decl == *p)
    1865              :         {
    1866        34058 :           gimple_call_set_fndecl (e->call_stmt, e->callee->decl);
    1867        34058 :           return e->call_stmt;
    1868              :         }
    1869              :     }
    1870      1046169 :   if (flag_checking && decl)
    1871              :     {
    1872      1011057 :       if (cgraph_node *node = cgraph_node::get (decl))
    1873              :         {
    1874       875716 :           clone_info *info = clone_info::get (node);
    1875       875716 :           gcc_assert (!info || !info->param_adjustments);
    1876              :         }
    1877              :     }
    1878              : 
    1879      1046169 :   clone_info *callee_info = clone_info::get (e->callee);
    1880      1046169 :   if (symtab->dump_file)
    1881              :     {
    1882            0 :       fprintf (symtab->dump_file, "updating call of %s -> %s: ",
    1883            0 :                e->caller->dump_name (), e->callee->dump_name ());
    1884            0 :       print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
    1885            0 :       if (callee_info && callee_info->param_adjustments)
    1886            0 :         callee_info->param_adjustments->dump (symtab->dump_file);
    1887              :     }
    1888              : 
    1889       539138 :   if (ipa_param_adjustments *padjs
    1890      1046169 :          = callee_info ? callee_info->param_adjustments : NULL)
    1891              :     {
    1892              :       /* We need to defer cleaning EH info on the new statement to
    1893              :          fixup-cfg.  We may not have dominator information at this point
    1894              :          and thus would end up with unreachable blocks and have no way
    1895              :          to communicate that we need to run CFG cleanup then.  */
    1896       531921 :       int lp_nr = lookup_stmt_eh_lp (e->call_stmt);
    1897       531921 :       if (lp_nr != 0)
    1898       140590 :         remove_stmt_from_eh_lp (e->call_stmt);
    1899              : 
    1900       531921 :       tree old_fntype = gimple_call_fntype (e->call_stmt);
    1901       531921 :       new_stmt = padjs->modify_call (e, false, killed_ssas);
    1902       531921 :       cgraph_node *origin = e->callee;
    1903       748226 :       while (origin->clone_of)
    1904              :         origin = origin->clone_of;
    1905              : 
    1906       531921 :       if ((origin->former_clone_of
    1907       433926 :            && old_fntype == TREE_TYPE (origin->former_clone_of))
    1908       534383 :           || old_fntype == TREE_TYPE (origin->decl))
    1909       431466 :         gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
    1910              :       else
    1911              :         {
    1912       100455 :           tree new_fntype = padjs->build_new_function_type (old_fntype, true);
    1913       100455 :           gimple_call_set_fntype (new_stmt, new_fntype);
    1914              :         }
    1915              : 
    1916       531921 :       if (lp_nr != 0)
    1917       140590 :         add_stmt_to_eh_lp (new_stmt, lp_nr);
    1918              :     }
    1919              :   else
    1920              :     {
    1921       514248 :       if (flag_checking
    1922       514248 :           && !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    1923              :                                                   BUILT_IN_UNREACHABLE_TRAP))
    1924       344544 :         ipa_verify_edge_has_no_modifications (e);
    1925       514248 :       new_stmt = e->call_stmt;
    1926       514248 :       gimple_call_set_fndecl (new_stmt, e->callee->decl);
    1927       514248 :       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
    1928              :     }
    1929              : 
    1930              :   /* If changing the call to __cxa_pure_virtual or similar noreturn function,
    1931              :      adjust gimple_call_fntype too.  */
    1932      1046169 :   if (gimple_call_noreturn_p (new_stmt)
    1933       172974 :       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (e->callee->decl)))
    1934       172903 :       && TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl))
    1935      1219065 :       && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl)))
    1936       172896 :           == void_type_node))
    1937       172168 :     gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
    1938              : 
    1939              :   /* If the call becomes noreturn, remove the LHS if possible.  */
    1940      1046169 :   tree lhs = gimple_call_lhs (new_stmt);
    1941      1046169 :   if (lhs
    1942       298468 :       && gimple_call_noreturn_p (new_stmt)
    1943      1086996 :       && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (new_stmt)))
    1944           58 :           || should_remove_lhs_p (lhs)))
    1945              :     {
    1946        40788 :       gimple_call_set_lhs (new_stmt, NULL_TREE);
    1947              :       /* We need to fix up the SSA name to avoid checking errors.  */
    1948        40788 :       if (TREE_CODE (lhs) == SSA_NAME)
    1949              :         {
    1950        33973 :           tree var = create_tmp_reg_fn (DECL_STRUCT_FUNCTION (e->caller->decl),
    1951        33973 :                                         TREE_TYPE (lhs), NULL);
    1952        33973 :           SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
    1953        33973 :           SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
    1954        33973 :           set_ssa_default_def (DECL_STRUCT_FUNCTION (e->caller->decl),
    1955              :                                var, lhs);
    1956              :         }
    1957        40788 :       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
    1958              :     }
    1959              : 
    1960              :   /* If new callee has no static chain, remove it.  */
    1961      1046169 :   if (gimple_call_chain (new_stmt) && !DECL_STATIC_CHAIN (e->callee->decl))
    1962              :     {
    1963           56 :       gimple_call_set_chain (new_stmt, NULL);
    1964           56 :       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
    1965              :     }
    1966              : 
    1967      1046169 :   maybe_remove_unused_call_args (DECL_STRUCT_FUNCTION (e->caller->decl),
    1968              :                                  new_stmt);
    1969              : 
    1970              :   /* Update callback edges if setting the carrying edge's statement, or else
    1971              :      their pairing would fall apart.  */
    1972      1046169 :   e->caller->set_call_stmt_including_clones (e->call_stmt, new_stmt, e->has_callback);
    1973              : 
    1974      1046169 :   if (symtab->dump_file)
    1975              :     {
    1976            0 :       fprintf (symtab->dump_file, "  updated to:");
    1977            0 :       print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
    1978              :     }
    1979              :   return new_stmt;
    1980              : }
    1981              : 
    1982              : /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
    1983              :    OLD_STMT changed into NEW_STMT.  OLD_CALL is gimple_call_fndecl
    1984              :    of OLD_STMT if it was previously call statement.
    1985              :    If NEW_STMT is NULL, the call has been dropped without any
    1986              :    replacement.  */
    1987              : 
    1988              : static void
    1989       117822 : cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
    1990              :                                         gimple *old_stmt, tree old_call,
    1991              :                                         gimple *new_stmt)
    1992              : {
    1993       117822 :   tree new_call = (new_stmt && is_gimple_call (new_stmt))
    1994       122652 :                   ? gimple_call_fndecl (new_stmt) : 0;
    1995              : 
    1996              :   /* We are seeing indirect calls, then there is nothing to update.  */
    1997       117822 :   if (!new_call && !old_call)
    1998              :     return;
    1999              :   /* See if we turned indirect call into direct call or folded call to one builtin
    2000              :      into different builtin.  */
    2001       116327 :   if (old_call != new_call)
    2002              :     {
    2003       115137 :       cgraph_edge *e = node->get_edge (old_stmt);
    2004       115137 :       cgraph_edge *ne = NULL;
    2005       115137 :       profile_count count;
    2006              : 
    2007       115137 :       if (e)
    2008              :         {
    2009              :           /* If call was devirtualized during cloning, mark edge
    2010              :              as resolved.  */
    2011        93865 :           if (e->speculative)
    2012              :             {
    2013            0 :               if (new_stmt && is_gimple_call (new_stmt))
    2014              :                 {
    2015            0 :                   tree decl = gimple_call_fndecl (new_stmt);
    2016            0 :                   if (decl)
    2017            0 :                     e = cgraph_edge::make_direct
    2018            0 :                             (e, cgraph_node::get_create (decl));
    2019              :                 }
    2020              :               else
    2021            0 :                 gcc_unreachable ();
    2022              :             }
    2023              :           /* Keep calls marked as dead dead.  */
    2024        93865 :           if (new_stmt && is_gimple_call (new_stmt) && e->callee
    2025        94446 :               && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    2026              :                                     BUILT_IN_UNREACHABLE_TRAP))
    2027              :             {
    2028            3 :               cgraph_edge::set_call_stmt (node->get_edge (old_stmt),
    2029              :                                           as_a <gcall *> (new_stmt));
    2030           28 :               return;
    2031              :             }
    2032              :           /* See if the edge is already there and has the correct callee.  It
    2033              :              might be so because of indirect inlining has already updated
    2034              :              it.  We also might've cloned and redirected the edge.  */
    2035        93862 :           if (new_call && e->callee)
    2036              :             {
    2037              :               cgraph_node *callee = e->callee;
    2038         1157 :               while (callee)
    2039              :                 {
    2040          601 :                   if (callee->decl == new_call
    2041          601 :                       || callee->former_clone_of == new_call)
    2042              :                     {
    2043           22 :                       cgraph_edge::set_call_stmt (e, as_a <gcall *> (new_stmt));
    2044           22 :                       return;
    2045              :                     }
    2046          579 :                   callee = callee->clone_of;
    2047              :                 }
    2048              :             }
    2049              : 
    2050              :           /* Otherwise remove edge and create new one; we can't simply redirect
    2051              :              since function has changed, so inline plan and other information
    2052              :              attached to edge is invalid.  */
    2053        93840 :           count = e->count;
    2054        93840 :           if (e->indirect_unknown_callee || e->inline_failed)
    2055        93840 :             cgraph_edge::remove (e);
    2056              :           else
    2057            0 :             e->callee->remove_symbol_and_inline_clones ();
    2058              :         }
    2059        21272 :       else if (new_call)
    2060              :         {
    2061              :           /* We are seeing new direct call; compute profile info based on BB.  */
    2062            4 :           basic_block bb = gimple_bb (new_stmt);
    2063            4 :           count = bb->count;
    2064              :         }
    2065              : 
    2066        93844 :       if (new_call)
    2067              :         {
    2068         2334 :           ne = node->create_edge (cgraph_node::get_create (new_call),
    2069              :                                   as_a <gcall *> (new_stmt), count);
    2070         2334 :           gcc_assert (ne->inline_failed);
    2071              :         }
    2072              :     }
    2073              :   /* We only updated the call stmt; update pointer in cgraph edge..  */
    2074         1190 :   else if (old_stmt != new_stmt)
    2075            0 :     cgraph_edge::set_call_stmt (node->get_edge (old_stmt),
    2076              :                                 as_a <gcall *> (new_stmt));
    2077              : }
    2078              : 
    2079              : /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
    2080              :    OLD_STMT changed into NEW_STMT.  OLD_DECL is gimple_call_fndecl
    2081              :    of OLD_STMT before it was updated (updating can happen inplace).  */
    2082              : 
    2083              : void
    2084        96270 : cgraph_update_edges_for_call_stmt (gimple *old_stmt, tree old_decl,
    2085              :                                    gimple *new_stmt)
    2086              : {
    2087        96270 :   cgraph_node *orig = cgraph_node::get (cfun->decl);
    2088        96270 :   cgraph_node *node;
    2089              : 
    2090        96270 :   gcc_checking_assert (orig);
    2091        96270 :   gcc_assert (!orig->thunk);
    2092        96270 :   cgraph_update_edges_for_call_stmt_node (orig, old_stmt, old_decl, new_stmt);
    2093        96270 :   if (orig->clones)
    2094        42558 :     for (node = orig->clones; node != orig;)
    2095              :       {
    2096              :         /* Do not attempt to adjust bodies of yet unexpanded thunks.  */
    2097        21554 :         if (!node->thunk)
    2098        21552 :           cgraph_update_edges_for_call_stmt_node (node, old_stmt, old_decl,
    2099              :                                                   new_stmt);
    2100        21554 :         if (node->clones)
    2101              :           node = node->clones;
    2102        21547 :         else if (node->next_sibling_clone)
    2103              :           node = node->next_sibling_clone;
    2104              :         else
    2105              :           {
    2106        42015 :             while (node != orig && !node->next_sibling_clone)
    2107        21011 :               node = node->clone_of;
    2108        21004 :             if (node != orig)
    2109            0 :               node = node->next_sibling_clone;
    2110              :           }
    2111              :       }
    2112        96270 : }
    2113              : 
    2114              : 
    2115              : /* Remove all callees from the node.  */
    2116              : 
    2117              : void
    2118    247208744 : cgraph_node::remove_callees (void)
    2119              : {
    2120    247208744 :   cgraph_edge *e, *f;
    2121              : 
    2122    247208744 :   calls_comdat_local = false;
    2123              : 
    2124              :   /* It is sufficient to remove the edges from the lists of callers of
    2125              :      the callees.  The callee list of the node can be zapped with one
    2126              :      assignment.  */
    2127    286180873 :   for (e = callees; e; e = f)
    2128              :     {
    2129     38972129 :       f = e->next_callee;
    2130     38972129 :       symtab->call_edge_removal_hooks (e);
    2131     38972129 :       if (!e->indirect_unknown_callee)
    2132     38972129 :         e->remove_callee ();
    2133     38972129 :       symtab->free_edge (e);
    2134              :     }
    2135    248042810 :   for (e = indirect_calls; e; e = f)
    2136              :     {
    2137       834066 :       f = e->next_callee;
    2138       834066 :       symtab->call_edge_removal_hooks (e);
    2139       834066 :       if (!e->indirect_unknown_callee)
    2140            0 :         e->remove_callee ();
    2141       834066 :       symtab->free_edge (e);
    2142              :     }
    2143    247208744 :   indirect_calls = NULL;
    2144    247208744 :   callees = NULL;
    2145    247208744 :   if (call_site_hash)
    2146              :     {
    2147        30585 :       call_site_hash->empty ();
    2148        30585 :       call_site_hash = NULL;
    2149              :     }
    2150    247208744 : }
    2151              : 
    2152              : /* Remove all callers from the node.  */
    2153              : 
    2154              : void
    2155    112339309 : cgraph_node::remove_callers (void)
    2156              : {
    2157    112339309 :   cgraph_edge *e, *f;
    2158              : 
    2159              :   /* It is sufficient to remove the edges from the lists of callees of
    2160              :      the callers.  The caller list of the node can be zapped with one
    2161              :      assignment.  */
    2162    116694221 :   for (e = callers; e; e = f)
    2163              :     {
    2164      4354912 :       f = e->next_caller;
    2165              :       /* When removing a callback-carrying edge, remove all its attached edges
    2166              :          as well.  */
    2167      4354912 :       if (e->has_callback)
    2168              :         {
    2169            1 :           cgraph_edge *cbe, *next_cbe = NULL;
    2170            1 :           for (cbe = e->first_callback_edge (); cbe; cbe = next_cbe)
    2171              :             {
    2172            0 :               next_cbe = cbe->next_callback_edge ();
    2173            0 :               cgraph_edge::remove (cbe);
    2174              :             }
    2175              :         }
    2176      4354912 :       symtab->call_edge_removal_hooks (e);
    2177      4354912 :       e->remove_caller ();
    2178      4354912 :       symtab->free_edge (e);
    2179              :     }
    2180    112339309 :   callers = NULL;
    2181    112339309 : }
    2182              : 
    2183              : /* Helper function for cgraph_release_function_body and free_lang_data.
    2184              :    It releases body from function DECL without having to inspect its
    2185              :    possibly non-existent symtab node.  */
    2186              : 
    2187              : void
    2188    122544694 : release_function_body (tree decl)
    2189              : {
    2190    122544694 :   function *fn = DECL_STRUCT_FUNCTION (decl);
    2191    122544694 :   if (fn)
    2192              :     {
    2193    110939527 :       if (fn->cfg
    2194    110939527 :           && loops_for_fn (fn))
    2195              :         {
    2196      1671244 :           fn->curr_properties &= ~PROP_loops;
    2197      1671244 :           loop_optimizer_finalize (fn);
    2198              :         }
    2199    110939527 :       if (fn->gimple_df)
    2200              :         {
    2201      1679885 :           delete_tree_ssa (fn);
    2202      1679885 :           fn->eh = NULL;
    2203              :         }
    2204    110939527 :       if (fn->cfg)
    2205              :         {
    2206      1671245 :           gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
    2207      1671245 :           gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
    2208      1671245 :           delete_tree_cfg_annotations (fn);
    2209      1671245 :           free_cfg (fn);
    2210      1671245 :           fn->cfg = NULL;
    2211              :         }
    2212    110939527 :       if (fn->value_histograms)
    2213           12 :         free_histograms (fn);
    2214    110939527 :       gimple_set_body (decl, NULL);
    2215              :       /* Struct function hangs a lot of data that would leak if we didn't
    2216              :          removed all pointers to it.   */
    2217    110939527 :       ggc_free (fn);
    2218    110939527 :       DECL_STRUCT_FUNCTION (decl) = NULL;
    2219              :     }
    2220    122544694 :   DECL_SAVED_TREE (decl) = NULL;
    2221    122544694 : }
    2222              : 
    2223              : /* Release memory used to represent body of function.
    2224              :    Use this only for functions that are released before being translated to
    2225              :    target code (i.e. RTL).  Functions that are compiled to RTL and beyond
    2226              :    are free'd in final.cc via free_after_compilation().
    2227              :    KEEP_ARGUMENTS are useful only if you want to rebuild body as thunk.  */
    2228              : 
    2229              : void
    2230    122533208 : cgraph_node::release_body (bool keep_arguments)
    2231              : {
    2232    122533208 :   ipa_transforms_to_apply.release ();
    2233    122533208 :   if (!used_as_abstract_origin && symtab->state != PARSING)
    2234              :     {
    2235    121971841 :       DECL_RESULT (decl) = NULL;
    2236              : 
    2237    121971841 :       if (!keep_arguments)
    2238    121941081 :         DECL_ARGUMENTS (decl) = NULL;
    2239              :     }
    2240              :   /* If the node is abstract and needed, then do not clear
    2241              :      DECL_INITIAL of its associated function declaration because it's
    2242              :      needed to emit debug info later.  */
    2243    122533208 :   if (!used_as_abstract_origin && DECL_INITIAL (decl))
    2244    110432040 :     DECL_INITIAL (decl) = error_mark_node;
    2245    122533208 :   release_function_body (decl);
    2246    122533208 :   lto_free_function_in_decl_state_for_node (this);
    2247    122533208 :   if (flag_checking && clones)
    2248              :     {
    2249              :       /* It is invalid to release body before materializing clones except
    2250              :          for thunks that don't really need a body.  Verify also that we do
    2251              :          not leak pointers to the call statements.  */
    2252           33 :       for (cgraph_node *node = clones; node;
    2253           18 :            node = node->next_sibling_clone)
    2254           18 :         gcc_assert (node->thunk && !node->callees->call_stmt);
    2255              :     }
    2256    122533208 :   remove_callees ();
    2257    122533208 :   remove_all_references ();
    2258    122533208 : }
    2259              : 
    2260              : /* Remove function from symbol table.  */
    2261              : 
    2262              : void
    2263    112339309 : cgraph_node::remove (void)
    2264              : {
    2265    112339309 :   bool clone_info_set = false;
    2266    112339309 :   clone_info *info, saved_info;
    2267    112339309 :   if (symtab->ipa_clones_dump_file && symtab->cloned_nodes.contains (this))
    2268            4 :     fprintf (symtab->ipa_clones_dump_file,
    2269              :              "Callgraph removal;%s;%d;%s;%d;%d\n", asm_name (), get_uid (),
    2270            4 :              DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
    2271            8 :              DECL_SOURCE_COLUMN (decl));
    2272              : 
    2273    112339309 :   if ((info = clone_info::get (this)) != NULL)
    2274              :     {
    2275       349249 :       saved_info = *info;
    2276       349249 :       clone_info_set = true;
    2277              :     }
    2278    112339309 :   symtab->call_cgraph_removal_hooks (this);
    2279    112339309 :   remove_callers ();
    2280    112339309 :   remove_callees ();
    2281    112339309 :   ipa_transforms_to_apply.release ();
    2282    112339309 :   delete_function_version (function_version ());
    2283              : 
    2284              :   /* Incremental inlining access removed nodes stored in the postorder list.
    2285              :      */
    2286    112339309 :   force_output = false;
    2287    112339309 :   forced_by_abi = false;
    2288              : 
    2289    224329369 :   unregister (clone_info_set ? &saved_info : NULL);
    2290    112339309 :   if (prev_sibling_clone)
    2291       714789 :     prev_sibling_clone->next_sibling_clone = next_sibling_clone;
    2292    111624520 :   else if (clone_of)
    2293              :     {
    2294      1765311 :       clone_of->clones = next_sibling_clone;
    2295      1765311 :       if (!clones)
    2296              :         {
    2297      1759574 :           bool need_body = false;
    2298      1759574 :           for (cgraph_node *n = clone_of; n; n = n->clone_of)
    2299      1756579 :             if (n->analyzed || n->clones)
    2300              :               {
    2301              :                 need_body = true;
    2302              :                 break;
    2303              :               }
    2304      1756575 :           if (!need_body)
    2305         2995 :             clone_of->release_body ();
    2306              :         }
    2307              :     }
    2308    112339309 :   if (next_sibling_clone)
    2309       918238 :     next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
    2310    112339309 :   if (clones)
    2311              :     {
    2312        40330 :       cgraph_node *n, *next;
    2313              : 
    2314        40330 :       if (clone_of)
    2315              :         {
    2316       179338 :           for (n = clones; n->next_sibling_clone; n = n->next_sibling_clone)
    2317       139008 :             n->clone_of = clone_of;
    2318        40330 :           n->clone_of = clone_of;
    2319        40330 :           n->next_sibling_clone = clone_of->clones;
    2320        40330 :           if (clone_of->clones)
    2321        35412 :             clone_of->clones->prev_sibling_clone = n;
    2322        40330 :           clone_of->clones = clones;
    2323              :         }
    2324              :       else
    2325              :         {
    2326              :           /* We are removing node with clones.  This makes clones inconsistent,
    2327              :              but assume they will be removed subsequently and just keep clone
    2328              :              tree intact.  This can happen in unreachable function removal since
    2329              :              we remove unreachable functions in random order, not by bottom-up
    2330              :              walk of clone trees.  */
    2331            0 :           for (n = clones; n; n = next)
    2332              :             {
    2333            0 :                next = n->next_sibling_clone;
    2334            0 :                n->next_sibling_clone = NULL;
    2335            0 :                n->prev_sibling_clone = NULL;
    2336            0 :                n->clone_of = NULL;
    2337              :             }
    2338              :         }
    2339              :     }
    2340              : 
    2341              :   /* While all the clones are removed after being proceeded, the function
    2342              :      itself is kept in the cgraph even after it is compiled.  Check whether
    2343              :      we are done with this body and reclaim it proactively if this is the case.
    2344              :      */
    2345    112339309 :   if (symtab->state != LTO_STREAMING)
    2346              :     {
    2347    112337246 :       cgraph_node *n = cgraph_node::get (decl);
    2348    112337246 :       if (!n
    2349    112337246 :           || (!n->clones && !n->clone_of && !n->inlined_to
    2350      1104331 :               && ((symtab->global_info_ready || in_lto_p)
    2351         7640 :                   && (TREE_ASM_WRITTEN (n->decl)
    2352         7618 :                       || DECL_EXTERNAL (n->decl)
    2353         5376 :                       || !n->analyzed
    2354         5158 :                       || (!flag_wpa && n->in_other_partition)))))
    2355    109461918 :         release_body ();
    2356              :     }
    2357              :   else
    2358         2063 :     lto_free_function_in_decl_state_for_node (this);
    2359              : 
    2360    112339309 :   decl = NULL;
    2361    112339309 :   if (call_site_hash)
    2362              :     {
    2363            0 :       call_site_hash->empty ();
    2364            0 :       call_site_hash = NULL;
    2365              :     }
    2366              : 
    2367    112339309 :   symtab->release_symbol (this);
    2368    112339309 : }
    2369              : 
    2370              : /* Likewise indicate that a node is having address taken.  */
    2371              : 
    2372              : void
    2373      4603796 : cgraph_node::mark_address_taken (void)
    2374              : {
    2375              :   /* Indirect inlining can figure out that all uses of the address are
    2376              :      inlined.  */
    2377      4603796 :   if (inlined_to)
    2378              :     {
    2379            0 :       gcc_assert (cfun->after_inlining);
    2380            0 :       gcc_assert (callers->indirect_inlining_edge);
    2381              :       return;
    2382              :     }
    2383              :   /* FIXME: address_taken flag is used both as a shortcut for testing whether
    2384              :      IPA_REF_ADDR reference exists (and thus it should be set on node
    2385              :      representing alias we take address of) and as a test whether address
    2386              :      of the object was taken (and thus it should be set on node alias is
    2387              :      referring to).  We should remove the first use and the remove the
    2388              :      following set.  */
    2389      4603796 :   address_taken = 1;
    2390      4603796 :   cgraph_node *node = ultimate_alias_target ();
    2391      4603796 :   node->address_taken = 1;
    2392              : }
    2393              : 
    2394              : /* Return local info node for the compiled function.  */
    2395              : 
    2396              : cgraph_node *
    2397     12526310 : cgraph_node::local_info_node (tree decl)
    2398              : {
    2399     12526310 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
    2400     12526310 :   cgraph_node *node = get (decl);
    2401     12526310 :   if (!node)
    2402              :     return NULL;
    2403     12526310 :   return node->ultimate_alias_target ();
    2404              : }
    2405              : 
    2406              : /* Return RTL info for the compiled function.  */
    2407              : 
    2408              : cgraph_rtl_info *
    2409     59711425 : cgraph_node::rtl_info (const_tree decl)
    2410              : {
    2411     59711425 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
    2412     59711425 :   cgraph_node *node = get (decl);
    2413     59711425 :   if (!node)
    2414              :     return NULL;
    2415     59571584 :   enum availability avail;
    2416     59571584 :   node = node->ultimate_alias_target (&avail);
    2417     59571584 :   if (decl != current_function_decl
    2418     56560778 :       && (avail < AVAIL_AVAILABLE
    2419     51440744 :           || (node->decl != current_function_decl
    2420     51367068 :               && !TREE_ASM_WRITTEN (node->decl))))
    2421              :     return NULL;
    2422              :   /* Allocate if it doesn't exist.  */
    2423     50922366 :   if (node->rtl == NULL)
    2424              :     {
    2425      1345153 :       node->rtl = ggc_cleared_alloc<cgraph_rtl_info> ();
    2426      1345153 :       SET_HARD_REG_SET (node->rtl->function_used_regs);
    2427              :     }
    2428     50922366 :   return node->rtl;
    2429              : }
    2430              : 
    2431              : /* Return a string describing the failure REASON.  */
    2432              : 
    2433              : const char*
    2434         9866 : cgraph_inline_failed_string (cgraph_inline_failed_t reason)
    2435              : {
    2436              : #undef DEFCIFCODE
    2437              : #define DEFCIFCODE(code, type, string)  string,
    2438              : 
    2439         9866 :   static const char *cif_string_table[CIF_N_REASONS] = {
    2440              : #include "cif-code.def"
    2441              :   };
    2442              : 
    2443              :   /* Signedness of an enum type is implementation defined, so cast it
    2444              :      to unsigned before testing. */
    2445         9866 :   gcc_assert ((unsigned) reason < CIF_N_REASONS);
    2446         9866 :   return cif_string_table[reason];
    2447              : }
    2448              : 
    2449              : /* Return a type describing the failure REASON.  */
    2450              : 
    2451              : cgraph_inline_failed_type_t
    2452     71589918 : cgraph_inline_failed_type (cgraph_inline_failed_t reason)
    2453              : {
    2454              : #undef DEFCIFCODE
    2455              : #define DEFCIFCODE(code, type, string)  type,
    2456              : 
    2457     71589918 :   static cgraph_inline_failed_type_t cif_type_table[CIF_N_REASONS] = {
    2458              : #include "cif-code.def"
    2459              :   };
    2460              : 
    2461              :   /* Signedness of an enum type is implementation defined, so cast it
    2462              :      to unsigned before testing. */
    2463     71589918 :   gcc_assert ((unsigned) reason < CIF_N_REASONS);
    2464     71589918 :   return cif_type_table[reason];
    2465              : }
    2466              : 
    2467              : /* Names used to print out the availability enum.  */
    2468              : const char * const cgraph_availability_names[] =
    2469              :   {"unset", "not_available", "overwritable", "available", "local"};
    2470              : 
    2471              : /* Output flags of edge to a file F.  */
    2472              : 
    2473              : void
    2474        21998 : cgraph_edge::dump_edge_flags (FILE *f)
    2475              : {
    2476        21998 :   if (speculative)
    2477          220 :     fprintf (f, "(speculative) ");
    2478        21998 :   if (callback)
    2479            4 :     fprintf (f, "(callback) ");
    2480        21998 :   if (has_callback)
    2481            6 :     fprintf (f, "(has_callback) ");
    2482        21998 :   if (!inline_failed)
    2483         1793 :     fprintf (f, "(inlined) ");
    2484        21998 :   if (call_stmt_cannot_inline_p)
    2485            0 :     fprintf (f, "(call_stmt_cannot_inline_p) ");
    2486        21998 :   if (indirect_inlining_edge)
    2487          325 :     fprintf (f, "(indirect_inlining) ");
    2488        21998 :   if (count.initialized_p ())
    2489              :     {
    2490        21425 :       fprintf (f, "(");
    2491        21425 :       count.dump (f);
    2492        21425 :       fprintf (f, ",");
    2493        21425 :       fprintf (f, "%.2f per call) ", sreal_frequency ().to_double ());
    2494              :     }
    2495        21998 :   if (can_throw_external)
    2496         2286 :     fprintf (f, "(can throw external) ");
    2497        21998 : }
    2498              : 
    2499              : /* Dump edge to stderr.  */
    2500              : 
    2501              : void
    2502            0 : cgraph_edge::debug (void)
    2503              : {
    2504            0 :   fprintf (stderr, "%s -> %s ", caller->dump_asm_name (),
    2505            0 :            callee == NULL ? "(null)" : callee->dump_asm_name ());
    2506            0 :   dump_edge_flags (stderr);
    2507            0 :   fprintf (stderr, "\n\n");
    2508            0 :   caller->debug ();
    2509            0 :   if (callee != NULL)
    2510            0 :     callee->debug ();
    2511            0 : }
    2512              : 
    2513              : /* Dump call graph node to file F.  */
    2514              : 
    2515              : void
    2516         5911 : cgraph_node::dump (FILE *f)
    2517              : {
    2518         5911 :   cgraph_edge *edge;
    2519              : 
    2520         5911 :   dump_base (f);
    2521              : 
    2522         5911 :   if (inlined_to)
    2523          778 :     fprintf (f, "  Function %s is inline copy in %s\n",
    2524              :              dump_name (),
    2525              :              inlined_to->dump_name ());
    2526         5911 :   if (clone_of)
    2527          788 :     fprintf (f, "  Clone of %s\n", clone_of->dump_asm_name ());
    2528         5911 :   if (symtab->function_flags_ready)
    2529        10686 :     fprintf (f, "  Availability: %s\n",
    2530         5343 :              cgraph_availability_names [get_availability ()]);
    2531              : 
    2532         5911 :   if (profile_id)
    2533          155 :     fprintf (f, "  Profile id: %i\n",
    2534              :              profile_id);
    2535         5911 :   if (unit_id)
    2536          151 :     fprintf (f, "  Unit id: %i\n",
    2537              :              unit_id);
    2538         5911 :   cgraph_function_version_info *vi = function_version ();
    2539         5911 :   if (vi != NULL)
    2540              :     {
    2541            0 :       fprintf (f, "  Version info: ");
    2542            0 :       if (vi->prev != NULL)
    2543              :         {
    2544            0 :           fprintf (f, "prev: ");
    2545            0 :           fprintf (f, "%s ", vi->prev->this_node->dump_asm_name ());
    2546              :         }
    2547            0 :       if (vi->next != NULL)
    2548              :         {
    2549            0 :           fprintf (f, "next: ");
    2550            0 :           fprintf (f, "%s ", vi->next->this_node->dump_asm_name ());
    2551              :         }
    2552            0 :       if (vi->dispatcher_resolver != NULL_TREE)
    2553            0 :         fprintf (f, "dispatcher: %s",
    2554            0 :                  lang_hooks.decl_printable_name (vi->dispatcher_resolver, 2));
    2555              : 
    2556            0 :       fprintf (f, "\n");
    2557              :     }
    2558         5911 :   fprintf (f, "  Function flags:");
    2559         5911 :   if (count.initialized_p ())
    2560              :     {
    2561         3668 :       fprintf (f, " count:");
    2562         3668 :       count.dump (f);
    2563              :     }
    2564         5911 :   if (tp_first_run > 0)
    2565           70 :     fprintf (f, " first_run:%" PRId64, (int64_t) tp_first_run);
    2566         5911 :   if (cgraph_node *origin = nested_function_origin (this))
    2567            0 :     fprintf (f, " nested in:%s", origin->dump_asm_name ());
    2568         5911 :   if (gimple_has_body_p (decl))
    2569         3864 :     fprintf (f, " body");
    2570         5911 :   if (process)
    2571            0 :     fprintf (f, " process");
    2572         5911 :   if (local)
    2573         1169 :     fprintf (f, " local");
    2574         5911 :   if (redefined_extern_inline)
    2575            0 :     fprintf (f, " redefined_extern_inline");
    2576         5911 :   if (only_called_at_startup)
    2577          403 :     fprintf (f, " only_called_at_startup");
    2578         5911 :   if (only_called_at_exit)
    2579            7 :     fprintf (f, " only_called_at_exit");
    2580         5911 :   if (tm_clone)
    2581            0 :     fprintf (f, " tm_clone");
    2582         5911 :   if (calls_comdat_local)
    2583            9 :     fprintf (f, " calls_comdat_local");
    2584         5911 :   if (icf_merged)
    2585           24 :     fprintf (f, " icf_merged");
    2586         5911 :   if (merged_comdat)
    2587            0 :     fprintf (f, " merged_comdat");
    2588         5911 :   if (merged_extern_inline)
    2589            0 :     fprintf (f, " merged_extern_inline");
    2590         5911 :   if (split_part)
    2591           23 :     fprintf (f, " split_part");
    2592         5911 :   if (indirect_call_target)
    2593          213 :     fprintf (f, " indirect_call_target");
    2594         5911 :   if (nonfreeing_fn)
    2595          343 :     fprintf (f, " nonfreeing_fn");
    2596         5911 :   if (DECL_STATIC_CONSTRUCTOR (decl))
    2597           48 :     fprintf (f," static_constructor (priority:%i)", get_init_priority ());
    2598         5911 :   if (DECL_STATIC_DESTRUCTOR (decl))
    2599            7 :     fprintf (f," static_destructor (priority:%i)", get_fini_priority ());
    2600         5911 :   if (frequency == NODE_FREQUENCY_HOT)
    2601           62 :     fprintf (f, " hot");
    2602         5911 :   if (frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
    2603           40 :     fprintf (f, " unlikely_executed");
    2604         5911 :   if (frequency == NODE_FREQUENCY_EXECUTED_ONCE)
    2605          702 :     fprintf (f, " executed_once");
    2606         5911 :   if (opt_for_fn (decl, optimize_size))
    2607          176 :     fprintf (f, " optimize_size");
    2608         5911 :   if (parallelized_function)
    2609            4 :     fprintf (f, " parallelized_function");
    2610         5911 :   if (DECL_IS_MALLOC (decl))
    2611           72 :     fprintf (f, " decl_is_malloc");
    2612         5911 :   if (DECL_IS_OPERATOR_NEW_P (decl))
    2613           35 :     fprintf (f, " %soperator_new",
    2614           35 :              DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
    2615         5911 :   if (DECL_IS_OPERATOR_DELETE_P (decl))
    2616           26 :     fprintf (f, " %soperator_delete",
    2617           26 :              DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
    2618              : 
    2619         5911 :   if (DECL_STATIC_CHAIN (decl))
    2620            6 :     fprintf (f, " static_chain");
    2621              : 
    2622         5911 :   fprintf (f, "\n");
    2623              : 
    2624         5911 :   if (thunk)
    2625              :     {
    2626           49 :       fprintf (f, "  Thunk");
    2627           49 :       thunk_info::get (this)->dump (f);
    2628              :     }
    2629         5862 :   else if (former_thunk_p ())
    2630              :     {
    2631           21 :       fprintf (f, "  Former thunk ");
    2632           21 :       thunk_info::get (this)->dump (f);
    2633              :     }
    2634         5841 :   else gcc_checking_assert (!thunk_info::get (this));
    2635              : 
    2636         5911 :   fprintf (f, "  Called by: ");
    2637              : 
    2638         5911 :   profile_count sum = profile_count::zero ();
    2639        13662 :   for (edge = callers; edge; edge = edge->next_caller)
    2640              :     {
    2641         7751 :       fprintf (f, "%s ", edge->caller->dump_asm_name ());
    2642         7751 :       edge->dump_edge_flags (f);
    2643         7751 :       if (edge->count.initialized_p ())
    2644         7491 :         sum += edge->count.ipa ();
    2645              :     }
    2646              : 
    2647         5911 :   fprintf (f, "\n  Calls: ");
    2648        20158 :   for (edge = callees; edge; edge = edge->next_callee)
    2649              :     {
    2650        14247 :       fprintf (f, "%s ", edge->callee->dump_asm_name ());
    2651        14247 :       edge->dump_edge_flags (f);
    2652              :     }
    2653         5911 :   fprintf (f, "\n");
    2654              : 
    2655         5911 :   if (!body_removed && count.ipa ().initialized_p ())
    2656              :     {
    2657          110 :       bool ok = true;
    2658          110 :       bool min = false;
    2659              :       ipa_ref *ref;
    2660              : 
    2661          110 :       FOR_EACH_ALIAS (this, ref)
    2662            0 :         if (dyn_cast <cgraph_node *> (ref->referring)->count.initialized_p ())
    2663            0 :           sum += dyn_cast <cgraph_node *> (ref->referring)->count.ipa ();
    2664              : 
    2665          110 :       if (inlined_to
    2666          110 :           || (symtab->state < EXPANSION
    2667          110 :               && ultimate_alias_target () == this && only_called_directly_p ()))
    2668            3 :         ok = !count.ipa ().differs_from_p (sum);
    2669          107 :       else if (count.ipa () > profile_count::from_gcov_type (100)
    2670          107 :                && count.ipa () < sum.apply_scale (99, 100))
    2671            0 :         ok = false, min = true;
    2672          110 :       if (!ok)
    2673              :         {
    2674            0 :           fprintf (f, "   Invalid sum of caller counts ");
    2675            0 :           sum.dump (f);
    2676            0 :           if (min)
    2677            0 :             fprintf (f, ", should be at most ");
    2678              :           else
    2679            0 :             fprintf (f, ", should be ");
    2680            0 :           count.ipa ().dump (f);
    2681            0 :           fprintf (f, "\n");
    2682              :         }
    2683              :     }
    2684              : 
    2685         6677 :   for (edge = indirect_calls; edge; edge = edge->next_callee)
    2686              :     {
    2687          766 :       fprintf (f, "   ");
    2688          766 :       edge->indirect_info->dump (f);
    2689              :     }
    2690         5911 : }
    2691              : 
    2692              : /* Dump call graph node to file F in graphviz format.  */
    2693              : 
    2694              : void
    2695            0 : cgraph_node::dump_graphviz (FILE *f)
    2696              : {
    2697            0 :   cgraph_edge *edge;
    2698              : 
    2699            0 :   for (edge = callees; edge; edge = edge->next_callee)
    2700              :     {
    2701            0 :       cgraph_node *callee = edge->callee;
    2702              : 
    2703            0 :       fprintf (f, "\t\"%s\" -> \"%s\"\n", dump_name (), callee->dump_name ());
    2704              :     }
    2705            0 : }
    2706              : 
    2707              : 
    2708              : /* Dump call graph node NODE to stderr.  */
    2709              : 
    2710              : DEBUG_FUNCTION void
    2711            0 : cgraph_node::debug (void)
    2712              : {
    2713            0 :   dump (stderr);
    2714            0 : }
    2715              : 
    2716              : /* Dump the callgraph to file F.  */
    2717              : 
    2718              : void
    2719           77 : cgraph_node::dump_cgraph (FILE *f)
    2720              : {
    2721           77 :   cgraph_node *node;
    2722              : 
    2723           77 :   fprintf (f, "callgraph:\n\n");
    2724          362 :   FOR_EACH_FUNCTION (node)
    2725          285 :     node->dump (f);
    2726           77 : }
    2727              : 
    2728              : /* Dump human readable information about the indirect call to F.  If NEWLINE
    2729              :    is true, it will be terminated by a newline.  */
    2730              : 
    2731              : void
    2732          913 : cgraph_indirect_call_info::dump (FILE *f, bool newline) const
    2733              : {
    2734          913 :   if (const cgraph_polymorphic_indirect_info *pii
    2735          913 :       = dyn_cast <const cgraph_polymorphic_indirect_info *> (this))
    2736              :     {
    2737          512 :       fprintf (f, "    indirect polymorphic callsite, %s, "
    2738              :                "calling param %i, offset " HOST_WIDE_INT_PRINT_DEC
    2739              :                "otr_token " HOST_WIDE_INT_PRINT_DEC ", otr_type ",
    2740          512 :                pii->vptr_changed ? "vptr_changed" : "vptr not changed",
    2741          512 :                pii->param_index, pii->offset, pii->otr_token);
    2742          512 :       print_generic_expr (f, pii->otr_type);
    2743          512 :       fprintf (f, ", context ");
    2744          512 :       pii->context.dump (f, false);
    2745              :     }
    2746          401 :   else if (const cgraph_simple_indirect_info *sii
    2747          401 :            = dyn_cast <const cgraph_simple_indirect_info *> (this))
    2748              :     {
    2749          401 :       if (sii->agg_contents)
    2750           49 :         fprintf (f, "    indirect %s callsite, calling param %i, "
    2751              :                  "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
    2752           49 :                  sii->member_ptr ? "member ptr" : "aggregate",
    2753           49 :                  sii->param_index, sii->offset,
    2754           49 :                  sii->by_ref ? "by reference" : "by_value");
    2755          352 :       else if (sii->param_index >= 0)
    2756            7 :         fprintf (f, "    indirect simple callsite, calling param %i",
    2757              :                  sii->param_index);
    2758              :       else
    2759          345 :         fprintf (f, "    indirect simple callsite, not calling a known "
    2760              :                  "parameter");
    2761              :     }
    2762              :   else
    2763            0 :     fprintf (f, "    indirect callsite");
    2764              : 
    2765          913 :   fprintf (f, ", flags %i, num speculative call targets: %i", ecf_flags,
    2766          913 :            num_speculative_call_targets);
    2767          913 :   if (newline)
    2768          766 :     fprintf (f, "\n");
    2769          913 : }
    2770              : 
    2771              : /* Dump human readable information about the indirect call to stderr.  */
    2772              : 
    2773              : void
    2774            0 : cgraph_indirect_call_info::debug () const
    2775              : {
    2776            0 :   dump (stderr);
    2777            0 : }
    2778              : 
    2779              : /* Return true when the DECL can possibly be inlined.  */
    2780              : 
    2781              : bool
    2782    101569470 : cgraph_function_possibly_inlined_p (tree decl)
    2783              : {
    2784    101569470 :   if (!symtab->global_info_ready)
    2785     94133422 :     return !DECL_UNINLINABLE (decl);
    2786      7436048 :   return DECL_POSSIBLY_INLINED (decl);
    2787              : }
    2788              : 
    2789              : /* Return function availability.  See cgraph.h for description of individual
    2790              :    return values.  */
    2791              : enum availability
    2792    807561084 : cgraph_node::get_availability (symtab_node *ref)
    2793              : {
    2794    807561084 :   if (ref)
    2795              :     {
    2796    564858947 :       cgraph_node *cref = dyn_cast <cgraph_node *> (ref);
    2797    564858947 :       if (cref)
    2798    564858947 :         ref = cref->inlined_to;
    2799              :     }
    2800    807561084 :   enum availability avail;
    2801    807561084 :   if (!analyzed && !in_other_partition)
    2802    482442634 :     avail = AVAIL_NOT_AVAILABLE;
    2803    325118450 :   else if (local)
    2804     93812523 :     avail = AVAIL_LOCAL;
    2805    231305927 :   else if (inlined_to)
    2806      2118042 :     avail = AVAIL_AVAILABLE;
    2807    229187885 :   else if (transparent_alias)
    2808          134 :     ultimate_alias_target (&avail, ref);
    2809    229187751 :   else if (ifunc_resolver
    2810    229187751 :            || lookup_attribute ("noipa", DECL_ATTRIBUTES (decl)))
    2811      3487021 :     avail = AVAIL_INTERPOSABLE;
    2812    225700730 :   else if (!externally_visible)
    2813     24567359 :     avail = AVAIL_AVAILABLE;
    2814              :   /* If this is a reference from symbol itself and there are no aliases, we
    2815              :      may be sure that the symbol was not interposed by something else because
    2816              :      the symbol itself would be unreachable otherwise.
    2817              : 
    2818              :      Also comdat groups are always resolved in groups.  */
    2819        19498 :   else if ((this == ref && !has_aliases_p ())
    2820    201134151 :            || (ref && get_comdat_group ()
    2821      1318605 :                && get_comdat_group () == ref->get_comdat_group ()))
    2822        22226 :     avail = AVAIL_AVAILABLE;
    2823              :   /* Inline functions are safe to be analyzed even if their symbol can
    2824              :      be overwritten at runtime.  It is not meaningful to enforce any sane
    2825              :      behavior on replacing inline function by different body.  */
    2826    201111145 :   else if (DECL_DECLARED_INLINE_P (decl))
    2827     74182726 :     avail = AVAIL_AVAILABLE;
    2828              : 
    2829              :   /* If the function can be overwritten, return OVERWRITABLE.  Take
    2830              :      care at least of two notable extensions - the COMDAT functions
    2831              :      used to share template instantiations in C++ (this is symmetric
    2832              :      to code cp_cannot_inline_tree_fn and probably shall be shared and
    2833              :      the inlinability hooks completely eliminated).  */
    2834              : 
    2835    126928419 :   else if (decl_replaceable_p (decl, semantic_interposition)
    2836    126928419 :            && !DECL_EXTERNAL (decl))
    2837      9291204 :     avail = AVAIL_INTERPOSABLE;
    2838    117637215 :   else avail = AVAIL_AVAILABLE;
    2839              : 
    2840    807561084 :   return avail;
    2841              : }
    2842              : 
    2843              : /* Worker for cgraph_node_can_be_local_p.  */
    2844              : static bool
    2845       916658 : cgraph_node_cannot_be_local_p_1 (cgraph_node *node, void *)
    2846              : {
    2847       916658 :   return !(!node->force_output
    2848       895783 :            && !node->ref_by_asm
    2849       895779 :            && !node->ifunc_resolver
    2850              :            /* Limitation of gas requires us to output targets of symver aliases
    2851              :               as global symbols.  This is binutils PR 25295.  */
    2852       895739 :            && !node->symver
    2853       895739 :            && ((DECL_COMDAT (node->decl)
    2854       444523 :                 && !node->forced_by_abi
    2855       426084 :                 && !node->used_from_object_file_p ()
    2856       426084 :                 && !node->same_comdat_group)
    2857       536279 :                || !node->externally_visible)
    2858       508686 :            && !DECL_STATIC_CONSTRUCTOR (node->decl)
    2859       506896 :            && !DECL_STATIC_DESTRUCTOR (node->decl));
    2860              : }
    2861              : 
    2862              : /* Return true if cgraph_node can be made local for API change.
    2863              :    Extern inline functions and C++ COMDAT functions can be made local
    2864              :    at the expense of possible code size growth if function is used in multiple
    2865              :    compilation units.  */
    2866              : bool
    2867      1209028 : cgraph_node::can_be_local_p (void)
    2868              : {
    2869      1209028 :   return (!address_taken
    2870      1209028 :           && !call_for_symbol_thunks_and_aliases (cgraph_node_cannot_be_local_p_1,
    2871      1209028 :                                                 NULL, true));
    2872              : }
    2873              : 
    2874              : /* Call callback on cgraph_node, thunks and aliases associated to cgraph_node.
    2875              :    When INCLUDE_OVERWRITABLE is false, overwritable symbols are
    2876              :    skipped.  When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
    2877              :    skipped.  */
    2878              : bool
    2879    184377076 : cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
    2880              :                                                    (cgraph_node *, void *),
    2881              :                                                  void *data,
    2882              :                                                  bool include_overwritable,
    2883              :                                                  bool exclude_virtual_thunks)
    2884              : {
    2885    184377076 :   cgraph_edge *e;
    2886    184377076 :   ipa_ref *ref;
    2887    184377076 :   enum availability avail = AVAIL_AVAILABLE;
    2888              : 
    2889    184377076 :   if (include_overwritable
    2890    184377076 :       || (avail = get_availability ()) > AVAIL_INTERPOSABLE)
    2891              :     {
    2892    184365339 :       if (callback (this, data))
    2893              :         return true;
    2894              :     }
    2895    196914883 :   FOR_EACH_ALIAS (this, ref)
    2896              :     {
    2897     17770104 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2898     17770104 :       if (include_overwritable
    2899     17770104 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
    2900     17768799 :         if (alias->call_for_symbol_thunks_and_aliases (callback, data,
    2901              :                                                      include_overwritable,
    2902              :                                                      exclude_virtual_thunks))
    2903              :           return true;
    2904              :     }
    2905    179144779 :   if (avail <= AVAIL_INTERPOSABLE)
    2906              :     return false;
    2907    189187702 :   for (e = callers; e; e = e->next_caller)
    2908     10054660 :     if (e->caller->thunk
    2909         5888 :         && (include_overwritable
    2910         3592 :             || e->caller->get_availability () > AVAIL_INTERPOSABLE)
    2911     10060548 :         && !(exclude_virtual_thunks
    2912           22 :              && thunk_info::get (e->caller)->virtual_offset_p))
    2913         5876 :       if (e->caller->call_for_symbol_thunks_and_aliases (callback, data,
    2914              :                                                        include_overwritable,
    2915              :                                                        exclude_virtual_thunks))
    2916              :         return true;
    2917              : 
    2918              :   return false;
    2919              : }
    2920              : 
    2921              : /* Worker to bring NODE local.  */
    2922              : 
    2923              : bool
    2924            0 : cgraph_node::make_local (cgraph_node *node, void *)
    2925              : {
    2926            0 :   gcc_checking_assert (node->can_be_local_p ());
    2927            0 :   if (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
    2928              :     {
    2929            0 :       node->make_decl_local ();
    2930            0 :       node->set_section (NULL);
    2931            0 :       node->set_comdat_group (NULL);
    2932            0 :       node->externally_visible = false;
    2933            0 :       node->forced_by_abi = false;
    2934            0 :       node->local = true;
    2935            0 :       node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
    2936            0 :                            || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
    2937            0 :                            && !flag_incremental_link);
    2938            0 :       node->resolution = LDPR_PREVAILING_DEF_IRONLY;
    2939            0 :       gcc_assert (node->get_availability () == AVAIL_LOCAL);
    2940              :     }
    2941            0 :   return false;
    2942              : }
    2943              : 
    2944              : /* Bring cgraph node local.  */
    2945              : 
    2946              : void
    2947            0 : cgraph_node::make_local (void)
    2948              : {
    2949            0 :   call_for_symbol_thunks_and_aliases (cgraph_node::make_local, NULL, true);
    2950            0 : }
    2951              : 
    2952              : /* Worker to set nothrow flag.  */
    2953              : 
    2954              : static void
    2955       941235 : set_nothrow_flag_1 (cgraph_node *node, bool nothrow, bool non_call,
    2956              :                     bool *changed)
    2957              : {
    2958       941235 :   cgraph_edge *e;
    2959              : 
    2960       941235 :   if (nothrow && !TREE_NOTHROW (node->decl))
    2961              :     {
    2962              :       /* With non-call exceptions we can't say for sure if other function body
    2963              :          was not possibly optimized to still throw.  */
    2964       941210 :       if (!non_call || node->binds_to_current_def_p ())
    2965              :         {
    2966       935446 :           TREE_NOTHROW (node->decl) = true;
    2967       935446 :           *changed = true;
    2968      2296602 :           for (e = node->callers; e; e = e->next_caller)
    2969      1361156 :             e->can_throw_external = false;
    2970              :         }
    2971              :     }
    2972            0 :   else if (!nothrow && TREE_NOTHROW (node->decl))
    2973              :     {
    2974            0 :       TREE_NOTHROW (node->decl) = false;
    2975            0 :       *changed = true;
    2976              :     }
    2977              :   ipa_ref *ref;
    2978       993220 :   FOR_EACH_ALIAS (node, ref)
    2979              :     {
    2980        51985 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2981        51985 :       if (!nothrow || alias->get_availability () > AVAIL_INTERPOSABLE)
    2982        51560 :         set_nothrow_flag_1 (alias, nothrow, non_call, changed);
    2983              :     }
    2984      2339849 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    2985      1398614 :     if (e->caller->thunk
    2986      1398614 :         && (!nothrow || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    2987          138 :       set_nothrow_flag_1 (e->caller, nothrow, non_call, changed);
    2988       941235 : }
    2989              : 
    2990              : /* Set TREE_NOTHROW on NODE's decl and on aliases of NODE
    2991              :    if any to NOTHROW.  */
    2992              : 
    2993              : bool
    2994       901825 : cgraph_node::set_nothrow_flag (bool nothrow)
    2995              : {
    2996       901825 :   bool changed = false;
    2997       901825 :   bool non_call = opt_for_fn (decl, flag_non_call_exceptions);
    2998              : 
    2999       901825 :   if (!nothrow || get_availability () > AVAIL_INTERPOSABLE)
    3000       889428 :     set_nothrow_flag_1 (this, nothrow, non_call, &changed);
    3001              :   else
    3002              :     {
    3003              :       ipa_ref *ref;
    3004              : 
    3005        19962 :       FOR_EACH_ALIAS (this, ref)
    3006              :         {
    3007         7565 :           cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    3008         7565 :           if (!nothrow || alias->get_availability () > AVAIL_INTERPOSABLE)
    3009          109 :             set_nothrow_flag_1 (alias, nothrow, non_call, &changed);
    3010              :         }
    3011              :     }
    3012       901825 :   return changed;
    3013              : }
    3014              : 
    3015              : /* Worker to set malloc flag.  */
    3016              : static void
    3017        39539 : set_malloc_flag_1 (cgraph_node *node, bool malloc_p, bool *changed)
    3018              : {
    3019        39539 :   if (malloc_p && !DECL_IS_MALLOC (node->decl))
    3020              :     {
    3021        39122 :       DECL_IS_MALLOC (node->decl) = true;
    3022        39122 :       *changed = true;
    3023              :     }
    3024              : 
    3025              :   ipa_ref *ref;
    3026        39540 :   FOR_EACH_ALIAS (node, ref)
    3027              :     {
    3028            1 :       cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    3029            1 :       if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    3030            1 :         set_malloc_flag_1 (alias, malloc_p, changed);
    3031              :     }
    3032              : 
    3033        87202 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3034        47663 :     if (e->caller->thunk
    3035        47663 :         && (!malloc_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    3036            0 :       set_malloc_flag_1 (e->caller, malloc_p, changed);
    3037        39539 : }
    3038              : 
    3039              : /* Set DECL_IS_MALLOC on NODE's decl and on NODE's aliases if any.  */
    3040              : 
    3041              : bool
    3042        39538 : cgraph_node::set_malloc_flag (bool malloc_p)
    3043              : {
    3044        39538 :   bool changed = false;
    3045              : 
    3046        39538 :   if (!malloc_p || get_availability () > AVAIL_INTERPOSABLE)
    3047        39538 :     set_malloc_flag_1 (this, malloc_p, &changed);
    3048              :   else
    3049              :     {
    3050              :       ipa_ref *ref;
    3051              : 
    3052            0 :       FOR_EACH_ALIAS (this, ref)
    3053              :         {
    3054            0 :           cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    3055            0 :           if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    3056            0 :             set_malloc_flag_1 (alias, malloc_p, &changed);
    3057              :         }
    3058              :     }
    3059        39538 :   return changed;
    3060              : }
    3061              : 
    3062              : /* Worker to set malloc flag.  */
    3063              : static void
    3064       248983 : add_detected_attribute_1 (cgraph_node *node, const char *attr, bool *changed)
    3065              : {
    3066       248983 :   if (!lookup_attribute (attr, DECL_ATTRIBUTES (node->decl)))
    3067              :     {
    3068       223568 :       DECL_ATTRIBUTES (node->decl) = tree_cons (get_identifier (attr),
    3069       223568 :                                          NULL_TREE, DECL_ATTRIBUTES (node->decl));
    3070       223568 :       *changed = true;
    3071              :     }
    3072              : 
    3073              :   ipa_ref *ref;
    3074       249523 :   FOR_EACH_ALIAS (node, ref)
    3075              :     {
    3076          540 :       cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    3077          540 :       if (alias->get_availability () > AVAIL_INTERPOSABLE)
    3078          131 :         add_detected_attribute_1 (alias, attr, changed);
    3079              :     }
    3080              : 
    3081       779464 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3082       530481 :     if (e->caller->thunk
    3083       530481 :         && (e->caller->get_availability () > AVAIL_INTERPOSABLE))
    3084           14 :       add_detected_attribute_1 (e->caller, attr, changed);
    3085       248983 : }
    3086              : 
    3087              : /* Add attribyte ATTR to function and its aliases.  */
    3088              : 
    3089              : bool
    3090       252610 : cgraph_node::add_detected_attribute (const char *attr)
    3091              : {
    3092       252610 :   bool changed = false;
    3093              : 
    3094       252610 :   if (get_availability () > AVAIL_INTERPOSABLE)
    3095       248838 :     add_detected_attribute_1 (this, attr, &changed);
    3096              :   else
    3097              :     {
    3098              :       ipa_ref *ref;
    3099              : 
    3100         3796 :       FOR_EACH_ALIAS (this, ref)
    3101              :         {
    3102           24 :           cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    3103           24 :           if (alias->get_availability () > AVAIL_INTERPOSABLE)
    3104            0 :             add_detected_attribute_1 (alias, attr, &changed);
    3105              :         }
    3106              :     }
    3107       252610 :   return changed;
    3108              : }
    3109              : 
    3110              : /* Worker to set noreturng flag.  */
    3111              : static void
    3112        27344 : set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed)
    3113              : {
    3114        27344 :   if (noreturn_p && !TREE_THIS_VOLATILE (node->decl))
    3115              :     {
    3116        27344 :       TREE_THIS_VOLATILE (node->decl) = true;
    3117        27344 :       *changed = true;
    3118              :     }
    3119              : 
    3120              :   ipa_ref *ref;
    3121        27989 :   FOR_EACH_ALIAS (node, ref)
    3122              :     {
    3123          645 :       cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    3124          645 :       if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    3125          645 :         set_noreturn_flag_1 (alias, noreturn_p, changed);
    3126              :     }
    3127              : 
    3128        43585 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3129        16241 :     if (e->caller->thunk
    3130        16241 :         && (!noreturn_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    3131           20 :       set_noreturn_flag_1 (e->caller, noreturn_p, changed);
    3132        27344 : }
    3133              : 
    3134              : /* Set TREE_THIS_VOLATILE on NODE's decl and on NODE's aliases if any.  */
    3135              : 
    3136              : bool
    3137        26839 : cgraph_node::set_noreturn_flag (bool noreturn_p)
    3138              : {
    3139        26839 :   bool changed = false;
    3140              : 
    3141        26839 :   if (!noreturn_p || get_availability () > AVAIL_INTERPOSABLE)
    3142        26670 :     set_noreturn_flag_1 (this, noreturn_p, &changed);
    3143              :   else
    3144              :     {
    3145              :       ipa_ref *ref;
    3146              : 
    3147          186 :       FOR_EACH_ALIAS (this, ref)
    3148              :         {
    3149           17 :           cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
    3150           17 :           if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE)
    3151            9 :             set_noreturn_flag_1 (alias, noreturn_p, &changed);
    3152              :         }
    3153              :     }
    3154        26839 :   return changed;
    3155              : }
    3156              : 
    3157              : /* Worker to set_const_flag.  */
    3158              : 
    3159              : static void
    3160       976330 : set_const_flag_1 (cgraph_node *node, bool set_const, bool looping,
    3161              :                   bool *changed)
    3162              : {
    3163              :   /* Static constructors and destructors without a side effect can be
    3164              :      optimized out.  */
    3165       976330 :   if (set_const && !looping)
    3166              :     {
    3167       970329 :       if (DECL_STATIC_CONSTRUCTOR (node->decl))
    3168              :         {
    3169          269 :           DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
    3170          269 :           *changed = true;
    3171              :         }
    3172       970329 :       if (DECL_STATIC_DESTRUCTOR (node->decl))
    3173              :         {
    3174            1 :           DECL_STATIC_DESTRUCTOR (node->decl) = 0;
    3175            1 :           *changed = true;
    3176              :         }
    3177              :     }
    3178       976330 :   if (!set_const)
    3179              :     {
    3180         2199 :       if (TREE_READONLY (node->decl))
    3181              :         {
    3182          159 :           TREE_READONLY (node->decl) = 0;
    3183          159 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3184          159 :           *changed = true;
    3185              :         }
    3186              :     }
    3187              :   else
    3188              :     {
    3189              :       /* Consider function:
    3190              : 
    3191              :          bool a(int *p)
    3192              :          {
    3193              :            return *p==*p;
    3194              :          }
    3195              : 
    3196              :          During early optimization we will turn this into:
    3197              : 
    3198              :          bool a(int *p)
    3199              :          {
    3200              :            return true;
    3201              :          }
    3202              : 
    3203              :          Now if this function will be detected as CONST however when interposed
    3204              :          it may end up being just pure.  We always must assume the worst
    3205              :          scenario here.  */
    3206       974131 :       if (TREE_READONLY (node->decl))
    3207              :         {
    3208          741 :           if (!looping && DECL_LOOPING_CONST_OR_PURE_P (node->decl))
    3209              :             {
    3210          424 :               DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3211          424 :               *changed = true;
    3212              :             }
    3213              :         }
    3214       973390 :       else if (node->binds_to_current_def_p ())
    3215              :         {
    3216       171428 :           TREE_READONLY (node->decl) = true;
    3217       171428 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
    3218       171428 :           DECL_PURE_P (node->decl) = false;
    3219       171428 :           *changed = true;
    3220              :         }
    3221              :       else
    3222              :         {
    3223       801962 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3224            0 :             fprintf (dump_file, "Dropping state to PURE because function does "
    3225              :                      "not bind to current def.\n");
    3226       801962 :           if (!DECL_PURE_P (node->decl))
    3227              :             {
    3228       381618 :               DECL_PURE_P (node->decl) = true;
    3229       381618 :               DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
    3230       381618 :               *changed = true;
    3231              :             }
    3232       420344 :           else if (!looping && DECL_LOOPING_CONST_OR_PURE_P (node->decl))
    3233              :             {
    3234          143 :               DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3235          143 :               *changed = true;
    3236              :             }
    3237              :         }
    3238              :     }
    3239              : 
    3240              :   ipa_ref *ref;
    3241      1082305 :   FOR_EACH_ALIAS (node, ref)
    3242              :     {
    3243       105975 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    3244       105975 :       if (!set_const || alias->get_availability () > AVAIL_INTERPOSABLE)
    3245       105912 :         set_const_flag_1 (alias, set_const, looping, changed);
    3246              :     }
    3247       976426 :   for (struct cgraph_node *n = node->simd_clones; n != NULL;
    3248           96 :        n = n->simdclone->next_clone)
    3249           96 :     set_const_flag_1 (n, set_const, looping, changed);
    3250      2625145 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3251      1648815 :     if (e->caller->thunk
    3252      1648815 :         && (!set_const || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    3253              :       {
    3254              :         /* Virtual thunks access virtual offset in the vtable, so they can
    3255              :            only be pure, never const.  */
    3256          369 :         if (set_const
    3257          369 :             && (thunk_info::get (e->caller)->virtual_offset_p
    3258          238 :                 || !node->binds_to_current_def_p (e->caller)))
    3259          131 :           *changed |= e->caller->set_pure_flag (true, looping);
    3260              :         else
    3261          238 :           set_const_flag_1 (e->caller, set_const, looping, changed);
    3262              :       }
    3263       976330 : }
    3264              : 
    3265              : /* If SET_CONST is true, mark function, aliases and thunks to be ECF_CONST.
    3266              :    If SET_CONST if false, clear the flag.
    3267              : 
    3268              :    When setting the flag be careful about possible interposition and
    3269              :    do not set the flag for functions that can be interposed and set pure
    3270              :    flag for functions that can bind to other definition.
    3271              : 
    3272              :    Return true if any change was done. */
    3273              : 
    3274              : bool
    3275       896056 : cgraph_node::set_const_flag (bool set_const, bool looping)
    3276              : {
    3277       896056 :   bool changed = false;
    3278       896056 :   if (!set_const || get_availability () > AVAIL_INTERPOSABLE)
    3279       869889 :     set_const_flag_1 (this, set_const, looping, &changed);
    3280              :   else
    3281              :     {
    3282              :       ipa_ref *ref;
    3283              : 
    3284        27046 :       FOR_EACH_ALIAS (this, ref)
    3285              :         {
    3286          879 :           cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    3287          879 :           if (!set_const || alias->get_availability () > AVAIL_INTERPOSABLE)
    3288          195 :             set_const_flag_1 (alias, set_const, looping, &changed);
    3289              :         }
    3290              :     }
    3291       896056 :   return changed;
    3292              : }
    3293              : 
    3294              : /* Info used by set_pure_flag_1.  */
    3295              : 
    3296              : struct set_pure_flag_info
    3297              : {
    3298              :   bool pure;
    3299              :   bool looping;
    3300              :   bool changed;
    3301              : };
    3302              : 
    3303              : /* Worker to set_pure_flag.  */
    3304              : 
    3305              : static bool
    3306       347427 : set_pure_flag_1 (cgraph_node *node, void *data)
    3307              : {
    3308       347427 :   struct set_pure_flag_info *info = (struct set_pure_flag_info *)data;
    3309              :   /* Static constructors and destructors without a side effect can be
    3310              :      optimized out.  */
    3311       347427 :   if (info->pure && !info->looping)
    3312              :     {
    3313       280587 :       if (DECL_STATIC_CONSTRUCTOR (node->decl))
    3314              :         {
    3315            0 :           DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
    3316            0 :           info->changed = true;
    3317              :         }
    3318       280587 :       if (DECL_STATIC_DESTRUCTOR (node->decl))
    3319              :         {
    3320            0 :           DECL_STATIC_DESTRUCTOR (node->decl) = 0;
    3321            0 :           info->changed = true;
    3322              :         }
    3323              :     }
    3324       347427 :   if (info->pure)
    3325              :     {
    3326       345228 :       if (!DECL_PURE_P (node->decl) && !TREE_READONLY (node->decl))
    3327              :         {
    3328       344637 :           DECL_PURE_P (node->decl) = true;
    3329       344637 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = info->looping;
    3330       344637 :           info->changed = true;
    3331              :         }
    3332          591 :       else if (DECL_LOOPING_CONST_OR_PURE_P (node->decl)
    3333          591 :                && !info->looping)
    3334              :         {
    3335          314 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3336          314 :           info->changed = true;
    3337              :         }
    3338              :     }
    3339              :   else
    3340              :     {
    3341         2199 :       if (DECL_PURE_P (node->decl))
    3342              :         {
    3343           75 :           DECL_PURE_P (node->decl) = false;
    3344           75 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3345           75 :           info->changed = true;
    3346              :         }
    3347              :     }
    3348       347427 :   return false;
    3349              : }
    3350              : 
    3351              : /* Set DECL_PURE_P on cgraph_node's decl and on aliases of the node
    3352              :    if any to PURE.
    3353              : 
    3354              :    When setting the flag, be careful about possible interposition.
    3355              :    Return true if any change was done. */
    3356              : 
    3357              : bool
    3358       358217 : cgraph_node::set_pure_flag (bool pure, bool looping)
    3359              : {
    3360       358217 :   struct set_pure_flag_info info = {pure, looping, false};
    3361       358217 :   call_for_symbol_thunks_and_aliases (set_pure_flag_1, &info, !pure, true);
    3362       358217 :   for (struct cgraph_node *n = simd_clones; n != NULL;
    3363            0 :        n = n->simdclone->next_clone)
    3364            0 :     set_pure_flag_1 (n, &info);
    3365       358217 :   return info.changed;
    3366              : }
    3367              : 
    3368              : /* Return true when cgraph_node cannot return or throw and thus
    3369              :    it is safe to ignore its side effects for IPA analysis.  */
    3370              : 
    3371              : bool
    3372     14296826 : cgraph_node::cannot_return_p (void)
    3373              : {
    3374     14296826 :   int flags = flags_from_decl_or_type (decl);
    3375     14296826 :   if (!opt_for_fn (decl, flag_exceptions))
    3376      4715017 :     return (flags & ECF_NORETURN) != 0;
    3377              :   else
    3378      9581809 :     return ((flags & (ECF_NORETURN | ECF_NOTHROW))
    3379      9581809 :              == (ECF_NORETURN | ECF_NOTHROW));
    3380              : }
    3381              : 
    3382              : /* Return true when call of edge cannot lead to return from caller
    3383              :    and thus it is safe to ignore its side effects for IPA analysis
    3384              :    when computing side effects of the caller.
    3385              :    FIXME: We could actually mark all edges that have no reaching
    3386              :    patch to the exit block or throw to get better results.  */
    3387              : bool
    3388      3044548 : cgraph_edge::cannot_lead_to_return_p (void)
    3389              : {
    3390      3044548 :   if (caller->cannot_return_p ())
    3391              :     return true;
    3392      2956861 :   if (indirect_unknown_callee)
    3393              :     {
    3394        92828 :       int flags = indirect_info->ecf_flags;
    3395        92828 :       if (!opt_for_fn (caller->decl, flag_exceptions))
    3396        19619 :         return (flags & ECF_NORETURN) != 0;
    3397              :       else
    3398        73209 :         return ((flags & (ECF_NORETURN | ECF_NOTHROW))
    3399        73209 :                  == (ECF_NORETURN | ECF_NOTHROW));
    3400              :     }
    3401              :   else
    3402      2864033 :     return callee->cannot_return_p ();
    3403              : }
    3404              : 
    3405              : /* Return true if the edge after scaling it profile by SCALE
    3406              :    may be considered hot.  */
    3407              : 
    3408              : bool
    3409      5279833 : cgraph_edge::maybe_hot_p (sreal scale)
    3410              : {
    3411              :   /* Never consider calls in functions optimized for size hot.  */
    3412      5279833 :   if (opt_for_fn (caller->decl, optimize_size))
    3413              :     return false;
    3414              : 
    3415              :   /* If reliable IPA count is available, just use it.  */
    3416      5216607 :   profile_count c = count.ipa ();
    3417      5216607 :   if (c.reliable_p ()
    3418      5216607 :       || (c.quality () == AFDO && c.nonzero_p ()))
    3419       617364 :     return maybe_hot_count_p (NULL, c * scale);
    3420              : 
    3421              :   /* In auto-FDO, count 0 may lead to hot code in case the
    3422              :      call is simply not called often enough to receive some samples.  */
    3423      4599243 :   if ((c.quality () == AFDO
    3424      4599243 :        || count.quality () == GUESSED_GLOBAL0_ADJUSTED)
    3425      4599243 :       && callee && callee->count.quality () == AFDO)
    3426            0 :     return maybe_hot_count_p (NULL, c.force_nonzero () * scale);
    3427              : 
    3428              :   /* See if we can determine hotness using caller frequency.  */
    3429      4599243 :   if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
    3430      4596137 :       || (callee
    3431      4123147 :           && callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
    3432              :     return false;
    3433      4593431 :   if (caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
    3434      4593431 :       && (callee
    3435      4120441 :           && callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
    3436              :     return false;
    3437              :   /* ??? This may make sense for hot functions determined by
    3438              :      user attribute, but if function is hot by profile, it may
    3439              :      contains non-hot calls.  In most practical cases this case
    3440              :      is handled by the reliable ipa count above, but i.e. after
    3441              :      inlining function with no profile to function with profile
    3442              :      we get here.. */
    3443      4537743 :   if (caller->frequency == NODE_FREQUENCY_HOT)
    3444              :     return true;
    3445              : 
    3446              :   /* Use IPA count and if it s not available appy local heuristics.  */
    3447      4537741 :   if (c.initialized_p ())
    3448              :     {
    3449              :       /* A special case; AFDO zero means that function may quite possibly
    3450              :          be executed few times per execution.  If scale is large, we still
    3451              :          want to consider the call hot.  */
    3452            0 :       if (c.quality () == AFDO)
    3453            0 :         c = c.force_nonzero ();
    3454            0 :       return maybe_hot_count_p (NULL, c * scale);
    3455              :     }
    3456      4537741 :   if (!count.initialized_p ())
    3457              :     return true;
    3458      3322018 :   cgraph_node *where = caller->inlined_to ? caller->inlined_to : caller;
    3459      3322018 :   if (!where->count.initialized_p ())
    3460              :     return true;
    3461      3322018 :   c = count * scale;
    3462      3322018 :   if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE)
    3463              :     {
    3464        82176 :       if (c * 2 < where->count * 3)
    3465              :         return false;
    3466              :     }
    3467      3239842 :   else if (c * param_hot_bb_frequency_fraction < where->count)
    3468              :     return false;
    3469              :   return true;
    3470              : }
    3471              : 
    3472              : /* Return true if the edge may be considered hot.  */
    3473              : 
    3474              : bool
    3475      2150655 : cgraph_edge::maybe_hot_p ()
    3476              : {
    3477      2150655 :   return maybe_hot_p (1);
    3478              : }
    3479              : 
    3480              : /* Worker for cgraph_can_remove_if_no_direct_calls_p.  */
    3481              : 
    3482              : static bool
    3483       740722 : nonremovable_p (cgraph_node *node, void *)
    3484              : {
    3485       740722 :   return !node->can_remove_if_no_direct_calls_and_refs_p ();
    3486              : }
    3487              : 
    3488              : /* Return true if whole comdat group can be removed if there are no direct
    3489              :    calls to THIS.  */
    3490              : 
    3491              : bool
    3492       967702 : cgraph_node::can_remove_if_no_direct_calls_p (bool will_inline)
    3493              : {
    3494       967702 :   struct ipa_ref *ref;
    3495              : 
    3496              :   /* For local symbols or non-comdat group it is the same as
    3497              :      can_remove_if_no_direct_calls_p.  */
    3498       967702 :   if (!externally_visible || !same_comdat_group)
    3499              :     {
    3500       747935 :       if (DECL_EXTERNAL (decl))
    3501              :         return true;
    3502       747935 :       if (address_taken)
    3503              :         return false;
    3504       713758 :       return !call_for_symbol_and_aliases (nonremovable_p, NULL, true);
    3505              :     }
    3506              : 
    3507       219767 :   if (will_inline && address_taken)
    3508              :     return false;
    3509              : 
    3510              :   /* Otherwise check if we can remove the symbol itself and then verify
    3511              :      that only uses of the comdat groups are direct call to THIS
    3512              :      or its aliases.   */
    3513       219767 :   if (!can_remove_if_no_direct_calls_and_refs_p ())
    3514              :     return false;
    3515              : 
    3516              :   /* Check that all refs come from within the comdat group.  */
    3517       421845 :   for (int i = 0; iterate_referring (i, ref); i++)
    3518       214566 :     if (ref->referring->get_comdat_group () != get_comdat_group ())
    3519              :       return false;
    3520              : 
    3521       207279 :   struct cgraph_node *target = ultimate_alias_target ();
    3522       207279 :   for (cgraph_node *next = dyn_cast<cgraph_node *> (same_comdat_group);
    3523       624655 :        next != this; next = dyn_cast<cgraph_node *> (next->same_comdat_group))
    3524              :     {
    3525       220263 :       if (!externally_visible)
    3526            0 :         continue;
    3527       220263 :       if (!next->alias
    3528       220263 :           && !next->can_remove_if_no_direct_calls_and_refs_p ())
    3529              :         return false;
    3530              : 
    3531              :       /* If we see different symbol than THIS, be sure to check calls.  */
    3532       220263 :       if (next->ultimate_alias_target () != target)
    3533        21212 :         for (cgraph_edge *e = next->callers; e; e = e->next_caller)
    3534         4584 :           if (e->caller->get_comdat_group () != get_comdat_group ()
    3535         4584 :               || will_inline)
    3536              :             return false;
    3537              : 
    3538              :       /* If function is not being inlined, we care only about
    3539              :          references outside of the comdat group.  */
    3540       218412 :       if (!will_inline)
    3541       219551 :         for (int i = 0; next->iterate_referring (i, ref); i++)
    3542        10863 :           if (ref->referring->get_comdat_group () != get_comdat_group ())
    3543              :             return false;
    3544              :     }
    3545              :   return true;
    3546              : }
    3547              : 
    3548              : /* Return true when function cgraph_node can be expected to be removed
    3549              :    from program when direct calls in this compilation unit are removed.
    3550              : 
    3551              :    As a special case COMDAT functions are
    3552              :    cgraph_can_remove_if_no_direct_calls_p while the are not
    3553              :    cgraph_only_called_directly_p (it is possible they are called from other
    3554              :    unit)
    3555              : 
    3556              :    This function behaves as cgraph_only_called_directly_p because eliminating
    3557              :    all uses of COMDAT function does not make it necessarily disappear from
    3558              :    the program unless we are compiling whole program or we do LTO.  In this
    3559              :    case we know we win since dynamic linking will not really discard the
    3560              :    linkonce section.  */
    3561              : 
    3562              : bool
    3563      3150038 : cgraph_node::will_be_removed_from_program_if_no_direct_calls_p
    3564              :          (bool will_inline)
    3565              : {
    3566      3150038 :   gcc_assert (!inlined_to);
    3567      3150038 :   if (DECL_EXTERNAL (decl))
    3568              :     return true;
    3569              : 
    3570      3150038 :   if (!in_lto_p && !flag_whole_program)
    3571              :     {
    3572              :       /* If the symbol is in comdat group, we need to verify that whole comdat
    3573              :          group becomes unreachable.  Technically we could skip references from
    3574              :          within the group, too.  */
    3575      2936399 :       if (!only_called_directly_p ())
    3576              :         return false;
    3577       719898 :       if (same_comdat_group && externally_visible)
    3578              :         {
    3579            0 :           struct cgraph_node *target = ultimate_alias_target ();
    3580              : 
    3581            0 :           if (will_inline && address_taken)
    3582              :             return true;
    3583            0 :           for (cgraph_node *next = dyn_cast<cgraph_node *> (same_comdat_group);
    3584            0 :                next != this;
    3585            0 :                next = dyn_cast<cgraph_node *> (next->same_comdat_group))
    3586              :             {
    3587            0 :               if (!externally_visible)
    3588            0 :                 continue;
    3589            0 :               if (!next->alias
    3590            0 :                   && !next->only_called_directly_p ())
    3591              :                 return false;
    3592              : 
    3593              :               /* If we see different symbol than THIS,
    3594              :                  be sure to check calls.  */
    3595            0 :               if (next->ultimate_alias_target () != target)
    3596            0 :                 for (cgraph_edge *e = next->callers; e; e = e->next_caller)
    3597            0 :                   if (e->caller->get_comdat_group () != get_comdat_group ()
    3598            0 :                       || will_inline)
    3599              :                     return false;
    3600              :             }
    3601              :         }
    3602       719898 :       return true;
    3603              :     }
    3604              :   else
    3605       213639 :     return can_remove_if_no_direct_calls_p (will_inline);
    3606              : }
    3607              : 
    3608              : 
    3609              : /* Worker for cgraph_only_called_directly_p.  */
    3610              : 
    3611              : static bool
    3612     15883599 : cgraph_not_only_called_directly_p_1 (cgraph_node *node, void *)
    3613              : {
    3614     15883599 :   return !node->only_called_directly_or_aliased_p ();
    3615              : }
    3616              : 
    3617              : /* Return true when function cgraph_node and all its aliases are only called
    3618              :    directly.
    3619              :    i.e. it is not externally visible, address was not taken and
    3620              :    it is not used in any other non-standard way.  */
    3621              : 
    3622              : bool
    3623     15785842 : cgraph_node::only_called_directly_p (void)
    3624              : {
    3625     15785842 :   gcc_assert (ultimate_alias_target () == this);
    3626     15785842 :   return !call_for_symbol_and_aliases (cgraph_not_only_called_directly_p_1,
    3627     15785842 :                                        NULL, true);
    3628              : }
    3629              : 
    3630              : 
    3631              : /* Collect all callers of NODE.  Worker for collect_callers_of_node.  */
    3632              : 
    3633              : static bool
    3634       127371 : collect_callers_of_node_1 (cgraph_node *node, void *data)
    3635              : {
    3636       127371 :   vec<cgraph_edge *> *redirect_callers = (vec<cgraph_edge *> *)data;
    3637       127371 :   cgraph_edge *cs;
    3638       127371 :   enum availability avail;
    3639       127371 :   node->ultimate_alias_target (&avail);
    3640              : 
    3641       127371 :   if (avail > AVAIL_INTERPOSABLE)
    3642       448056 :     for (cs = node->callers; cs != NULL; cs = cs->next_caller)
    3643       320685 :       if (!cs->indirect_inlining_edge
    3644       320685 :           && !cs->caller->thunk)
    3645       320626 :         redirect_callers->safe_push (cs);
    3646       127371 :   return false;
    3647              : }
    3648              : 
    3649              : /* Collect all callers of cgraph_node and its aliases that are known to lead to
    3650              :    cgraph_node (i.e. are not overwritable).  */
    3651              : 
    3652              : auto_vec<cgraph_edge *>
    3653       126089 : cgraph_node::collect_callers (void)
    3654              : {
    3655       126089 :   auto_vec<cgraph_edge *> redirect_callers;
    3656       126089 :   call_for_symbol_thunks_and_aliases (collect_callers_of_node_1,
    3657              :                                     &redirect_callers, false);
    3658       126089 :   return redirect_callers;
    3659              : }
    3660              : 
    3661              : 
    3662              : /* Return TRUE if NODE2 a clone of NODE or is equivalent to it.  Return
    3663              :    optimistically true if this cannot be determined.  */
    3664              : 
    3665              : static bool
    3666        43752 : clone_of_p (cgraph_node *node, cgraph_node *node2)
    3667              : {
    3668        43752 :   node = node->ultimate_alias_target ();
    3669        43752 :   node2 = node2->ultimate_alias_target ();
    3670              : 
    3671        43752 :   if (node2->clone_of == node
    3672         5257 :       || node2->former_clone_of == node->decl)
    3673              :     return true;
    3674              : 
    3675         5319 :   if (!node->thunk && !node->former_thunk_p ())
    3676              :     {
    3677              :       while (node2
    3678        15584 :              && node->decl != node2->decl
    3679        25974 :              && node->decl != node2->former_clone_of)
    3680        10389 :         node2 = node2->clone_of;
    3681         5195 :       return node2 != NULL;
    3682              :     }
    3683              : 
    3684              :   /* There are no virtual clones of thunks so check former_clone_of or if we
    3685              :      might have skipped thunks because this adjustments are no longer
    3686              :      necessary.  */
    3687           62 :   while (node->thunk || node->former_thunk_p ())
    3688              :     {
    3689           62 :       if (!thunk_info::get (node)->this_adjusting)
    3690              :         return false;
    3691              :       /* In case of instrumented expanded thunks, which can have multiple calls
    3692              :          in them, we do not know how to continue and just have to be
    3693              :          optimistic.  The same applies if all calls have already been inlined
    3694              :          into the thunk.  */
    3695           62 :       if (!node->callees || node->callees->next_callee)
    3696              :         return true;
    3697           59 :       node = node->callees->callee->ultimate_alias_target ();
    3698              : 
    3699           59 :       clone_info *info = clone_info::get (node2);
    3700           59 :       if (!info || !info->param_adjustments
    3701          118 :           || info->param_adjustments->first_param_intact_p ())
    3702            0 :         return false;
    3703           59 :       if (node2->former_clone_of == node->decl
    3704           59 :           || node2->former_clone_of == node->former_clone_of)
    3705              :         return true;
    3706              : 
    3707              :       cgraph_node *n2 = node2;
    3708            0 :       while (n2 && node->decl != n2->decl)
    3709            0 :         n2 = n2->clone_of;
    3710            0 :       if (n2)
    3711              :         return true;
    3712              :     }
    3713              : 
    3714              :   return false;
    3715              : }
    3716              : 
    3717              : /* Verify edge count and frequency.  */
    3718              : 
    3719              : bool
    3720    195648470 : cgraph_edge::verify_count ()
    3721              : {
    3722    195648470 :   bool error_found = false;
    3723    195648470 :   if (!count.verify ())
    3724              :     {
    3725            0 :       error ("caller edge count invalid");
    3726            0 :       error_found = true;
    3727              :     }
    3728    195648470 :   return error_found;
    3729              : }
    3730              : 
    3731              : /* Switch to THIS_CFUN if needed and print STMT to stderr.  */
    3732              : static void
    3733            0 : cgraph_debug_gimple_stmt (function *this_cfun, gimple *stmt)
    3734              : {
    3735            0 :   bool fndecl_was_null = false;
    3736              :   /* debug_gimple_stmt needs correct cfun */
    3737            0 :   if (cfun != this_cfun)
    3738            0 :     set_cfun (this_cfun);
    3739              :   /* ...and an actual current_function_decl */
    3740            0 :   if (!current_function_decl)
    3741              :     {
    3742            0 :       current_function_decl = this_cfun->decl;
    3743            0 :       fndecl_was_null = true;
    3744              :     }
    3745            0 :   debug_gimple_stmt (stmt);
    3746            0 :   if (fndecl_was_null)
    3747            0 :     current_function_decl = NULL;
    3748            0 : }
    3749              : 
    3750              : /* Verify that call graph edge corresponds to DECL from the associated
    3751              :    statement.  Return true if the verification should fail.  */
    3752              : 
    3753              : bool
    3754     97736838 : cgraph_edge::verify_corresponds_to_fndecl (tree decl)
    3755              : {
    3756     97736838 :   cgraph_node *node;
    3757              : 
    3758     97736838 :   if (!decl || callee->inlined_to)
    3759              :     return false;
    3760     94109485 :   if (symtab->state == LTO_STREAMING)
    3761              :     return false;
    3762     94109485 :   node = cgraph_node::get (decl);
    3763              : 
    3764              :   /* We do not know if a node from a different partition is an alias or what it
    3765              :      aliases and therefore cannot do the former_clone_of check reliably.  When
    3766              :      body_removed is set, we have lost all information about what was alias or
    3767              :      thunk of and also cannot proceed.  */
    3768     94109485 :   if (!node
    3769     94004885 :       || node->body_removed
    3770     93404238 :       || node->in_other_partition
    3771     93404238 :       || callee->icf_merged
    3772     93304342 :       || callee->in_other_partition)
    3773              :     return false;
    3774              : 
    3775     93304342 :   node = node->ultimate_alias_target ();
    3776              : 
    3777              :   /* Optimizers can redirect unreachable calls or calls triggering undefined
    3778              :      behavior to __builtin_unreachable or __builtin_unreachable trap.  */
    3779              : 
    3780     93304342 :   if (fndecl_built_in_p (callee->decl, BUILT_IN_UNREACHABLE,
    3781              :                                        BUILT_IN_UNREACHABLE_TRAP))
    3782              :     return false;
    3783              : 
    3784     90158600 :   if (callee->former_clone_of != node->decl
    3785     90156146 :       && (node != callee->ultimate_alias_target ())
    3786     90202352 :       && !clone_of_p (node, callee))
    3787              :     return true;
    3788              :   else
    3789     90158600 :     return false;
    3790              : }
    3791              : 
    3792              : /* Disable warnings about missing quoting in GCC diagnostics for
    3793              :    the verification errors.  Their format strings don't follow GCC
    3794              :    diagnostic conventions and the calls are ultimately followed by
    3795              :    one to internal_error.  */
    3796              : #if __GNUC__ >= 10
    3797              : #  pragma GCC diagnostic push
    3798              : #  pragma GCC diagnostic ignored "-Wformat-diag"
    3799              : #endif
    3800              : 
    3801              : /* Verify consistency of speculative call in NODE corresponding to STMT
    3802              :    and LTO_STMT_UID.  If INDIRECT is set, assume that it is the indirect
    3803              :    edge of call sequence. Return true if error is found.
    3804              : 
    3805              :    This function is called to every component of indirect call (direct edges,
    3806              :    indirect edge and refs).  To save duplicated work, do full testing only
    3807              :    in that case.  */
    3808              : static bool
    3809       436983 : verify_speculative_call (struct cgraph_node *node, gimple *stmt,
    3810              :                          unsigned int lto_stmt_uid,
    3811              :                          struct cgraph_edge *indirect)
    3812              : {
    3813       436983 :   if (indirect == NULL)
    3814              :     {
    3815       527026 :       for (indirect = node->indirect_calls; indirect;
    3816       205366 :            indirect = indirect->next_callee)
    3817       527026 :         if (indirect->call_stmt == stmt
    3818       321786 :             && indirect->lto_stmt_uid == lto_stmt_uid)
    3819              :           break;
    3820       321660 :       if (!indirect)
    3821              :         {
    3822            0 :           error ("missing indirect call in speculative call sequence");
    3823            0 :           return true;
    3824              :         }
    3825       321660 :       if (!indirect->speculative)
    3826              :         {
    3827            0 :           error ("indirect call in speculative call sequence has no "
    3828              :                  "speculative flag");
    3829            0 :           return true;
    3830              :         }
    3831              :       return false;
    3832              :     }
    3833              : 
    3834              :   /* Maximal number of targets.  We probably will never want to have more than
    3835              :      this.  */
    3836              :   const unsigned int num = 256;
    3837              :   cgraph_edge *direct_calls[num];
    3838              :   ipa_ref *refs[num];
    3839              : 
    3840     29638011 :   for (unsigned int i = 0; i < num; i++)
    3841              :     {
    3842     29522688 :       direct_calls[i] = NULL;
    3843     29522688 :       refs[i] = NULL;
    3844              :     }
    3845              : 
    3846       115323 :   cgraph_edge *first_call = NULL;
    3847       115323 :   cgraph_edge *prev_call = NULL;
    3848              : 
    3849      1178649 :   for (cgraph_edge *direct = node->callees; direct;
    3850      1063326 :        direct = direct->next_callee)
    3851      1063326 :     if (direct->call_stmt == stmt && direct->lto_stmt_uid == lto_stmt_uid)
    3852              :       {
    3853       160830 :         if (!first_call)
    3854       115323 :           first_call = direct;
    3855       160830 :         if (prev_call && direct != prev_call->next_callee)
    3856              :           {
    3857            0 :             error ("speculative edges are not adjacent");
    3858            0 :             return true;
    3859              :           }
    3860       160830 :         prev_call = direct;
    3861       160830 :         if (!direct->speculative)
    3862              :           {
    3863            0 :             error ("direct call to %s in speculative call sequence has no "
    3864            0 :                    "speculative flag", direct->callee->dump_name ());
    3865            0 :             return true;
    3866              :           }
    3867       160830 :         if (direct->speculative_id >= num)
    3868              :           {
    3869            0 :             error ("direct call to %s in speculative call sequence has "
    3870              :                    "speculative_id %i out of range",
    3871            0 :                    direct->callee->dump_name (), direct->speculative_id);
    3872            0 :             return true;
    3873              :           }
    3874       160830 :         if (direct_calls[direct->speculative_id])
    3875              :           {
    3876            0 :             error ("duplicate direct call to %s in speculative call sequence "
    3877              :                    "with speculative_id %i",
    3878            0 :                    direct->callee->dump_name (), direct->speculative_id);
    3879            0 :             return true;
    3880              :           }
    3881       160830 :         direct_calls[direct->speculative_id] = direct;
    3882              :       }
    3883              : 
    3884       115323 :   if (first_call->call_stmt
    3885       115323 :       && first_call != node->get_edge (first_call->call_stmt))
    3886              :     {
    3887            0 :       error ("call stmt hash does not point to first direct edge of "
    3888              :              "speculative call sequence");
    3889            0 :       return true;
    3890              :     }
    3891              : 
    3892              :   ipa_ref *ref;
    3893      1478278 :   for (int i = 0; node->iterate_reference (i, ref); i++)
    3894      1362955 :     if (ref->speculative
    3895       285216 :         && ref->stmt == stmt && ref->lto_stmt_uid == lto_stmt_uid)
    3896              :       {
    3897       160830 :         if (ref->speculative_id >= num)
    3898              :           {
    3899            0 :             error ("direct call to %s in speculative call sequence has "
    3900              :                    "speculative_id %i out of range",
    3901            0 :                    ref->referred->dump_name (), ref->speculative_id);
    3902            0 :             return true;
    3903              :           }
    3904       160830 :         if (refs[ref->speculative_id])
    3905              :           {
    3906            0 :             error ("duplicate reference %s in speculative call sequence "
    3907              :                    "with speculative_id %i",
    3908            0 :                    ref->referred->dump_name (), ref->speculative_id);
    3909            0 :             return true;
    3910              :           }
    3911       160830 :         refs[ref->speculative_id] = ref;
    3912              :       }
    3913              : 
    3914              :   int num_targets = 0;
    3915     29638011 :   for (unsigned int i = 0 ; i < num ; i++)
    3916              :     {
    3917     29522688 :       if (refs[i] && !direct_calls[i])
    3918              :         {
    3919            0 :           error ("missing direct call for speculation %i", i);
    3920            0 :           return true;
    3921              :         }
    3922     29522688 :       if (!refs[i] && direct_calls[i])
    3923              :         {
    3924            0 :           error ("missing ref for speculation %i", i);
    3925            0 :           return true;
    3926              :         }
    3927     29522688 :       if (refs[i] != NULL)
    3928       160830 :         num_targets++;
    3929              :     }
    3930              : 
    3931       115323 :   if (num_targets != indirect->num_speculative_call_targets_p ())
    3932              :     {
    3933            0 :       error ("number of speculative targets %i mismatched with "
    3934              :              "num_speculative_call_targets %i",
    3935              :              num_targets,
    3936              :              indirect->num_speculative_call_targets_p ());
    3937            0 :       return true;
    3938              :     }
    3939              :   return false;
    3940              : }
    3941              : 
    3942              : /* Verify cgraph nodes of given cgraph node.  */
    3943              : DEBUG_FUNCTION void
    3944     51526688 : cgraph_node::verify_node (void)
    3945              : {
    3946     51526688 :   cgraph_edge *e;
    3947     51526688 :   function *this_cfun = DECL_STRUCT_FUNCTION (decl);
    3948     51526688 :   basic_block this_block;
    3949     51526688 :   gimple_stmt_iterator gsi;
    3950     51526688 :   bool error_found = false;
    3951     51526688 :   int i;
    3952     51526688 :   ipa_ref *ref = NULL;
    3953              : 
    3954     51526688 :   if (seen_error ())
    3955     51526688 :     return;
    3956              : 
    3957     51526688 :   timevar_push (TV_CGRAPH_VERIFY);
    3958     51526688 :   error_found |= verify_base ();
    3959    156496409 :   for (e = callees; e; e = e->next_callee)
    3960    104969721 :     if (e->aux)
    3961              :       {
    3962            0 :         error ("aux field set for edge %s->%s",
    3963            0 :                identifier_to_locale (e->caller->name ()),
    3964            0 :                identifier_to_locale (e->callee->name ()));
    3965            0 :         error_found = true;
    3966              :       }
    3967     51526688 :   if (!count.verify ())
    3968              :     {
    3969            0 :       error ("cgraph count invalid");
    3970            0 :       error_found = true;
    3971              :     }
    3972     51526688 :   if (inlined_to && same_comdat_group)
    3973              :     {
    3974            0 :       error ("inline clone in same comdat group list");
    3975            0 :       error_found = true;
    3976              :     }
    3977     51526688 :   if (inlined_to && !count.compatible_p (inlined_to->count))
    3978              :     {
    3979            0 :       error ("inline clone count is not compatible");
    3980            0 :       count.debug ();
    3981            0 :       inlined_to->count.debug ();
    3982            0 :       error_found = true;
    3983              :     }
    3984     51526688 :   if (tp_first_run < 0)
    3985              :     {
    3986            0 :       error ("tp_first_run must be non-negative");
    3987            0 :       error_found = true;
    3988              :     }
    3989     51526688 :   if (!definition && !in_other_partition && local)
    3990              :     {
    3991            0 :       error ("local symbols must be defined");
    3992            0 :       error_found = true;
    3993              :     }
    3994     51526688 :   if (inlined_to && externally_visible)
    3995              :     {
    3996            0 :       error ("externally visible inline clone");
    3997            0 :       error_found = true;
    3998              :     }
    3999     51526688 :   if (inlined_to && address_taken)
    4000              :     {
    4001            0 :       error ("inline clone with address taken");
    4002            0 :       error_found = true;
    4003              :     }
    4004     51526688 :   if (inlined_to && force_output)
    4005              :     {
    4006            0 :       error ("inline clone is forced to output");
    4007            0 :       error_found = true;
    4008              :     }
    4009     51526688 :   if (inlined_to && ref_by_asm)
    4010              :     {
    4011            0 :       error ("inline clone is referenced by assembly");
    4012            0 :       error_found = true;
    4013              :     }
    4014     51526688 :   if (symtab->state != LTO_STREAMING)
    4015              :     {
    4016     51416740 :       if (calls_comdat_local && !same_comdat_group)
    4017              :         {
    4018            0 :           error ("calls_comdat_local is set outside of a comdat group");
    4019            0 :           error_found = true;
    4020              :         }
    4021     51416740 :       if (!inlined_to && calls_comdat_local != check_calls_comdat_local_p ())
    4022              :         {
    4023            0 :           error ("invalid calls_comdat_local flag");
    4024            0 :           error_found = true;
    4025              :         }
    4026              :     }
    4027     51526688 :   if (DECL_IS_MALLOC (decl)
    4028     51526688 :       && !POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
    4029              :     {
    4030            0 :       error ("malloc attribute should be used for a function that "
    4031              :              "returns a pointer");
    4032            0 :       error_found = true;
    4033              :     }
    4034     51526688 :   if (definition
    4035     34533638 :       && externally_visible
    4036              :       /* For aliases in lto1 free_lang_data doesn't guarantee preservation
    4037              :          of opt_for_fn (decl, flag_semantic_interposition).  See PR105399.  */
    4038     19172348 :       && (!alias || !in_lto_p)
    4039     51526688 :       && semantic_interposition
    4040     19169491 :          != opt_for_fn (decl, flag_semantic_interposition))
    4041              :     {
    4042            0 :       error ("semantic interposition mismatch");
    4043            0 :       error_found = true;
    4044              :     }
    4045     53887568 :   for (e = indirect_calls; e; e = e->next_callee)
    4046              :     {
    4047      2360880 :       if (e->aux)
    4048              :         {
    4049            0 :           error ("aux field set for indirect edge from %s",
    4050            0 :                  identifier_to_locale (e->caller->name ()));
    4051            0 :           error_found = true;
    4052              :         }
    4053      2360880 :       if (!e->count.compatible_p (count))
    4054              :         {
    4055            0 :           error ("edge count is not compatible with function count");
    4056            0 :           e->count.debug ();
    4057            0 :           count.debug ();
    4058            0 :           error_found = true;
    4059              :         }
    4060      2360880 :       if (inlined_to && !e->count.compatible_p (inlined_to->count))
    4061              :         {
    4062            0 :           error ("edge count is not compatible with inlined to function count");
    4063            0 :           e->count.debug ();
    4064            0 :           count.debug ();
    4065            0 :           error_found = true;
    4066              :         }
    4067      2360880 :       if (!e->indirect_unknown_callee
    4068      2360880 :           || !e->indirect_info)
    4069              :         {
    4070            0 :           error ("An indirect edge from %s is not marked as indirect or has "
    4071              :                  "associated indirect_info, the corresponding statement is: ",
    4072            0 :                  identifier_to_locale (e->caller->name ()));
    4073            0 :           cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4074            0 :           error_found = true;
    4075              :         }
    4076      2360880 :       if (e->call_stmt && e->lto_stmt_uid)
    4077              :         {
    4078            0 :           error ("edge has both call_stmt and lto_stmt_uid set");
    4079            0 :           error_found = true;
    4080              :         }
    4081              :     }
    4082     51526688 :   bool check_comdat = comdat_local_p ();
    4083    139844557 :   for (e = callers; e; e = e->next_caller)
    4084              :     {
    4085     88317869 :       if (e->verify_count ())
    4086            0 :         error_found = true;
    4087     88317869 :       if (check_comdat
    4088     88317869 :           && !in_same_comdat_group_p (e->caller))
    4089              :         {
    4090            0 :           error ("comdat-local function called by %s outside its comdat",
    4091              :                  identifier_to_locale (e->caller->name ()));
    4092            0 :           error_found = true;
    4093              :         }
    4094     88317869 :       if (!e->inline_failed)
    4095              :         {
    4096      7975614 :           if (inlined_to
    4097      7975614 :               != (e->caller->inlined_to
    4098      7975614 :                   ? e->caller->inlined_to : e->caller))
    4099              :             {
    4100            0 :               error ("inlined_to pointer is wrong");
    4101            0 :               error_found = true;
    4102              :             }
    4103      7975614 :           if (callers->next_caller)
    4104              :             {
    4105            0 :               error ("multiple inline callers");
    4106            0 :               error_found = true;
    4107              :             }
    4108              :         }
    4109              :       else
    4110     80342255 :         if (inlined_to)
    4111              :           {
    4112            0 :             error ("inlined_to pointer set for noninline callers");
    4113            0 :             error_found = true;
    4114              :           }
    4115              :     }
    4116    156496409 :   for (e = callees; e; e = e->next_callee)
    4117              :     {
    4118    104969721 :       if (e->verify_count ())
    4119            0 :         error_found = true;
    4120    104969721 :       if (!e->count.compatible_p (count))
    4121              :         {
    4122            0 :           error ("edge count is not compatible with function count");
    4123            0 :           e->count.debug ();
    4124            0 :           count.debug ();
    4125            0 :           error_found = true;
    4126              :         }
    4127    104969721 :       if (gimple_has_body_p (e->caller->decl)
    4128     98777801 :           && !e->caller->inlined_to
    4129     90107519 :           && !e->speculative
    4130     90049253 :           && !e->callback
    4131     90026646 :           && !e->has_callback
    4132              :           /* Optimized out calls are redirected to __builtin_unreachable.  */
    4133     89938493 :           && (e->count.nonzero_p ()
    4134     51616019 :               || ! e->callee->decl
    4135     51616019 :               || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    4136              :                                      BUILT_IN_UNREACHABLE_TRAP))
    4137              :           && count
    4138     88189777 :               == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
    4139    193151904 :           && (!e->count.ipa_p ()
    4140     40226768 :               && e->count.differs_from_p (gimple_bb (e->call_stmt)->count)))
    4141              :         {
    4142            0 :           error ("caller edge count does not match BB count");
    4143            0 :           fprintf (stderr, "edge count: ");
    4144            0 :           e->count.dump (stderr);
    4145            0 :           fprintf (stderr, "\n bb count: ");
    4146            0 :           gimple_bb (e->call_stmt)->count.dump (stderr);
    4147            0 :           fprintf (stderr, "\n");
    4148            0 :           error_found = true;
    4149              :         }
    4150    104969721 :       if (e->call_stmt && e->lto_stmt_uid)
    4151              :         {
    4152            0 :           error ("edge has both call_stmt and lto_stmt_uid set");
    4153            0 :           error_found = true;
    4154              :         }
    4155    104969721 :       if (e->speculative
    4156    104969721 :           && verify_speculative_call (e->caller, e->call_stmt, e->lto_stmt_uid,
    4157              :                                       NULL))
    4158              :         error_found = true;
    4159              :     }
    4160     53887568 :   for (e = indirect_calls; e; e = e->next_callee)
    4161              :     {
    4162      2360880 :       if (e->verify_count ())
    4163            0 :         error_found = true;
    4164      2360880 :       if (gimple_has_body_p (e->caller->decl)
    4165      2310296 :           && !e->caller->inlined_to
    4166      2065486 :           && !e->speculative
    4167      2025150 :           && e->count.ipa_p ()
    4168              :           && count
    4169       754921 :               == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
    4170      3115797 :           && (!e->count.ipa_p ()
    4171            0 :               && e->count.differs_from_p (gimple_bb (e->call_stmt)->count)))
    4172              :         {
    4173            0 :           error ("indirect call count does not match BB count");
    4174            0 :           fprintf (stderr, "edge count: ");
    4175            0 :           e->count.dump (stderr);
    4176            0 :           fprintf (stderr, "\n bb count: ");
    4177            0 :           gimple_bb (e->call_stmt)->count.dump (stderr);
    4178            0 :           fprintf (stderr, "\n");
    4179            0 :           error_found = true;
    4180              :         }
    4181      2360880 :       if (e->speculative
    4182      2360880 :           && verify_speculative_call (e->caller, e->call_stmt, e->lto_stmt_uid,
    4183              :                                       e))
    4184              :         error_found = true;
    4185              :     }
    4186    117246836 :   for (i = 0; iterate_reference (i, ref); i++)
    4187              :     {
    4188     65720148 :       if (ref->stmt && ref->lto_stmt_uid)
    4189              :         {
    4190            0 :           error ("reference has both stmt and lto_stmt_uid set");
    4191            0 :           error_found = true;
    4192              :         }
    4193     65720148 :       if (ref->speculative
    4194     65720148 :           && verify_speculative_call (this, ref->stmt,
    4195              :                                       ref->lto_stmt_uid, NULL))
    4196              :         error_found = true;
    4197              :     }
    4198              : 
    4199     51526688 :   if (!callers && inlined_to)
    4200              :     {
    4201            0 :       error ("inlined_to pointer is set but no predecessors found");
    4202            0 :       error_found = true;
    4203              :     }
    4204     51526688 :   if (inlined_to == this)
    4205              :     {
    4206            0 :       error ("inlined_to pointer refers to itself");
    4207            0 :       error_found = true;
    4208              :     }
    4209              : 
    4210     51526688 :   if (clone_of)
    4211              :     {
    4212      5792351 :       cgraph_node *first_clone = clone_of->clones;
    4213      5792351 :       if (first_clone != this)
    4214              :         {
    4215      2877823 :           if (prev_sibling_clone->clone_of != clone_of)
    4216              :             {
    4217            0 :               error ("cgraph_node has wrong clone_of");
    4218            0 :               error_found = true;
    4219              :             }
    4220              :         }
    4221              :     }
    4222     51526688 :   if (clones)
    4223              :     {
    4224              :       cgraph_node *n;
    4225      8001962 :       for (n = clones; n; n = n->next_sibling_clone)
    4226      6379751 :         if (n->clone_of != this)
    4227              :           break;
    4228      1622211 :       if (n)
    4229              :         {
    4230            0 :           error ("cgraph_node has wrong clone list");
    4231            0 :           error_found = true;
    4232              :         }
    4233              :     }
    4234     51526688 :   if ((prev_sibling_clone || next_sibling_clone) && !clone_of)
    4235              :     {
    4236            0 :        error ("cgraph_node is in clone list but it is not clone");
    4237            0 :        error_found = true;
    4238              :     }
    4239     51526688 :   if (!prev_sibling_clone && clone_of && clone_of->clones != this)
    4240              :     {
    4241            0 :       error ("cgraph_node has wrong prev_clone pointer");
    4242            0 :       error_found = true;
    4243              :     }
    4244     51526688 :   if (prev_sibling_clone && prev_sibling_clone->next_sibling_clone != this)
    4245              :     {
    4246            0 :       error ("double linked list of clones corrupted");
    4247            0 :       error_found = true;
    4248              :     }
    4249              : 
    4250     51526688 :   if (analyzed && alias)
    4251              :     {
    4252      1386106 :       bool ref_found = false;
    4253      1386106 :       int i;
    4254      1386106 :       ipa_ref *ref = NULL;
    4255              : 
    4256      1386106 :       if (callees)
    4257              :         {
    4258            0 :           error ("Alias has call edges");
    4259            0 :           error_found = true;
    4260              :         }
    4261      2772212 :       for (i = 0; iterate_reference (i, ref); i++)
    4262      1386106 :         if (ref->use != IPA_REF_ALIAS)
    4263              :           {
    4264            0 :             error ("Alias has non-alias reference");
    4265            0 :             error_found = true;
    4266              :           }
    4267      1386106 :         else if (ref_found)
    4268              :           {
    4269            0 :             error ("Alias has more than one alias reference");
    4270            0 :             error_found = true;
    4271              :           }
    4272              :         else
    4273              :           ref_found = true;
    4274      1386106 :       if (!ref_found)
    4275              :         {
    4276            0 :           error ("Analyzed alias has no reference");
    4277            0 :           error_found = true;
    4278              :         }
    4279              :     }
    4280              : 
    4281     51526688 :   if (analyzed && thunk)
    4282              :     {
    4283        21925 :       if (!callees)
    4284              :         {
    4285            0 :           error ("No edge out of thunk node");
    4286            0 :           error_found = true;
    4287              :         }
    4288        21925 :       else if (callees->next_callee)
    4289              :         {
    4290            0 :           error ("More than one edge out of thunk node");
    4291            0 :           error_found = true;
    4292              :         }
    4293        21925 :       if (gimple_has_body_p (decl) && !inlined_to)
    4294              :         {
    4295            0 :           error ("Thunk is not supposed to have body");
    4296            0 :           error_found = true;
    4297              :         }
    4298              :     }
    4299     34509751 :   else if (analyzed && gimple_has_body_p (decl)
    4300     29884378 :            && !TREE_ASM_WRITTEN (decl)
    4301     29884378 :            && (!DECL_EXTERNAL (decl) || inlined_to)
    4302     80858136 :            && !flag_wpa)
    4303              :     {
    4304     29327018 :       if ((this_cfun->curr_properties & PROP_assumptions_done) != 0)
    4305              :         ;
    4306     29326910 :       else if (this_cfun->cfg)
    4307              :         {
    4308     29326910 :           hash_set<gimple *> stmts;
    4309              : 
    4310              :           /* Reach the trees by walking over the CFG, and note the
    4311              :              enclosing basic-blocks in the call edges.  */
    4312    244158796 :           FOR_EACH_BB_FN (this_block, this_cfun)
    4313              :             {
    4314    214831886 :               for (gsi = gsi_start_phis (this_block);
    4315    259397705 :                    !gsi_end_p (gsi); gsi_next (&gsi))
    4316     44565819 :                 stmts.add (gsi_stmt (gsi));
    4317    429663772 :               for (gsi = gsi_start_bb (this_block);
    4318   1291767001 :                    !gsi_end_p (gsi);
    4319   1076935115 :                    gsi_next (&gsi))
    4320              :                 {
    4321   1076935115 :                   gimple *stmt = gsi_stmt (gsi);
    4322   1076935115 :                   stmts.add (stmt);
    4323   1076935115 :                   if (is_gimple_call (stmt))
    4324              :                     {
    4325    104295588 :                       cgraph_edge *e = get_edge (stmt);
    4326    104295588 :                       tree decl = gimple_call_fndecl (stmt);
    4327    104295588 :                       if (e)
    4328              :                         {
    4329     99920431 :                           if (e->aux)
    4330              :                             {
    4331            0 :                               error ("shared call_stmt:");
    4332            0 :                               cgraph_debug_gimple_stmt (this_cfun, stmt);
    4333            0 :                               error_found = true;
    4334              :                             }
    4335     99920431 :                           if (!e->indirect_unknown_callee)
    4336              :                             {
    4337              :                               /* Callback edges violate this assertion
    4338              :                                  because their call statement doesn't exist,
    4339              :                                  their associated statement belongs to the
    4340              :                                  callback-dispatching function.  */
    4341     97736838 :                               if (!e->callback
    4342     97736838 :                                   && e->verify_corresponds_to_fndecl (decl))
    4343              :                                 {
    4344            0 :                                   error ("edge points to wrong declaration:");
    4345            0 :                                   debug_tree (e->callee->decl);
    4346            0 :                                   fprintf (stderr," Instead of:");
    4347            0 :                                   debug_tree (decl);
    4348            0 :                                   error_found = true;
    4349              :                                 }
    4350              :                             }
    4351      2183593 :                           else if (decl)
    4352              :                             {
    4353            0 :                               error ("an indirect edge with unknown callee "
    4354              :                                      "corresponding to a call_stmt with "
    4355              :                                      "a known declaration:");
    4356            0 :                               error_found = true;
    4357            0 :                               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4358              :                             }
    4359     99920431 :                           e->aux = (void *)1;
    4360              :                         }
    4361      4375157 :                       else if (decl)
    4362              :                         {
    4363            0 :                           error ("missing callgraph edge for call stmt:");
    4364            0 :                           cgraph_debug_gimple_stmt (this_cfun, stmt);
    4365            0 :                           error_found = true;
    4366              :                         }
    4367              :                     }
    4368              :                 }
    4369              :               }
    4370     99444790 :             for (i = 0; iterate_reference (i, ref); i++)
    4371     61287629 :               if (ref->stmt && !stmts.contains (ref->stmt))
    4372              :                 {
    4373            0 :                   error ("reference to dead statement");
    4374            0 :                   cgraph_debug_gimple_stmt (this_cfun, ref->stmt);
    4375            0 :                   error_found = true;
    4376              :                 }
    4377     29326910 :         }
    4378              :       else
    4379              :         /* No CFG available?!  */
    4380            0 :         gcc_unreachable ();
    4381              : 
    4382    127127778 :       for (e = callees; e; e = e->next_callee)
    4383              :         {
    4384     97800760 :           if (!e->callback && e->callback_id)
    4385              :             {
    4386            0 :               error ("non-callback edge has callback_id set");
    4387            0 :               error_found = true;
    4388              :             }
    4389              : 
    4390     97800760 :           if (e->callback && e->has_callback)
    4391              :             {
    4392            0 :               error ("edge has both callback and has_callback set");
    4393            0 :               error_found = true;
    4394              :             }
    4395              : 
    4396     97800760 :           if (e->callback)
    4397              :             {
    4398        24102 :               if (!e->get_callback_carrying_edge ())
    4399              :                 {
    4400            0 :                   error ("callback edge %s->%s has no callback-carrying",
    4401            0 :                          identifier_to_locale (e->caller->name ()),
    4402            0 :                          identifier_to_locale (e->callee->name ()));
    4403            0 :                   error_found = true;
    4404              :                 }
    4405              :             }
    4406              : 
    4407     97800760 :           if (e->has_callback
    4408        95155 :               && !callback_is_special_cased (e->callee->decl, e->call_stmt)
    4409     97885178 :               && !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
    4410              :             {
    4411        84406 :               int ncallbacks = 0;
    4412        84406 :               int nfound_edges = 0;
    4413        84406 :               for (tree cb = lookup_attribute (CALLBACK_ATTR_IDENT, DECL_ATTRIBUTES (
    4414              :                                                              e->callee->decl));
    4415       168812 :                    cb; cb = lookup_attribute (CALLBACK_ATTR_IDENT, TREE_CHAIN (cb)),
    4416              :                         ncallbacks++)
    4417              :                 ;
    4418       775030 :               for (cgraph_edge *cbe = callees; cbe; cbe = cbe->next_callee)
    4419              :                 {
    4420       690624 :                   if (cbe->callback && cbe->call_stmt == e->call_stmt
    4421        20730 :                       && cbe->lto_stmt_uid == e->lto_stmt_uid)
    4422              :                     {
    4423        20730 :                       nfound_edges++;
    4424              :                     }
    4425              :                 }
    4426        84406 :               if (ncallbacks < nfound_edges)
    4427              :                 {
    4428            0 :                   error ("callback edge %s->%s callback edge count mismatch, "
    4429              :                          "expected at most %d, found %d",
    4430            0 :                          identifier_to_locale (e->caller->name ()),
    4431            0 :                          identifier_to_locale (e->callee->name ()), ncallbacks,
    4432              :                          nfound_edges);
    4433              :                 }
    4434              :             }
    4435              : 
    4436     97800760 :           if (e->has_callback
    4437     97800760 :               && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
    4438           12 :             for (cgraph_edge *cbe = e->first_callback_edge (); cbe;
    4439            0 :                  cbe = cbe->next_callback_edge ())
    4440            0 :               if (!fndecl_built_in_p (cbe->callee->decl, BUILT_IN_UNREACHABLE))
    4441            0 :                 error ("callback-carrying edge is pointing towards "
    4442              :                        "__builtin_unreachable, but its callback edge %s -> %s "
    4443              :                        "is not",
    4444            0 :                        cbe->caller->name (), cbe->callee->name ());
    4445              : 
    4446     97800760 :           if (!e->aux && !e->speculative && !e->callback && !e->has_callback)
    4447              :             {
    4448            0 :               error ("edge %s->%s has no corresponding call_stmt",
    4449            0 :                      identifier_to_locale (e->caller->name ()),
    4450            0 :                      identifier_to_locale (e->callee->name ()));
    4451            0 :               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4452            0 :               error_found = true;
    4453              :             }
    4454     97800760 :           e->aux = 0;
    4455              :         }
    4456     31614536 :       for (e = indirect_calls; e; e = e->next_callee)
    4457              :         {
    4458      2287518 :           if (!e->aux && !e->speculative)
    4459              :             {
    4460            0 :               error ("an indirect edge from %s has no corresponding call_stmt",
    4461            0 :                      identifier_to_locale (e->caller->name ()));
    4462            0 :               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4463            0 :               error_found = true;
    4464              :             }
    4465      2287518 :           e->aux = 0;
    4466              :         }
    4467              :     }
    4468              : 
    4469     51526688 :   if (nested_function_info *info = nested_function_info::get (this))
    4470              :     {
    4471            0 :       if (info->nested != NULL)
    4472              :         {
    4473            0 :           for (cgraph_node *n = info->nested; n != NULL;
    4474            0 :                n = next_nested_function (n))
    4475              :             {
    4476            0 :               nested_function_info *ninfo = nested_function_info::get (n);
    4477            0 :               if (ninfo->origin == NULL)
    4478              :                 {
    4479            0 :                   error ("missing origin for a node in a nested list");
    4480            0 :                   error_found = true;
    4481              :                 }
    4482            0 :               else if (ninfo->origin != this)
    4483              :                 {
    4484            0 :                   error ("origin points to a different parent");
    4485            0 :                   error_found = true;
    4486            0 :                   break;
    4487              :                 }
    4488              :             }
    4489              :         }
    4490            0 :       if (info->next_nested != NULL && info->origin == NULL)
    4491              :         {
    4492            0 :           error ("missing origin for a node in a nested list");
    4493            0 :           error_found = true;
    4494              :         }
    4495              :     }
    4496              : 
    4497     51526688 :   if (error_found)
    4498              :     {
    4499            0 :       dump (stderr);
    4500            0 :       internal_error ("verify_cgraph_node failed");
    4501              :     }
    4502     51526688 :   timevar_pop (TV_CGRAPH_VERIFY);
    4503              : }
    4504              : 
    4505              : /* Verify whole cgraph structure.  */
    4506              : DEBUG_FUNCTION void
    4507          800 : cgraph_node::verify_cgraph_nodes (void)
    4508              : {
    4509          800 :   cgraph_node *node;
    4510              : 
    4511          800 :   if (seen_error ())
    4512              :     return;
    4513              : 
    4514         5096 :   FOR_EACH_FUNCTION (node)
    4515         4320 :     node->verify ();
    4516              : }
    4517              : 
    4518              : #if __GNUC__ >= 10
    4519              : #  pragma GCC diagnostic pop
    4520              : #endif
    4521              : 
    4522              : /* Walk the alias chain to return the function cgraph_node is alias of.
    4523              :    Walk through thunks, too.
    4524              :    When AVAILABILITY is non-NULL, get minimal availability in the chain.
    4525              :    When REF is non-NULL, assume that reference happens in symbol REF
    4526              :    when determining the availability.  */
    4527              : 
    4528              : cgraph_node *
    4529    132601851 : cgraph_node::function_symbol (enum availability *availability,
    4530              :                               struct symtab_node *ref)
    4531              : {
    4532    132601851 :   cgraph_node *node = ultimate_alias_target (availability, ref);
    4533              : 
    4534    265209080 :   while (node->thunk)
    4535              :     {
    4536         5378 :       enum availability a;
    4537              : 
    4538         5378 :       ref = node;
    4539         5378 :       node = node->callees->callee;
    4540         9343 :       node = node->ultimate_alias_target (availability ? &a : NULL, ref);
    4541         5378 :       if (availability && a < *availability)
    4542           32 :         *availability = a;
    4543              :     }
    4544    132601851 :   return node;
    4545              : }
    4546              : 
    4547              : /* Walk the alias chain to return the function cgraph_node is alias of.
    4548              :    Walk through non virtual thunks, too.  Thus we return either a function
    4549              :    or a virtual thunk node.
    4550              :    When AVAILABILITY is non-NULL, get minimal availability in the chain.
    4551              :    When REF is non-NULL, assume that reference happens in symbol REF
    4552              :    when determining the availability.  */
    4553              : 
    4554              : cgraph_node *
    4555     33280844 : cgraph_node::function_or_virtual_thunk_symbol
    4556              :                                 (enum availability *availability,
    4557              :                                  struct symtab_node *ref)
    4558              : {
    4559     33280844 :   cgraph_node *node = ultimate_alias_target (availability, ref);
    4560              : 
    4561     66562752 :   while (node->thunk && !thunk_info::get (node)->virtual_offset_p)
    4562              :     {
    4563         1064 :       enum availability a;
    4564              : 
    4565         1064 :       ref = node;
    4566         1064 :       node = node->callees->callee;
    4567         1064 :       node = node->ultimate_alias_target (availability ? &a : NULL, ref);
    4568         1064 :       if (availability && a < *availability)
    4569          296 :         *availability = a;
    4570              :     }
    4571     33280844 :   return node;
    4572              : }
    4573              : 
    4574              : /* When doing LTO, read cgraph_node's body from disk if it is not already
    4575              :    present.  Also perform any necessary clone materializations.  */
    4576              : 
    4577              : bool
    4578      6085763 : cgraph_node::get_untransformed_body ()
    4579              : {
    4580      6085763 :   lto_file_decl_data *file_data;
    4581      6085763 :   const char *data, *name;
    4582      6085763 :   size_t len;
    4583      6085763 :   tree decl = this->decl;
    4584              : 
    4585              :   /* See if there is clone to be materialized.
    4586              :      (inline clones does not need materialization, but we can be seeing
    4587              :       an inline clone of real clone).  */
    4588      6085763 :   cgraph_node *p = this;
    4589      8746657 :   for (cgraph_node *c = clone_of; c; c = c->clone_of)
    4590              :     {
    4591      2660894 :       if (c->decl != decl)
    4592       127314 :         p->materialize_clone ();
    4593      2660894 :       p = c;
    4594              :     }
    4595              : 
    4596              :   /* Check if body is already there.  Either we have gimple body or
    4597              :      the function is thunk and in that case we set DECL_ARGUMENTS.  */
    4598      6085763 :   if (DECL_ARGUMENTS (decl) || gimple_has_body_p (decl))
    4599      6002243 :     return false;
    4600              : 
    4601       167040 :   gcc_assert (in_lto_p && !DECL_RESULT (decl));
    4602              : 
    4603        83520 :   timevar_push (TV_IPA_LTO_GIMPLE_IN);
    4604              : 
    4605        83520 :   file_data = lto_file_data;
    4606        83520 :   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    4607              : 
    4608              :   /* We may have renamed the declaration, e.g., a static function.  */
    4609        83520 :   name = lto_get_decl_name_mapping (file_data, name);
    4610        83520 :   struct lto_in_decl_state *decl_state
    4611        83520 :          = lto_get_function_in_decl_state (file_data, decl);
    4612              : 
    4613        83520 :   cgraph_node *origin = this;
    4614       167213 :   while (origin->clone_of)
    4615              :     origin = origin->clone_of;
    4616              : 
    4617        83520 :   int stream_order = origin->order - file_data->order_base;
    4618       167040 :   data = lto_get_section_data (file_data, LTO_section_function_body,
    4619              :                                name, stream_order, &len,
    4620        83520 :                                decl_state->compressed);
    4621        83520 :   if (!data)
    4622            0 :     fatal_error (input_location, "%s: section %s.%d is missing",
    4623              :                  file_data->file_name, name, stream_order);
    4624              : 
    4625        83520 :   gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
    4626              : 
    4627        83520 :   if (!quiet_flag)
    4628            0 :     fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
    4629        83520 :   lto_input_function_body (file_data, this, data);
    4630        83520 :   lto_stats.num_function_bodies++;
    4631        83520 :   lto_free_section_data (file_data, LTO_section_function_body, name,
    4632        83520 :                          data, len, decl_state->compressed);
    4633        83520 :   lto_free_function_in_decl_state_for_node (this);
    4634              :   /* Keep lto file data so ipa-inline-analysis knows about cross module
    4635              :      inlining.  */
    4636              : 
    4637        83520 :   timevar_pop (TV_IPA_LTO_GIMPLE_IN);
    4638              : 
    4639        83520 :   return true;
    4640              : }
    4641              : 
    4642              : /* Prepare function body.  When doing LTO, read cgraph_node's body from disk
    4643              :    if it is not already present.  When some IPA transformations are scheduled,
    4644              :    apply them.  */
    4645              : 
    4646              : bool
    4647        28865 : cgraph_node::get_body (void)
    4648              : {
    4649        28865 :   bool updated;
    4650              : 
    4651        28865 :   updated = get_untransformed_body ();
    4652              : 
    4653              :   /* Getting transformed body makes no sense for inline clones;
    4654              :      we should never use this on real clones because they are materialized
    4655              :      early.
    4656              :      TODO: Materializing clones here will likely lead to smaller LTRANS
    4657              :      footprint. */
    4658        28865 :   gcc_assert (!inlined_to && !clone_of);
    4659        28865 :   if (ipa_transforms_to_apply.exists ())
    4660              :     {
    4661        12380 :       opt_pass *saved_current_pass = current_pass;
    4662        12380 :       FILE *saved_dump_file = dump_file;
    4663        12380 :       const char *saved_dump_file_name = dump_file_name;
    4664        12380 :       dump_flags_t saved_dump_flags = dump_flags;
    4665        12380 :       dump_file_name = NULL;
    4666        12380 :       set_dump_file (NULL);
    4667              : 
    4668        12380 :       push_cfun (DECL_STRUCT_FUNCTION (decl));
    4669              : 
    4670        12380 :       update_ssa (TODO_update_ssa_only_virtuals);
    4671        12380 :       execute_all_ipa_transforms (true);
    4672        12380 :       cgraph_edge::rebuild_edges ();
    4673        12380 :       free_dominance_info (CDI_DOMINATORS);
    4674        12380 :       free_dominance_info (CDI_POST_DOMINATORS);
    4675        12380 :       pop_cfun ();
    4676        12380 :       updated = true;
    4677              : 
    4678        12380 :       current_pass = saved_current_pass;
    4679        12380 :       set_dump_file (saved_dump_file);
    4680        12380 :       dump_file_name = saved_dump_file_name;
    4681        12380 :       dump_flags = saved_dump_flags;
    4682              :     }
    4683        28865 :   return updated;
    4684              : }
    4685              : 
    4686              : /* Return the DECL_STRUCT_FUNCTION of the function.  */
    4687              : 
    4688              : struct function *
    4689        99464 : cgraph_node::get_fun () const
    4690              : {
    4691        99464 :   const cgraph_node *node = this;
    4692        99464 :   struct function *fun = DECL_STRUCT_FUNCTION (node->decl);
    4693              : 
    4694        99464 :   while (!fun && node->clone_of)
    4695              :     {
    4696            0 :       node = node->clone_of;
    4697            0 :       fun = DECL_STRUCT_FUNCTION (node->decl);
    4698              :     }
    4699              : 
    4700        99464 :   return fun;
    4701              : }
    4702              : 
    4703              : /* Reset all state within cgraph.cc so that we can rerun the compiler
    4704              :    within the same process.  For use by toplev::finalize.  */
    4705              : 
    4706              : void
    4707       256621 : cgraph_cc_finalize (void)
    4708              : {
    4709       256621 :   nested_function_info::release ();
    4710       256621 :   thunk_info::release ();
    4711       256621 :   clone_info::release ();
    4712       256621 :   symtab = NULL;
    4713              : 
    4714       256621 :   x_cgraph_nodes_queue = NULL;
    4715              : 
    4716       256621 :   cgraph_fnver_htab = NULL;
    4717       256621 :   version_info_node = NULL;
    4718       256621 : }
    4719              : 
    4720              : /* A worker for call_for_symbol_and_aliases.  */
    4721              : 
    4722              : bool
    4723       709038 : cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
    4724              :                                                               void *),
    4725              :                                             void *data,
    4726              :                                             bool include_overwritable)
    4727              : {
    4728       709038 :   ipa_ref *ref;
    4729      1396687 :   FOR_EACH_ALIAS (this, ref)
    4730              :     {
    4731       790017 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    4732       790017 :       if (include_overwritable
    4733       790017 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
    4734       790017 :         if (alias->call_for_symbol_and_aliases (callback, data,
    4735              :                                                 include_overwritable))
    4736              :           return true;
    4737              :     }
    4738              :   return false;
    4739              : }
    4740              : 
    4741              : /* Return true if NODE has thunk.  */
    4742              : 
    4743              : bool
    4744        39111 : cgraph_node::has_thunk_p (cgraph_node *node, void *)
    4745              : {
    4746        73578 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    4747        34467 :     if (e->caller->thunk)
    4748              :       return true;
    4749              :   return false;
    4750              : }
    4751              : 
    4752              : /* Expected frequency of executions within the function.  */
    4753              : 
    4754              : sreal
    4755    211215560 : cgraph_edge::sreal_frequency ()
    4756              : {
    4757    211215560 :   return count.to_sreal_scale (caller->inlined_to
    4758    211215560 :                                ? caller->inlined_to->count
    4759    211215560 :                                : caller->count);
    4760              : }
    4761              : 
    4762              : /* Expected frequency of executions within the function.
    4763              :    If edge is speculative, sum all its indirect targets.  */
    4764              : 
    4765              : sreal
    4766         3993 : cgraph_edge::combined_sreal_frequency ()
    4767              : {
    4768         3993 :   if (!speculative)
    4769         3724 :     return sreal_frequency ();
    4770          269 :   cgraph_edge *e = this;
    4771          269 :   if (e->callee)
    4772            0 :     e = e->speculative_call_indirect_edge ();
    4773          269 :   sreal sum = e->sreal_frequency ();
    4774          269 :   for (e = e->first_speculative_call_target ();
    4775          624 :        e;
    4776          355 :        e = e->next_speculative_call_target ())
    4777          355 :     sum += e->sreal_frequency ();
    4778          269 :   return sum;
    4779              : }
    4780              : 
    4781              : 
    4782              : /* During LTO stream in this can be used to check whether call can possibly
    4783              :    be internal to the current translation unit.  */
    4784              : 
    4785              : bool
    4786       479164 : cgraph_edge::possibly_call_in_translation_unit_p (void)
    4787              : {
    4788       479164 :   gcc_checking_assert (in_lto_p && caller->prevailing_p ());
    4789              : 
    4790              :   /* While incremental linking we may end up getting function body later.  */
    4791       479164 :   if (flag_incremental_link == INCREMENTAL_LINK_LTO)
    4792              :     return true;
    4793              : 
    4794              :   /* We may be smarter here and avoid streaming in indirect calls we can't
    4795              :      track, but that would require arranging streaming the indirect call
    4796              :      summary first.  */
    4797       478937 :   if (!callee)
    4798              :     return true;
    4799              : 
    4800              :   /* If callee is local to the original translation unit, it will be
    4801              :      defined.  */
    4802       476213 :   if (!TREE_PUBLIC (callee->decl) && !DECL_EXTERNAL (callee->decl))
    4803              :     return true;
    4804              : 
    4805              :   /* Otherwise we need to lookup prevailing symbol (symbol table is not merged,
    4806              :      yet) and see if it is a definition.  In fact we may also resolve aliases,
    4807              :      but that is probably not too important.  */
    4808       480227 :   symtab_node *node = callee;
    4809       480227 :   for (int n = 10; node->previous_sharing_asm_name && n ; n--)
    4810        10105 :     node = node->previous_sharing_asm_name;
    4811       470122 :   if (node->previous_sharing_asm_name)
    4812          234 :     node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (callee->decl));
    4813       470122 :   gcc_assert (TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
    4814       470122 :   return node->get_availability () >= AVAIL_INTERPOSABLE;
    4815              : }
    4816              : 
    4817              : /* Return num_speculative_targets of this edge.  */
    4818              : 
    4819              : int
    4820       184517 : cgraph_edge::num_speculative_call_targets_p (void)
    4821              : {
    4822       184517 :   return indirect_info ? indirect_info->num_speculative_call_targets : 0;
    4823              : }
    4824              : 
    4825              : /* Check if function calls comdat local.  This is used to recompute
    4826              :    calls_comdat_local flag after function transformations.  */
    4827              : bool
    4828     48402506 : cgraph_node::check_calls_comdat_local_p ()
    4829              : {
    4830    156130028 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
    4831      3574446 :     if (e->inline_failed
    4832    116449196 :         ? e->callee->comdat_local_p ()
    4833      3574446 :         : e->callee->check_calls_comdat_local_p ())
    4834        49376 :       return true;
    4835              :   return false;
    4836              : }
    4837              : 
    4838              : /* Return true if this node represents a former, i.e. an expanded, thunk.  */
    4839              : 
    4840              : bool
    4841      5050942 : cgraph_node::former_thunk_p (void)
    4842              : {
    4843      5050942 :   if (thunk)
    4844              :     return false;
    4845      5050942 :   thunk_info *i = thunk_info::get (this);
    4846      5050942 :   if (!i)
    4847              :     return false;
    4848           67 :   gcc_checking_assert (i->fixed_offset || i->virtual_offset_p
    4849              :                        || i->indirect_offset);
    4850              :   return true;
    4851              : }
    4852              : 
    4853              : /* A stashed copy of "symtab" for use by selftest::symbol_table_test.
    4854              :    This needs to be a global so that it can be a GC root, and thus
    4855              :    prevent the stashed copy from being garbage-collected if the GC runs
    4856              :    during a symbol_table_test.  */
    4857              : 
    4858              : symbol_table *saved_symtab;
    4859              : 
    4860              : #if CHECKING_P
    4861              : 
    4862              : namespace selftest {
    4863              : 
    4864              : /* class selftest::symbol_table_test.  */
    4865              : 
    4866              : /* Constructor.  Store the old value of symtab, and create a new one.  */
    4867              : 
    4868           64 : symbol_table_test::symbol_table_test ()
    4869              : {
    4870           64 :   gcc_assert (saved_symtab == NULL);
    4871           64 :   saved_symtab = symtab;
    4872           64 :   symtab = new (ggc_alloc<symbol_table> ()) symbol_table ();
    4873           64 : }
    4874              : 
    4875              : /* Destructor.  Restore the old value of symtab.  */
    4876              : 
    4877           64 : symbol_table_test::~symbol_table_test ()
    4878              : {
    4879           64 :   gcc_assert (saved_symtab != NULL);
    4880           64 :   symtab = saved_symtab;
    4881           64 :   saved_symtab = NULL;
    4882           64 : }
    4883              : 
    4884              : /* Verify that symbol_table_test works.  */
    4885              : 
    4886              : static void
    4887            4 : test_symbol_table_test ()
    4888              : {
    4889              :   /* Simulate running two selftests involving symbol tables.  */
    4890           12 :   for (int i = 0; i < 2; i++)
    4891              :     {
    4892            8 :       symbol_table_test stt;
    4893            8 :       tree test_decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
    4894              :                                    get_identifier ("test_decl"),
    4895              :                                    build_function_type_list (void_type_node,
    4896              :                                                              NULL_TREE));
    4897            8 :       cgraph_node *node = cgraph_node::get_create (test_decl);
    4898            8 :       gcc_assert (node);
    4899              : 
    4900              :       /* Verify that the node has order 0 on both iterations,
    4901              :          and thus that nodes have predictable dump names in selftests.  */
    4902            8 :       ASSERT_EQ (node->order, 0);
    4903            8 :       ASSERT_STREQ (node->dump_name (), "test_decl/1");
    4904            8 :     }
    4905            4 : }
    4906              : 
    4907              : /* Run all of the selftests within this file.  */
    4908              : 
    4909              : void
    4910            4 : cgraph_cc_tests ()
    4911              : {
    4912            4 :   test_symbol_table_test ();
    4913            4 : }
    4914              : 
    4915              : } // namespace selftest
    4916              : 
    4917              : #endif /* CHECKING_P */
    4918              : 
    4919              : #include "gt-cgraph.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.