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