LCOV - code coverage report
Current view: top level - gcc - cgraph.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 81.9 % 2344 1919
Test Date: 2026-03-28 14:25:54 Functions: 92.6 % 136 126
Legend: Lines:     hit not hit

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