LCOV - code coverage report
Current view: top level - gcc - cgraph.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 81.8 % 2347 1921
Test Date: 2026-04-20 14:57:17 Functions: 92.7 % 137 127
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Callgraph handling code.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              :    Contributed by Jan Hubicka
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : /*  This file contains basic routines manipulating call graph
      22              : 
      23              :     The call-graph is a data structure designed for inter-procedural
      24              :     optimization.  It represents a multi-graph where nodes are functions
      25              :     (symbols within symbol table) and edges are call sites. */
      26              : 
      27              : #include "config.h"
      28              : #include "system.h"
      29              : #include "coretypes.h"
      30              : #include "backend.h"
      31              : #include "target.h"
      32              : #include "rtl.h"
      33              : #include "tree.h"
      34              : #include "gimple.h"
      35              : #include "predict.h"
      36              : #include "alloc-pool.h"
      37              : #include "gimple-ssa.h"
      38              : #include "cgraph.h"
      39              : #include "lto-streamer.h"
      40              : #include "fold-const.h"
      41              : #include "varasm.h"
      42              : #include "calls.h"
      43              : #include "print-tree.h"
      44              : #include "langhooks.h"
      45              : #include "intl.h"
      46              : #include "tree-eh.h"
      47              : #include "gimple-iterator.h"
      48              : #include "tree-cfg.h"
      49              : #include "tree-ssa.h"
      50              : #include "value-prof.h"
      51              : #include "ipa-utils.h"
      52              : #include "symbol-summary.h"
      53              : #include "tree-vrp.h"
      54              : #include "sreal.h"
      55              : #include "ipa-cp.h"
      56              : #include "ipa-prop.h"
      57              : #include "ipa-fnsummary.h"
      58              : #include "cfgloop.h"
      59              : #include "gimple-pretty-print.h"
      60              : #include "tree-dfa.h"
      61              : #include "profile.h"
      62              : #include "context.h"
      63              : #include "gimplify.h"
      64              : #include "stringpool.h"
      65              : #include "attribs.h"
      66              : #include "selftest.h"
      67              : #include "tree-into-ssa.h"
      68              : #include "ipa-inline.h"
      69              : #include "tree-nested.h"
      70              : #include "symtab-thunks.h"
      71              : #include "symtab-clones.h"
      72              : #include "attr-callback.h"
      73              : 
      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      5027149 : symtab_node::address_can_be_compared_p ()
     151              : {
     152              :   /* Address of virtual tables and functions is never compared.  */
     153      5027149 :   if (DECL_VIRTUAL_P (decl))
     154              :     return false;
     155              :   /* Address of C++ cdtors is never compared.  */
     156      4935644 :   if (is_a <cgraph_node *> (this)
     157       543940 :       && (DECL_CXX_CONSTRUCTOR_P (decl)
     158       539546 :           || 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      4929851 :   if (is_a <varpool_node *> (this)
     163      4391704 :       && (DECL_IN_CONSTANT_POOL (decl)
     164      4391701 :           || ((flag_merge_constants >= 2 || DECL_MERGEABLE (decl))
     165         2088 :               && TREE_READONLY (decl) && !TREE_THIS_VOLATILE (decl))))
     166         2084 :     return false;
     167              :   return true;
     168              : }
     169              : 
     170              : /* Get the cgraph_function_version_info node corresponding to node.  */
     171              : cgraph_function_version_info *
     172    135523610 : cgraph_node::function_version (void)
     173              : {
     174    135523610 :   cgraph_function_version_info key;
     175    135523610 :   key.this_node = this;
     176              : 
     177    135523610 :   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      1591392 : cgraph_node::apply_scale (profile_count num, profile_count den)
     266              : {
     267      1715527 :   if (num == den && !(num == profile_count::zero ()))
     268       122235 :     return;
     269              : 
     270      2745634 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
     271              :     {
     272      1276477 :       if (!e->inline_failed)
     273       162681 :         e->callee->apply_scale (num, den);
     274      1276477 :       e->count = e->count.apply_scale (num, den);
     275              :     }
     276      1495355 :   for (cgraph_edge *e = indirect_calls; e; e = e->next_callee)
     277        26198 :     e->count = e->count.apply_scale (num, den);
     278      1469157 :   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    104189579 : cgraph_node::delete_function_version (cgraph_function_version_info *decl_v)
     339              : {
     340    104189579 :   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       302424 : symbol_table::initialize (void)
     431              : {
     432       302424 :   if (!dump_file)
     433       302422 :     dump_file = dump_begin (TDI_cgraph, NULL);
     434              : 
     435       302424 :   if (!ipa_clones_dump_file)
     436       302424 :     ipa_clones_dump_file = dump_begin (TDI_clones, NULL);
     437       302424 : }
     438              : 
     439              : /* Allocate new callgraph node and insert it into basic data structures.  */
     440              : 
     441              : cgraph_node *
     442    107948656 : symbol_table::create_empty (void)
     443              : {
     444    107948656 :   cgraph_count++;
     445    107948656 :   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      1909365 : symbol_table::add_edge_removal_hook (cgraph_edge_hook hook, void *data)
     451              : {
     452      1909365 :   cgraph_edge_hook_list *entry;
     453      3818730 :   cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
     454              : 
     455      1909365 :   entry = (cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
     456      1909365 :   entry->hook = hook;
     457      1909365 :   entry->data = data;
     458      1909365 :   entry->next = NULL;
     459      6612185 :   while (*ptr)
     460      4702820 :     ptr = &(*ptr)->next;
     461      1909365 :   *ptr = entry;
     462      1909365 :   return entry;
     463              : }
     464              : 
     465              : /* Remove ENTRY from the list of hooks called on removing edges.  */
     466              : void
     467      1909351 : symbol_table::remove_edge_removal_hook (cgraph_edge_hook_list *entry)
     468              : {
     469      1909351 :   cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
     470              : 
     471      5209491 :   while (*ptr != entry)
     472      3300140 :     ptr = &(*ptr)->next;
     473      1909351 :   *ptr = entry->next;
     474      1909351 :   free (entry);
     475      1909351 : }
     476              : 
     477              : /* Call all edge removal hooks.  */
     478              : void
     479     44751958 : symbol_table::call_edge_removal_hooks (cgraph_edge *e)
     480              : {
     481     44751958 :   cgraph_edge_hook_list *entry = m_first_edge_removal_hook;
     482     73328176 :   while (entry)
     483              :   {
     484     28576218 :     entry->hook (e, entry->data);
     485     28576218 :     entry = entry->next;
     486              :   }
     487     44751958 : }
     488              : 
     489              : /* Register HOOK to be called with DATA on each removed node.  */
     490              : cgraph_node_hook_list *
     491      8011235 : symbol_table::add_cgraph_removal_hook (cgraph_node_hook hook, void *data)
     492              : {
     493      8011235 :   cgraph_node_hook_list *entry;
     494     16022470 :   cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
     495              : 
     496      8011235 :   entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
     497      8011235 :   entry->hook = hook;
     498      8011235 :   entry->data = data;
     499      8011235 :   entry->next = NULL;
     500     41758497 :   while (*ptr)
     501     33747262 :     ptr = &(*ptr)->next;
     502      8011235 :   *ptr = entry;
     503      8011235 :   return entry;
     504              : }
     505              : 
     506              : /* Remove ENTRY from the list of hooks called on removing nodes.  */
     507              : void
     508      7901310 : symbol_table::remove_cgraph_removal_hook (cgraph_node_hook_list *entry)
     509              : {
     510      7901310 :   cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
     511              : 
     512     37186800 :   while (*ptr != entry)
     513     29285490 :     ptr = &(*ptr)->next;
     514      7901310 :   *ptr = entry->next;
     515      7901310 :   free (entry);
     516      7901310 : }
     517              : 
     518              : /* Call all node removal hooks.  */
     519              : void
     520    104221903 : symbol_table::call_cgraph_removal_hooks (cgraph_node *node)
     521              : {
     522    104221903 :   cgraph_node_hook_list *entry = m_first_cgraph_removal_hook;
     523    146542722 :   while (entry)
     524              :   {
     525     42320819 :     entry->hook (node, entry->data);
     526     42320819 :     entry = entry->next;
     527              :   }
     528    104221903 : }
     529              : 
     530              : /* Call all node removal hooks.  */
     531              : void
     532       119513 : symbol_table::call_cgraph_insertion_hooks (cgraph_node *node)
     533              : {
     534       119513 :   cgraph_node_hook_list *entry = m_first_cgraph_insertion_hook;
     535       358773 :   while (entry)
     536              :   {
     537       239260 :     entry->hook (node, entry->data);
     538       239260 :     entry = entry->next;
     539              :   }
     540       119513 : }
     541              : 
     542              : 
     543              : /* Register HOOK to be called with DATA on each inserted node.  */
     544              : cgraph_node_hook_list *
     545      8496649 : symbol_table::add_cgraph_insertion_hook (cgraph_node_hook hook, void *data)
     546              : {
     547      8496649 :   cgraph_node_hook_list *entry;
     548     16993298 :   cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
     549              : 
     550      8496649 :   entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
     551      8496649 :   entry->hook = hook;
     552      8496649 :   entry->data = data;
     553      8496649 :   entry->next = NULL;
     554     25191266 :   while (*ptr)
     555     16694617 :     ptr = &(*ptr)->next;
     556      8496649 :   *ptr = entry;
     557      8496649 :   return entry;
     558              : }
     559              : 
     560              : /* Remove ENTRY from the list of hooks called on inserted nodes.  */
     561              : void
     562      8349102 : symbol_table::remove_cgraph_insertion_hook (cgraph_node_hook_list *entry)
     563              : {
     564      8349102 :   cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
     565              : 
     566     23050685 :   while (*ptr != entry)
     567     14701583 :     ptr = &(*ptr)->next;
     568      8349102 :   *ptr = entry->next;
     569      8349102 :   free (entry);
     570      8349102 : }
     571              : 
     572              : /* Register HOOK to be called with DATA on each duplicated edge.  */
     573              : cgraph_2edge_hook_list *
     574      1676848 : symbol_table::add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
     575              : {
     576      1676848 :   cgraph_2edge_hook_list *entry;
     577      3353696 :   cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
     578              : 
     579      1676848 :   entry = (cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
     580      1676848 :   entry->hook = hook;
     581      1676848 :   entry->data = data;
     582      1676848 :   entry->next = NULL;
     583      5389623 :   while (*ptr)
     584      3712775 :     ptr = &(*ptr)->next;
     585      1676848 :   *ptr = entry;
     586      1676848 :   return entry;
     587              : }
     588              : 
     589              : /* Remove ENTRY from the list of hooks called on duplicating edges.  */
     590              : void
     591      1676834 : symbol_table::remove_edge_duplication_hook (cgraph_2edge_hook_list *entry)
     592              : {
     593      1676834 :   cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
     594              : 
     595      3986929 :   while (*ptr != entry)
     596      2310095 :     ptr = &(*ptr)->next;
     597      1676834 :   *ptr = entry->next;
     598      1676834 :   free (entry);
     599      1676834 : }
     600              : 
     601              : /* Call all edge duplication hooks.  */
     602              : void
     603      7362934 : symbol_table::call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2)
     604              : {
     605      7362934 :   cgraph_2edge_hook_list *entry = m_first_edge_duplicated_hook;
     606     21995047 :   while (entry)
     607              :   {
     608     14632113 :     entry->hook (cs1, cs2, entry->data);
     609     14632113 :     entry = entry->next;
     610              :   }
     611      7362934 : }
     612              : 
     613              : /* Register HOOK to be called with DATA on each duplicated node.  */
     614              : cgraph_2node_hook_list *
     615      7869251 : symbol_table::add_cgraph_duplication_hook (cgraph_2node_hook hook, void *data)
     616              : {
     617      7869251 :   cgraph_2node_hook_list *entry;
     618     15738502 :   cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
     619              : 
     620      7869251 :   entry = (cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
     621      7869251 :   entry->hook = hook;
     622      7869251 :   entry->data = data;
     623      7869251 :   entry->next = NULL;
     624     38840981 :   while (*ptr)
     625     30971730 :     ptr = &(*ptr)->next;
     626      7869251 :   *ptr = entry;
     627      7869251 :   return entry;
     628              : }
     629              : 
     630              : /* Remove ENTRY from the list of hooks called on duplicating nodes.  */
     631              : void
     632      7772624 : symbol_table::remove_cgraph_duplication_hook (cgraph_2node_hook_list *entry)
     633              : {
     634      7772624 :   cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
     635              : 
     636     35235895 :   while (*ptr != entry)
     637     27463271 :     ptr = &(*ptr)->next;
     638      7772624 :   *ptr = entry->next;
     639      7772624 :   free (entry);
     640      7772624 : }
     641              : 
     642              : /* Call all node duplication hooks.  */
     643              : void
     644      3122116 : symbol_table::call_cgraph_duplication_hooks (cgraph_node *node,
     645              :                                              cgraph_node *node2)
     646              : {
     647      3122116 :   cgraph_2node_hook_list *entry = m_first_cgraph_duplicated_hook;
     648     22204715 :   while (entry)
     649              :   {
     650     19082599 :     entry->hook (node, node2, entry->data);
     651     19082599 :     entry = entry->next;
     652              :   }
     653      3122116 : }
     654              : 
     655              : /* Return cgraph node assigned to DECL.  Create new one when needed.  */
     656              : 
     657              : cgraph_node *
     658    104630826 : cgraph_node::create (tree decl)
     659              : {
     660    104630826 :   cgraph_node *node = symtab->create_empty ();
     661    104630826 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
     662              : 
     663    104630826 :   node->decl = decl;
     664    104630826 :   node->semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
     665              : 
     666    104571224 :   if ((flag_openacc || flag_openmp)
     667    104898333 :       && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
     668              :     {
     669         8438 :       node->offloadable = 1;
     670         8438 :       if (ENABLE_OFFLOADING)
     671              :         g->have_offload = true;
     672              :     }
     673              : 
     674    104630826 :   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     675          125 :     node->ifunc_resolver = true;
     676              : 
     677    104630826 :   node->register_symbol ();
     678    104630826 :   maybe_record_nested_function (node);
     679              : 
     680    104630826 :   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    582467939 : cgraph_node::get_create (tree decl)
     688              : {
     689    582467939 :   cgraph_node *first_clone = cgraph_node::get (decl);
     690              : 
     691    582467939 :   if (first_clone && !first_clone->inlined_to)
     692              :     return first_clone;
     693              : 
     694    104564210 :   cgraph_node *node = cgraph_node::create (decl);
     695    104564210 :   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    104564204 :   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      7785808 : cgraph_node::create_alias (tree alias, tree target)
     719              : {
     720      7785808 :   cgraph_node *alias_node;
     721              : 
     722      7785808 :   gcc_assert (TREE_CODE (target) == FUNCTION_DECL
     723              :               || TREE_CODE (target) == IDENTIFIER_NODE);
     724      7785808 :   gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
     725      7785808 :   alias_node = cgraph_node::get_create (alias);
     726      7785808 :   gcc_assert (!alias_node->definition);
     727      7785808 :   alias_node->alias_target = target;
     728      7785808 :   alias_node->definition = true;
     729      7785808 :   alias_node->alias = true;
     730      7785808 :   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     731           47 :     alias_node->transparent_alias = alias_node->weakref = true;
     732      7785808 :   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
     733          322 :     alias_node->ifunc_resolver = true;
     734      7785808 :   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      7766352 : cgraph_node::create_same_body_alias (tree alias, tree decl)
     745              : {
     746      7766352 :   cgraph_node *n;
     747              : 
     748              :   /* If aliases aren't supported by the assembler, fail.  */
     749      7766352 :   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      7766352 :   if (symtab->global_info_ready)
     755              :     return NULL;
     756              : 
     757      7766352 :   n = cgraph_node::create_alias (alias, decl);
     758      7766352 :   n->cpp_implicit_alias = true;
     759      7766352 :   if (symtab->cpp_implicit_aliases_done)
     760      3578707 :     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         4349 : 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         4349 :   cgraph_node *node;
     777              : 
     778         4349 :   node = cgraph_node::get (alias);
     779         4349 :   if (node)
     780         3623 :     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         4349 :   gcc_checking_assert (virtual_offset
     786              :                        ? virtual_value == wi::to_wide (virtual_offset)
     787              :                        : virtual_value == 0);
     788              : 
     789         4349 :   node->thunk = true;
     790         4349 :   node->definition = true;
     791              : 
     792         4349 :   thunk_info *i;
     793         4349 :   thunk_info local_info;
     794         4349 :   if (symtab->state < CONSTRUCTION)
     795              :     i = &local_info;
     796              :   else
     797            0 :     i = thunk_info::get_create (node);
     798         4349 :   i->fixed_offset = fixed_offset;
     799         4349 :   i->virtual_value = virtual_value;
     800         4349 :   i->indirect_offset = indirect_offset;
     801         4349 :   i->alias = real_alias;
     802         4349 :   i->this_adjusting = this_adjusting;
     803         4349 :   i->virtual_offset_p = virtual_offset != NULL;
     804         4349 :   if (symtab->state < CONSTRUCTION)
     805         4349 :     i->register_early (node);
     806              : 
     807         4349 :   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    229532102 : 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    229532102 :   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     45920902 : 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     45920902 :   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    281562476 : cgraph_edge_hasher::equal (cgraph_edge *x, gimple *y)
     852              : {
     853    281562476 :   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         5201 : cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
     860              : {
     861         5201 :   gimple *call = e->call_stmt;
     862         5201 :   *e->caller->call_site_hash->find_slot_with_hash
     863         5201 :       (call, cgraph_edge_hasher::hash (call), INSERT) = e;
     864         5201 : }
     865              : 
     866              : /* Add call graph edge E to call site hash of its caller.  */
     867              : 
     868              : static inline void
     869      8668682 : 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      8668682 :   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      8668668 :   if (e->callback)
     879              :     return;
     880      8668656 :   cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
     881      8668656 :       (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt), INSERT);
     882      8668656 :   if (*slot)
     883              :     {
     884         5279 :       cgraph_edge *edge = (cgraph_edge *) *slot;
     885         5279 :       gcc_assert (edge->speculative || edge->has_callback);
     886         5279 :       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         5187 :       if (e->callee && (!e->prev_callee
     893            4 :                         || !e->prev_callee->speculative
     894            4 :                         || e->prev_callee->call_stmt != e->call_stmt))
     895          816 :         *slot = e;
     896         5187 :       return;
     897              :     }
     898      8663377 :   gcc_assert (!*slot || e->speculative);
     899      8663377 :   *slot = e;
     900              : }
     901              : 
     902              : /* Return the callgraph edge representing the GIMPLE_CALL statement
     903              :    CALL_STMT.  */
     904              : 
     905              : cgraph_edge *
     906    208510627 : cgraph_node::get_edge (gimple *call_stmt)
     907              : {
     908    208510627 :   cgraph_edge *e, *e2;
     909    208510627 :   int n = 0;
     910              : 
     911    208510627 :   if (call_site_hash)
     912     35992491 :     return call_site_hash->find_with_hash
     913     35992491 :         (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   1670612139 :   for (e = callees; e; e = e->next_callee)
     921              :     {
     922   1623345288 :       if (e->call_stmt == call_stmt)
     923              :         break;
     924   1498094003 :       n++;
     925              :     }
     926              : 
     927    172518136 :   if (!e)
     928     60844444 :     for (e = indirect_calls; e; e = e->next_callee)
     929              :       {
     930     16401040 :         if (e->call_stmt == call_stmt)
     931              :           break;
     932     13577593 :         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    172518136 :   if (e && e->callback)
     940        55581 :     e = e->get_callback_carrying_edge ();
     941              : 
     942    172518136 :   if (n > 100)
     943              :     {
     944        31267 :       call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc (120);
     945      3208607 :       for (e2 = callees; e2; e2 = e2->next_callee)
     946      3177340 :         cgraph_add_edge_to_call_site_hash (e2);
     947       116180 :       for (e2 = indirect_calls; e2; e2 = e2->next_callee)
     948        84913 :         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      2916056 : cgraph_edge::set_call_stmt (cgraph_edge *e, gcall *new_stmt,
     963              :                             bool update_derived_edges)
     964              : {
     965      2916056 :   tree decl;
     966              : 
     967      2916056 :   cgraph_node *new_direct_callee = NULL;
     968      2886284 :   if ((e->indirect_unknown_callee || e->speculative)
     969      2961136 :       && (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      2916056 :   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         6598 :       && !new_direct_callee)
     983              :     {
     984         6598 :       cgraph_edge *direct, *indirect, *next;
     985         6598 :       ipa_ref *ref;
     986         6598 :       bool e_indirect = e->indirect_unknown_callee;
     987         6598 :       int n = 0;
     988              : 
     989         6598 :       direct = e->first_speculative_call_target ();
     990         6598 :       indirect = e->speculative_call_indirect_edge ();
     991              : 
     992         6598 :       gcall *old_stmt = direct->call_stmt;
     993        15308 :       for (cgraph_edge *d = direct; d; d = next)
     994              :         {
     995         8710 :           next = d->next_speculative_call_target ();
     996         8710 :           cgraph_edge *d2 = set_call_stmt (d, new_stmt, false);
     997         8710 :           gcc_assert (d2 == d);
     998         8710 :           n++;
     999              :         }
    1000         6598 :       gcc_checking_assert (indirect->num_speculative_call_targets_p () == n);
    1001        19715 :       for (unsigned int i = 0; e->caller->iterate_reference (i, ref); i++)
    1002        13117 :         if (ref->speculative && ref->stmt == old_stmt)
    1003              :           {
    1004         8710 :             ref->stmt = new_stmt;
    1005         8710 :             n--;
    1006              :           }
    1007              : 
    1008         6598 :       indirect = set_call_stmt (indirect, new_stmt, false);
    1009         6598 :       return e_indirect ? indirect : direct;
    1010              :     }
    1011              : 
    1012      2909458 :   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      2909458 :   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      2908668 :   if (e->caller->call_site_hash
    1038       600247 :       && (!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      3508915 :       && e->caller->get_edge (e->call_stmt) == e)
    1042       595044 :     e->caller->call_site_hash->remove_elt_with_hash
    1043       595044 :       (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt));
    1044              : 
    1045      2908668 :   e->call_stmt = new_stmt;
    1046              : 
    1047      2908668 :   function *fun = DECL_STRUCT_FUNCTION (e->caller->decl);
    1048      2908668 :   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      2908668 :   if (e->caller->call_site_hash
    1052       600247 :       && (!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       600247 :     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     45185787 : 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     45185787 :   cgraph_edge *edge;
    1072              : 
    1073              :   /* LTO does not actually have access to the call_stmt since these
    1074              :      have not been loaded yet.  */
    1075     45185787 :   if (call_stmt)
    1076              :     {
    1077              :       /* This is a rather expensive check possibly triggering
    1078              :          construction of call stmt hashtable.  */
    1079     44326708 :       cgraph_edge *e;
    1080     44326708 :       gcc_checking_assert (!(e = caller->get_edge (call_stmt))
    1081              :                            || e->speculative || e->has_callback || e->callback);
    1082              : 
    1083     44326708 :       gcc_assert (is_gimple_call (call_stmt));
    1084              :     }
    1085              : 
    1086     45185787 :   edge = ggc_alloc<cgraph_edge> ();
    1087     45185787 :   edge->m_summary_id = -1;
    1088     45185787 :   edges_count++;
    1089              : 
    1090     45185787 :   ++edges_max_uid;
    1091     45185787 :   gcc_assert (edges_max_uid != 0);
    1092     45185787 :   edge->m_uid = edges_max_uid;
    1093     45185787 :   edge->aux = NULL;
    1094     45185787 :   edge->caller = caller;
    1095     45185787 :   edge->callee = callee;
    1096     45185787 :   edge->prev_caller = NULL;
    1097     45185787 :   edge->next_caller = NULL;
    1098     45185787 :   edge->prev_callee = NULL;
    1099     45185787 :   edge->next_callee = NULL;
    1100     45185787 :   edge->lto_stmt_uid = 0;
    1101     45185787 :   edge->speculative_id = 0;
    1102              : 
    1103     45185787 :   edge->count = count;
    1104     45185787 :   edge->call_stmt = call_stmt;
    1105     45185787 :   edge->indirect_info = NULL;
    1106     45185787 :   edge->indirect_inlining_edge = 0;
    1107     45185787 :   edge->speculative = false;
    1108     45185787 :   edge->has_callback = false;
    1109     45185787 :   edge->callback = false;
    1110     45185787 :   edge->callback_id = 0;
    1111     45185787 :   edge->indirect_unknown_callee = indir_unknown_callee;
    1112     45185787 :   if (call_stmt && caller->call_site_hash)
    1113      4806182 :     cgraph_add_edge_to_call_site_hash (edge);
    1114              : 
    1115     45185787 :   if (cloning_p)
    1116              :     return edge;
    1117              : 
    1118     37835457 :   edge->can_throw_external
    1119     37835457 :     = call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl),
    1120              :                                            call_stmt) : false;
    1121     37835457 :   edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
    1122     37835457 :   edge->call_stmt_cannot_inline_p = false;
    1123              : 
    1124     37835457 :   if (opt_for_fn (edge->caller->decl, flag_devirtualize)
    1125     37835457 :       && call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
    1126     29665886 :     edge->in_polymorphic_cdtor
    1127     29665886 :       = decl_maybe_in_construction_p (NULL, NULL, call_stmt,
    1128              :                                       caller->decl);
    1129              :   else
    1130      8169571 :     edge->in_polymorphic_cdtor = caller->thunk;
    1131              : 
    1132     37169500 :   if (callee && symtab->state != LTO_STREAMING
    1133     74406829 :       && edge->callee->comdat_local_p ())
    1134         6792 :     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     44352906 : cgraph_node::create_edge (cgraph_node *callee,
    1145              :                           gcall *call_stmt, profile_count count, bool cloning_p)
    1146              : {
    1147     44352906 :   cgraph_edge *edge = symtab->create_edge (this, callee, call_stmt, count,
    1148              :                                            false, cloning_p);
    1149              : 
    1150     44352906 :   if (!cloning_p)
    1151     37169500 :     initialize_inline_failed (edge);
    1152              : 
    1153     44352906 :   edge->next_caller = callee->callers;
    1154     44352906 :   if (callee->callers)
    1155     34589113 :     callee->callers->prev_caller = edge;
    1156     44352906 :   edge->next_callee = callees;
    1157     44352906 :   if (callees)
    1158     34373702 :     callees->prev_callee = edge;
    1159     44352906 :   callees = edge;
    1160     44352906 :   callee->callers = edge;
    1161              : 
    1162     44352906 :   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       832881 : cgraph_node::create_indirect_edge (gcall *call_stmt, int ecf_flags,
    1173              :                                    profile_count count, bool cloning_p)
    1174              : {
    1175       832881 :   cgraph_edge *edge = symtab->create_edge (this, NULL, call_stmt, count, true,
    1176              :                                            cloning_p);
    1177              : 
    1178       832881 :   if (!cloning_p)
    1179              :     {
    1180       665957 :       initialize_inline_failed (edge);
    1181              : 
    1182       665957 :       tree target = NULL_TREE;
    1183       665957 :       if (call_stmt)
    1184       665957 :         target = gimple_call_fn (call_stmt);
    1185       665957 :       if (target && virtual_method_call_p (target))
    1186              :         {
    1187        93527 :           ipa_polymorphic_call_context context (decl, target, call_stmt);
    1188        93527 :           HOST_WIDE_INT token = tree_to_shwi (OBJ_TYPE_REF_TOKEN (target));
    1189        93527 :           tree type = obj_type_ref_class (target);
    1190        93527 :           edge->indirect_info
    1191        93527 :             = (new (ggc_alloc<cgraph_polymorphic_indirect_info> ())
    1192              :                cgraph_polymorphic_indirect_info (ecf_flags, context, token,
    1193        93527 :                                                  type));
    1194              :         }
    1195       572430 :       else if (target && TREE_CODE (target) == SSA_NAME)
    1196       565527 :         edge->indirect_info
    1197       565527 :           = (new (ggc_alloc<cgraph_simple_indirect_info> ())
    1198       565527 :              cgraph_simple_indirect_info (ecf_flags));
    1199              :       else
    1200         6903 :         edge->indirect_info
    1201         6903 :           = (new (ggc_alloc<cgraph_indirect_call_info> ())
    1202         6903 :              cgraph_indirect_call_info(CIIK_UNSPECIFIED, ecf_flags));
    1203              :     }
    1204              : 
    1205       832881 :   edge->next_callee = indirect_calls;
    1206       832881 :   if (indirect_calls)
    1207       403217 :     indirect_calls->prev_callee = edge;
    1208       832881 :   indirect_calls = edge;
    1209              : 
    1210       832881 :   return edge;
    1211              : }
    1212              : 
    1213              : /* Remove the edge from the list of the callees of the caller.  */
    1214              : 
    1215              : void
    1216      4550662 : cgraph_edge::remove_caller (void)
    1217              : {
    1218      4550662 :   if (prev_callee)
    1219      3744685 :     prev_callee->next_callee = next_callee;
    1220      4550662 :   if (next_callee)
    1221      3135066 :     next_callee->prev_callee = prev_callee;
    1222      4550662 :   if (!prev_callee)
    1223              :     {
    1224       805977 :       if (indirect_unknown_callee)
    1225         1213 :         caller->indirect_calls = next_callee;
    1226              :       else
    1227       804764 :         caller->callees = next_callee;
    1228              :     }
    1229      4550662 :   if (caller->call_site_hash
    1230      4550662 :       && this == caller->get_edge (call_stmt))
    1231       659510 :     caller->call_site_hash->remove_elt_with_hash
    1232       659510 :         (call_stmt, cgraph_edge_hasher::hash (call_stmt));
    1233      4550662 : }
    1234              : 
    1235              : /* Put the edge onto the free list.  */
    1236              : 
    1237              : void
    1238     44751958 : symbol_table::free_edge (cgraph_edge *e)
    1239              : {
    1240     44751958 :   edges_count--;
    1241     44751958 :   if (e->m_summary_id != -1)
    1242     21071476 :     edge_released_summary_ids.safe_push (e->m_summary_id);
    1243              : 
    1244     44751958 :   if (e->indirect_info)
    1245       825378 :     ggc_free (e->indirect_info);
    1246     44751958 :   ggc_free (e);
    1247     44751958 : }
    1248              : 
    1249              : /* Remove the edge in the cgraph.  */
    1250              : 
    1251              : void
    1252       115091 : cgraph_edge::remove (cgraph_edge *edge)
    1253              : {
    1254              :   /* Call all edge removal hooks.  */
    1255       115091 :   symtab->call_edge_removal_hooks (edge);
    1256              : 
    1257       115091 :   if (!edge->indirect_unknown_callee)
    1258              :     /* Remove from callers list of the callee.  */
    1259       112491 :     edge->remove_callee ();
    1260              : 
    1261              :   /* Remove from callees list of the callers.  */
    1262       115091 :   edge->remove_caller ();
    1263              : 
    1264              :   /* Put the edge onto the free list.  */
    1265       115091 :   symtab->free_edge (edge);
    1266       115091 : }
    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        16756 : cgraph_edge::get_next_speculative_id ()
    1274              : {
    1275        16756 :   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        16756 :   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        14953 : cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count,
    1318              :                                unsigned int speculative_id)
    1319              : {
    1320        14953 :   cgraph_node *n = caller;
    1321        14953 :   ipa_ref *ref = NULL;
    1322        14953 :   cgraph_edge *e2;
    1323              : 
    1324        14953 :   if (dump_file)
    1325           29 :     fprintf (dump_file, "Indirect call -> speculative call %s => %s\n",
    1326              :              n->dump_name (), n2->dump_name ());
    1327        14953 :   speculative = true;
    1328        14953 :   e2 = n->create_edge (n2, call_stmt, direct_count);
    1329        14953 :   initialize_inline_failed (e2);
    1330        14953 :   e2->speculative = true;
    1331        14953 :   if (TREE_NOTHROW (n2->decl))
    1332         9804 :     e2->can_throw_external = false;
    1333              :   else
    1334         5149 :     e2->can_throw_external = can_throw_external;
    1335        14953 :   e2->lto_stmt_uid = lto_stmt_uid;
    1336        14953 :   e2->speculative_id = speculative_id;
    1337        14953 :   e2->in_polymorphic_cdtor = in_polymorphic_cdtor;
    1338        14953 :   indirect_info->num_speculative_call_targets++;
    1339        14953 :   count -= e2->count;
    1340        14953 :   symtab->call_edge_duplication_hooks (this, e2);
    1341        14953 :   ref = n->create_reference (n2, IPA_REF_ADDR, call_stmt);
    1342        14953 :   ref->lto_stmt_uid = lto_stmt_uid;
    1343        14953 :   ref->speculative_id = speculative_id;
    1344        14953 :   ref->speculative = speculative;
    1345        14953 :   n2->mark_address_taken ();
    1346        14953 :   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        15083 : cgraph_edge::make_callback (cgraph_node *n2, unsigned int callback_id)
    1366              : {
    1367        15083 :   cgraph_node *n = caller;
    1368        15083 :   cgraph_edge *e2;
    1369              : 
    1370        15083 :   has_callback = true;
    1371        15083 :   e2 = n->create_edge (n2, call_stmt, count);
    1372        15083 :   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        15083 :   e2->inline_failed = CIF_CALLBACK_EDGE;
    1379        15083 :   e2->callback = true;
    1380        15083 :   e2->callback_id = callback_id;
    1381        15083 :   if (TREE_NOTHROW (n2->decl))
    1382        14832 :     e2->can_throw_external = false;
    1383              :   else
    1384          251 :     e2->can_throw_external = can_throw_external;
    1385        15083 :   e2->lto_stmt_uid = lto_stmt_uid;
    1386        15083 :   n2->mark_address_taken ();
    1387        15083 :   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        83173 : cgraph_edge::get_callback_carrying_edge ()
    1398              : {
    1399        83173 :   gcc_checking_assert (callback);
    1400        83173 :   cgraph_edge *e;
    1401       655217 :   for (e = caller->callees; e; e = e->next_callee)
    1402              :     {
    1403       655010 :       if (e->has_callback && e->call_stmt == call_stmt
    1404        82966 :           && e->lto_stmt_uid == lto_stmt_uid)
    1405              :         break;
    1406              :     }
    1407        83173 :   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        48157 : cgraph_edge::first_callback_edge ()
    1416              : {
    1417        48157 :   gcc_checking_assert (has_callback || callback);
    1418        48157 :   cgraph_edge *e = NULL;
    1419       222851 :   for (e = caller->callees; e; e = e->next_callee)
    1420              :     {
    1421       206031 :       if (e->callback && e->call_stmt == call_stmt
    1422        31337 :           && e->lto_stmt_uid == lto_stmt_uid)
    1423              :         break;
    1424              :     }
    1425        48157 :   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        31337 : cgraph_edge::next_callback_edge ()
    1434              : {
    1435        31337 :   gcc_checking_assert (callback);
    1436        31337 :   cgraph_edge *e = NULL;
    1437       321879 :   for (e = next_callee; e; e = e->next_callee)
    1438              :     {
    1439       290542 :       if (e->callback && e->call_stmt == call_stmt
    1440            0 :           && e->lto_stmt_uid == lto_stmt_uid)
    1441              :         break;
    1442              :     }
    1443        31337 :   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        49515 : cgraph_edge::first_speculative_call_target ()
    1470              : {
    1471        49515 :   cgraph_edge *e = this;
    1472              : 
    1473        49515 :   gcc_checking_assert (e->speculative);
    1474        49515 :   if (e->callee)
    1475              :     {
    1476        12991 :       while (e->prev_callee && e->prev_callee->speculative
    1477         1015 :              && e->prev_callee->call_stmt == e->call_stmt
    1478        39879 :              && 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         9636 :   if (e->call_stmt)
    1485         9600 :     return e->caller->get_edge (e->call_stmt);
    1486           49 :   for (cgraph_edge *e2 = e->caller->callees; true; e2 = e2->next_callee)
    1487           49 :     if (e2->speculative
    1488           42 :         && e->call_stmt == e2->call_stmt
    1489           42 :         && 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        38837 : update_call_stmt_hash_for_removing_direct_edge (cgraph_edge *e,
    1500              :                                                 cgraph_edge *indirect)
    1501              : {
    1502        38837 :   if (e->caller->call_site_hash)
    1503              :     {
    1504         5201 :       if (e->caller->get_edge (e->call_stmt) != e)
    1505              :         ;
    1506         5201 :       else if (!indirect->num_speculative_call_targets_p ())
    1507         4602 :         cgraph_update_edge_in_call_site_hash (indirect);
    1508              :       else
    1509              :         {
    1510          599 :           gcc_checking_assert (e->next_callee && e->next_callee->speculative
    1511              :                                && e->next_callee->call_stmt == e->call_stmt);
    1512          599 :           cgraph_update_edge_in_call_site_hash (e->next_callee);
    1513              :         }
    1514              :     }
    1515        38837 : }
    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         5556 : cgraph_edge::resolve_speculation (cgraph_edge *edge, tree callee_decl)
    1534              : {
    1535         5556 :   cgraph_edge *e2;
    1536         5556 :   ipa_ref *ref;
    1537              : 
    1538         5556 :   gcc_assert (edge->speculative && (!callee_decl || edge->callee));
    1539         5556 :   if (!edge->callee)
    1540            0 :     e2 = edge->first_speculative_call_target ();
    1541              :   else
    1542              :     e2 = edge;
    1543         5556 :   ref = e2->speculative_call_target_ref ();
    1544         5556 :   edge = edge->speculative_call_indirect_edge ();
    1545         5556 :   symtab_node *callee;
    1546         5556 :   if (!callee_decl
    1547         1133 :       || !(callee = symtab_node::get (callee_decl))
    1548         6689 :       || !ref->referred->semantically_equivalent_p (callee))
    1549              :     {
    1550         4737 :       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          819 :       cgraph_edge *tmp = edge;
    1572          819 :       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         5556 :   edge->count += e2->count;
    1580         5556 :   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         4737 :       edge->indirect_info->num_speculative_call_targets--;
    1585         4737 :       if (!edge->indirect_info->num_speculative_call_targets)
    1586          963 :         edge->speculative = false;
    1587              :     }
    1588              :   else
    1589          819 :     edge->speculative = false;
    1590         5556 :   e2->speculative = false;
    1591         5556 :   update_call_stmt_hash_for_removing_direct_edge (e2, edge);
    1592         5556 :   ref->remove_reference ();
    1593         5556 :   if (e2->indirect_unknown_callee || e2->inline_failed)
    1594         5079 :     remove (e2);
    1595              :   else
    1596          477 :     e2->callee->remove_symbol_and_inline_clones ();
    1597         5556 :   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         4779 : cgraph_edge::make_direct (cgraph_edge *edge, cgraph_node *callee)
    1622              : {
    1623         4779 :   gcc_assert (edge->indirect_unknown_callee || edge->speculative);
    1624              : 
    1625              :   /* If we are redirecting speculative call, make it non-speculative.  */
    1626         4779 :   if (edge->speculative)
    1627              :     {
    1628          958 :       cgraph_edge *found = NULL;
    1629          958 :       cgraph_edge *direct, *next;
    1630              : 
    1631          958 :       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          958 :       for (direct = edge->first_speculative_call_target ();
    1636         2300 :            direct;
    1637              :            direct = next)
    1638              :         {
    1639         1342 :           next = direct->next_speculative_call_target ();
    1640              : 
    1641              :           /* Compare ref not direct->callee.  Direct edge is possibly
    1642              :              inlined or redirected.  */
    1643         1342 :           if (!direct->speculative_call_target_ref ()
    1644         1342 :                ->referred->semantically_equivalent_p (callee)
    1645         1342 :               || found)
    1646          523 :             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          958 :       if (found)
    1656              :         {
    1657          819 :           cgraph_edge *e2 = resolve_speculation (found, callee->decl);
    1658          819 :           gcc_checking_assert (!found->speculative && e2 == found);
    1659              :           return found;
    1660              :         }
    1661          139 :       gcc_checking_assert (!edge->speculative);
    1662              :     }
    1663              : 
    1664         3960 :   edge->indirect_unknown_callee = 0;
    1665         3960 :   ggc_free (edge->indirect_info);
    1666         3960 :   edge->indirect_info = NULL;
    1667              : 
    1668              :   /* Get the edge out of the indirect edge list. */
    1669         3960 :   if (edge->prev_callee)
    1670          102 :     edge->prev_callee->next_callee = edge->next_callee;
    1671         3960 :   if (edge->next_callee)
    1672          542 :     edge->next_callee->prev_callee = edge->prev_callee;
    1673         3960 :   if (!edge->prev_callee)
    1674         3858 :     edge->caller->indirect_calls = edge->next_callee;
    1675              : 
    1676              :   /* Put it into the normal callee list */
    1677         3960 :   edge->prev_callee = NULL;
    1678         3960 :   edge->next_callee = edge->caller->callees;
    1679         3960 :   if (edge->caller->callees)
    1680         2581 :     edge->caller->callees->prev_callee = edge;
    1681         3960 :   edge->caller->callees = edge;
    1682              : 
    1683              :   /* Insert to callers list of the new callee.  */
    1684         3960 :   edge->set_callee (callee);
    1685              : 
    1686              :   /* We need to re-determine the inlining status of the edge.  */
    1687         3960 :   initialize_inline_failed (edge);
    1688         3960 :   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      4416620 : cgraph_edge::redirect_callee (cgraph_node *n)
    1696              : {
    1697      4416620 :   bool loc = callee->comdat_local_p ();
    1698      4416620 :   cgraph_node *old_callee = callee;
    1699              : 
    1700              :   /* Remove from callers list of the current callee.  */
    1701      4416620 :   remove_callee ();
    1702              : 
    1703              :   /* Insert to callers list of the new callee.  */
    1704      4416620 :   set_callee (n);
    1705              : 
    1706      4416620 :   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      4416620 :   if (!inline_failed)
    1724              :     return;
    1725       721075 :   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       721019 :   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      9911656 : cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e,
    1759              :                                            hash_set <tree> *killed_ssas)
    1760              : {
    1761      9911656 :   tree decl = gimple_call_fndecl (e->call_stmt);
    1762      9911656 :   gcall *new_stmt;
    1763              : 
    1764      9911656 :   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        33281 :       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        33281 :           gcc_checking_assert (e->callee);
    1776        33281 :           cgraph_edge *indirect = e->speculative_call_indirect_edge ();
    1777        33281 :           gcall *new_stmt;
    1778        33281 :           ipa_ref *ref;
    1779              : 
    1780              :           /* Expand speculation into GIMPLE code.  */
    1781        33281 :           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        33281 :           push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
    1791              : 
    1792        33281 :           profile_count all = indirect->count;
    1793        33281 :           for (cgraph_edge *e2 = e->first_speculative_call_target ();
    1794        74936 :                e2;
    1795        41655 :                e2 = e2->next_speculative_call_target ())
    1796        41655 :             all = all + e2->count;
    1797        33281 :           profile_probability prob = e->count.probability_in (all);
    1798        33281 :           if (!prob.initialized_p ())
    1799          170 :             prob = profile_probability::even ();
    1800        33281 :           ref = e->speculative_call_target_ref ();
    1801        66562 :           new_stmt = gimple_ic (e->call_stmt,
    1802              :                                 dyn_cast<cgraph_node *> (ref->referred),
    1803              :                                 prob);
    1804        33281 :           e->speculative = false;
    1805        33281 :           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        33281 :               indirect->indirect_info->num_speculative_call_targets--;
    1811        33281 :               if (!indirect->indirect_info->num_speculative_call_targets)
    1812        26350 :                 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        33281 :           update_call_stmt_hash_for_removing_direct_edge (e, indirect);
    1819        33281 :           cgraph_edge::set_call_stmt (e, new_stmt, false);
    1820        33281 :           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        33281 :           if (!indirect->speculative)
    1826        26350 :             indirect->count = gimple_bb (indirect->call_stmt)->count;
    1827        33281 :           ref->speculative = false;
    1828        33281 :           ref->stmt = NULL;
    1829        33281 :           pop_cfun ();
    1830              :           /* Continue redirecting E to proper target.  */
    1831              :         }
    1832              :     }
    1833              : 
    1834              : 
    1835      9911656 :   if (e->indirect_unknown_callee
    1836      9829018 :       || decl == e->callee->decl)
    1837      8818624 :     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      1093032 :   if (e->callback)
    1843              :     {
    1844         3437 :       cgraph_edge *carrying = e->get_callback_carrying_edge ();
    1845         3437 :       if (!callback_is_special_cased (carrying->callee->decl, e->call_stmt)
    1846         6102 :           && !lookup_attribute (CALLBACK_ATTR_IDENT,
    1847         2665 :                                 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         3437 :       int fn_idx = callback_fetch_fn_position (e, carrying);
    1853         3437 :       tree previous_arg = gimple_call_arg (e->call_stmt, fn_idx);
    1854         3437 :       location_t loc = EXPR_LOCATION (previous_arg);
    1855         3437 :       tree new_addr = build_fold_addr_expr_loc (loc, e->callee->decl);
    1856         3437 :       gimple_call_set_arg (e->call_stmt, fn_idx, new_addr);
    1857         3437 :       return e->call_stmt;
    1858              :     }
    1859              : 
    1860      1089595 :   if (decl && ipa_saved_clone_sources)
    1861              :     {
    1862       876076 :       tree *p = ipa_saved_clone_sources->get (e->callee);
    1863       876076 :       if (p && decl == *p)
    1864              :         {
    1865        31902 :           gimple_call_set_fndecl (e->call_stmt, e->callee->decl);
    1866        31902 :           return e->call_stmt;
    1867              :         }
    1868              :     }
    1869      1057693 :   if (flag_checking && decl)
    1870              :     {
    1871      1020864 :       if (cgraph_node *node = cgraph_node::get (decl))
    1872              :         {
    1873       883854 :           clone_info *info = clone_info::get (node);
    1874       883854 :           gcc_assert (!info || !info->param_adjustments);
    1875              :         }
    1876              :     }
    1877              : 
    1878      1057693 :   clone_info *callee_info = clone_info::get (e->callee);
    1879      1057693 :   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       604671 :   if (ipa_param_adjustments *padjs
    1889      1057693 :          = 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       597419 :       int lp_nr = lookup_stmt_eh_lp (e->call_stmt);
    1896       597419 :       if (lp_nr != 0)
    1897       141652 :         remove_stmt_from_eh_lp (e->call_stmt);
    1898              : 
    1899       597419 :       tree old_fntype = gimple_call_fntype (e->call_stmt);
    1900       597419 :       new_stmt = padjs->modify_call (e, false, killed_ssas);
    1901       597419 :       cgraph_node *origin = e->callee;
    1902       866798 :       while (origin->clone_of)
    1903              :         origin = origin->clone_of;
    1904              : 
    1905       597419 :       if ((origin->former_clone_of
    1906       476211 :            && old_fntype == TREE_TYPE (origin->former_clone_of))
    1907       600813 :           || old_fntype == TREE_TYPE (origin->decl))
    1908       472819 :         gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
    1909              :       else
    1910              :         {
    1911       124600 :           tree new_fntype = padjs->build_new_function_type (old_fntype, true);
    1912       124600 :           gimple_call_set_fntype (new_stmt, new_fntype);
    1913              :         }
    1914              : 
    1915       597419 :       if (lp_nr != 0)
    1916       141652 :         add_stmt_to_eh_lp (new_stmt, lp_nr);
    1917              :     }
    1918              :   else
    1919              :     {
    1920       460274 :       if (flag_checking
    1921       460274 :           && !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    1922              :                                                   BUILT_IN_UNREACHABLE_TRAP))
    1923       292669 :         ipa_verify_edge_has_no_modifications (e);
    1924       460274 :       new_stmt = e->call_stmt;
    1925       460274 :       gimple_call_set_fndecl (new_stmt, e->callee->decl);
    1926       460274 :       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      1057693 :   if (gimple_call_noreturn_p (new_stmt)
    1932       170892 :       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (e->callee->decl)))
    1933       170821 :       && TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl))
    1934      1228507 :       && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl)))
    1935       170814 :           == void_type_node))
    1936       170085 :     gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
    1937              : 
    1938              :   /* If the call becomes noreturn, remove the LHS if possible.  */
    1939      1057693 :   tree lhs = gimple_call_lhs (new_stmt);
    1940      1057693 :   if (lhs
    1941       290118 :       && gimple_call_noreturn_p (new_stmt)
    1942      1089127 :       && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (new_stmt)))
    1943           58 :           || should_remove_lhs_p (lhs)))
    1944              :     {
    1945        31395 :       gimple_call_set_lhs (new_stmt, NULL_TREE);
    1946              :       /* We need to fix up the SSA name to avoid checking errors.  */
    1947        31395 :       if (TREE_CODE (lhs) == SSA_NAME)
    1948              :         {
    1949        27117 :           tree var = create_tmp_reg_fn (DECL_STRUCT_FUNCTION (e->caller->decl),
    1950        27117 :                                         TREE_TYPE (lhs), NULL);
    1951        27117 :           SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
    1952        27117 :           SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
    1953        27117 :           set_ssa_default_def (DECL_STRUCT_FUNCTION (e->caller->decl),
    1954              :                                var, lhs);
    1955              :         }
    1956        31395 :       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
    1957              :     }
    1958              : 
    1959              :   /* If new callee has no static chain, remove it.  */
    1960      1057693 :   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      1057693 :   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      1057693 :   e->caller->set_call_stmt_including_clones (e->call_stmt, new_stmt, e->has_callback);
    1972              : 
    1973      1057693 :   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       119718 : cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
    1989              :                                         gimple *old_stmt, tree old_call,
    1990              :                                         gimple *new_stmt)
    1991              : {
    1992       119718 :   tree new_call = (new_stmt && is_gimple_call (new_stmt))
    1993       124695 :                   ? gimple_call_fndecl (new_stmt) : 0;
    1994              : 
    1995              :   /* We are seeing indirect calls, then there is nothing to update.  */
    1996       119718 :   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       118251 :   if (old_call != new_call)
    2001              :     {
    2002       116880 :       cgraph_edge *e = node->get_edge (old_stmt);
    2003       116880 :       cgraph_edge *ne = NULL;
    2004       116880 :       profile_count count;
    2005              : 
    2006       116880 :       if (e)
    2007              :         {
    2008              :           /* If call was devirtualized during cloning, mark edge
    2009              :              as resolved.  */
    2010        95610 :           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        95610 :           if (new_stmt && is_gimple_call (new_stmt) && e->callee
    2024        96194 :               && 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        95607 :           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        95585 :           count = e->count;
    2053        95585 :           if (e->indirect_unknown_callee || e->inline_failed)
    2054        95585 :             cgraph_edge::remove (e);
    2055              :           else
    2056            0 :             e->callee->remove_symbol_and_inline_clones ();
    2057              :         }
    2058        21270 :       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        95589 :       if (new_call)
    2066              :         {
    2067         2328 :           ne = node->create_edge (cgraph_node::get_create (new_call),
    2068              :                                   as_a <gcall *> (new_stmt), count);
    2069         2328 :           gcc_assert (ne->inline_failed);
    2070              :         }
    2071              :     }
    2072              :   /* We only updated the call stmt; update pointer in cgraph edge..  */
    2073         1371 :   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        98054 : cgraph_update_edges_for_call_stmt (gimple *old_stmt, tree old_decl,
    2084              :                                    gimple *new_stmt)
    2085              : {
    2086        98054 :   cgraph_node *orig = cgraph_node::get (cfun->decl);
    2087        98054 :   cgraph_node *node;
    2088              : 
    2089        98054 :   gcc_checking_assert (orig);
    2090        98054 :   gcc_assert (!orig->thunk);
    2091        98054 :   cgraph_update_edges_for_call_stmt_node (orig, old_stmt, old_decl, new_stmt);
    2092        98054 :   if (orig->clones)
    2093        42679 :     for (node = orig->clones; node != orig;)
    2094              :       {
    2095              :         /* Do not attempt to adjust bodies of yet unexpanded thunks.  */
    2096        21666 :         if (!node->thunk)
    2097        21664 :           cgraph_update_edges_for_call_stmt_node (node, old_stmt, old_decl,
    2098              :                                                   new_stmt);
    2099        21666 :         if (node->clones)
    2100              :           node = node->clones;
    2101        21653 :         else if (node->next_sibling_clone)
    2102              :           node = node->next_sibling_clone;
    2103              :         else
    2104              :           {
    2105        42039 :             while (node != orig && !node->next_sibling_clone)
    2106        21026 :               node = node->clone_of;
    2107        21013 :             if (node != orig)
    2108            0 :               node = node->next_sibling_clone;
    2109              :           }
    2110              :       }
    2111        98054 : }
    2112              : 
    2113              : 
    2114              : /* Remove all callees from the node.  */
    2115              : 
    2116              : void
    2117    231039146 : cgraph_node::remove_callees (void)
    2118              : {
    2119    231039146 :   cgraph_edge *e, *f;
    2120              : 
    2121    231039146 :   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    270417664 :   for (e = callees; e; e = f)
    2127              :     {
    2128     39378518 :       f = e->next_callee;
    2129     39378518 :       symtab->call_edge_removal_hooks (e);
    2130     39378518 :       if (!e->indirect_unknown_callee)
    2131     39378518 :         e->remove_callee ();
    2132     39378518 :       symtab->free_edge (e);
    2133              :     }
    2134    231861924 :   for (e = indirect_calls; e; e = f)
    2135              :     {
    2136       822778 :       f = e->next_callee;
    2137       822778 :       symtab->call_edge_removal_hooks (e);
    2138       822778 :       if (!e->indirect_unknown_callee)
    2139            0 :         e->remove_callee ();
    2140       822778 :       symtab->free_edge (e);
    2141              :     }
    2142    231039146 :   indirect_calls = NULL;
    2143    231039146 :   callees = NULL;
    2144    231039146 :   if (call_site_hash)
    2145              :     {
    2146        31192 :       call_site_hash->empty ();
    2147        31192 :       call_site_hash = NULL;
    2148              :     }
    2149    231039146 : }
    2150              : 
    2151              : /* Remove all callers from the node.  */
    2152              : 
    2153              : void
    2154    104189375 : cgraph_node::remove_callers (void)
    2155              : {
    2156    104189375 :   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    108624946 :   for (e = callers; e; e = f)
    2162              :     {
    2163      4435571 :       f = e->next_caller;
    2164              :       /* When removing a callback-carrying edge, remove all its attached edges
    2165              :          as well.  */
    2166      4435571 :       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      4435571 :       symtab->call_edge_removal_hooks (e);
    2176      4435571 :       e->remove_caller ();
    2177      4435571 :       symtab->free_edge (e);
    2178              :     }
    2179    104189375 :   callers = NULL;
    2180    104189375 : }
    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    114396654 : release_function_body (tree decl)
    2188              : {
    2189    114396654 :   function *fn = DECL_STRUCT_FUNCTION (decl);
    2190    114396654 :   if (fn)
    2191              :     {
    2192    102742884 :       if (fn->cfg
    2193    102742884 :           && loops_for_fn (fn))
    2194              :         {
    2195      1698676 :           fn->curr_properties &= ~PROP_loops;
    2196      1698676 :           loop_optimizer_finalize (fn);
    2197              :         }
    2198    102742884 :       if (fn->gimple_df)
    2199              :         {
    2200      1707324 :           delete_tree_ssa (fn);
    2201      1707324 :           fn->eh = NULL;
    2202              :         }
    2203    102742884 :       if (fn->cfg)
    2204              :         {
    2205      1698677 :           gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
    2206      1698677 :           gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
    2207      1698677 :           delete_tree_cfg_annotations (fn);
    2208      1698677 :           free_cfg (fn);
    2209      1698677 :           fn->cfg = NULL;
    2210              :         }
    2211    102742884 :       if (fn->value_histograms)
    2212           12 :         free_histograms (fn);
    2213    102742884 :       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    102742884 :       ggc_free (fn);
    2217    102742884 :       DECL_STRUCT_FUNCTION (decl) = NULL;
    2218              :     }
    2219    114396654 :   DECL_SAVED_TREE (decl) = NULL;
    2220    114396654 : }
    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    114384890 : cgraph_node::release_body (bool keep_arguments)
    2230              : {
    2231    114384890 :   ipa_transforms_to_apply.release ();
    2232    114384890 :   if (!used_as_abstract_origin && symtab->state != PARSING)
    2233              :     {
    2234    113814105 :       DECL_RESULT (decl) = NULL;
    2235              : 
    2236    113814105 :       if (!keep_arguments)
    2237    113783527 :         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    114384890 :   if (!used_as_abstract_origin && DECL_INITIAL (decl))
    2243    102229217 :     DECL_INITIAL (decl) = error_mark_node;
    2244    114384890 :   release_function_body (decl);
    2245    114384890 :   lto_free_function_in_decl_state_for_node (this);
    2246    114384890 :   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    114384890 :   remove_callees ();
    2256    114384890 :   remove_all_references ();
    2257    114384890 : }
    2258              : 
    2259              : /* Remove function from symbol table.  */
    2260              : 
    2261              : void
    2262    104189375 : cgraph_node::remove (void)
    2263              : {
    2264    104189375 :   bool clone_info_set = false;
    2265    104189375 :   clone_info *info, saved_info;
    2266    104189375 :   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    104189375 :   if ((info = clone_info::get (this)) != NULL)
    2273              :     {
    2274       414638 :       saved_info = *info;
    2275       414638 :       clone_info_set = true;
    2276              :     }
    2277    104189375 :   symtab->call_cgraph_removal_hooks (this);
    2278    104189375 :   remove_callers ();
    2279    104189375 :   remove_callees ();
    2280    104189375 :   ipa_transforms_to_apply.release ();
    2281    104189375 :   delete_function_version (function_version ());
    2282              : 
    2283              :   /* Incremental inlining access removed nodes stored in the postorder list.
    2284              :      */
    2285    104189375 :   force_output = false;
    2286    104189375 :   forced_by_abi = false;
    2287              : 
    2288    207964112 :   unregister (clone_info_set ? &saved_info : NULL);
    2289    104189375 :   if (prev_sibling_clone)
    2290       764281 :     prev_sibling_clone->next_sibling_clone = next_sibling_clone;
    2291    103425094 :   else if (clone_of)
    2292              :     {
    2293      1769650 :       clone_of->clones = next_sibling_clone;
    2294      1769650 :       if (!clones)
    2295              :         {
    2296      1766735 :           bool need_body = false;
    2297      1766735 :           for (cgraph_node *n = clone_of; n; n = n->clone_of)
    2298      1761119 :             if (n->analyzed || n->clones)
    2299              :               {
    2300              :                 need_body = true;
    2301              :                 break;
    2302              :               }
    2303      1761115 :           if (!need_body)
    2304         5616 :             clone_of->release_body ();
    2305              :         }
    2306              :     }
    2307    104189375 :   if (next_sibling_clone)
    2308       978602 :     next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
    2309    104189375 :   if (clones)
    2310              :     {
    2311        38808 :       cgraph_node *n, *next;
    2312              : 
    2313        38808 :       if (clone_of)
    2314              :         {
    2315       180476 :           for (n = clones; n->next_sibling_clone; n = n->next_sibling_clone)
    2316       141668 :             n->clone_of = clone_of;
    2317        38808 :           n->clone_of = clone_of;
    2318        38808 :           n->next_sibling_clone = clone_of->clones;
    2319        38808 :           if (clone_of->clones)
    2320        33801 :             clone_of->clones->prev_sibling_clone = n;
    2321        38808 :           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    104189375 :   if (symtab->state != LTO_STREAMING)
    2345              :     {
    2346    104187303 :       cgraph_node *n = cgraph_node::get (decl);
    2347    104187303 :       if (!n
    2348    104187303 :           || (!n->clones && !n->clone_of && !n->inlined_to
    2349      1097679 :               && ((symtab->global_info_ready || in_lto_p)
    2350        10361 :                   && (TREE_ASM_WRITTEN (n->decl)
    2351        10339 :                       || DECL_EXTERNAL (n->decl)
    2352         5413 :                       || !n->analyzed
    2353         5195 :                       || (!flag_wpa && n->in_other_partition)))))
    2354    101254218 :         release_body ();
    2355              :     }
    2356              :   else
    2357         2072 :     lto_free_function_in_decl_state_for_node (this);
    2358              : 
    2359    104189375 :   decl = NULL;
    2360    104189375 :   if (call_site_hash)
    2361              :     {
    2362            0 :       call_site_hash->empty ();
    2363            0 :       call_site_hash = NULL;
    2364              :     }
    2365              : 
    2366    104189375 :   symtab->release_symbol (this);
    2367    104189375 : }
    2368              : 
    2369              : /* Likewise indicate that a node is having address taken.  */
    2370              : 
    2371              : void
    2372      4657196 : cgraph_node::mark_address_taken (void)
    2373              : {
    2374              :   /* Indirect inlining can figure out that all uses of the address are
    2375              :      inlined.  */
    2376      4657196 :   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      4657196 :   address_taken = 1;
    2389      4657196 :   cgraph_node *node = ultimate_alias_target ();
    2390      4657196 :   node->address_taken = 1;
    2391              : }
    2392              : 
    2393              : /* Return local info node for the compiled function.  */
    2394              : 
    2395              : cgraph_node *
    2396     12601047 : cgraph_node::local_info_node (tree decl)
    2397              : {
    2398     12601047 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
    2399     12601047 :   cgraph_node *node = get (decl);
    2400     12601047 :   if (!node)
    2401              :     return NULL;
    2402     12601047 :   return node->ultimate_alias_target ();
    2403              : }
    2404              : 
    2405              : /* Return RTL info for the compiled function.  */
    2406              : 
    2407              : cgraph_rtl_info *
    2408     60189141 : cgraph_node::rtl_info (const_tree decl)
    2409              : {
    2410     60189141 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
    2411     60189141 :   cgraph_node *node = get (decl);
    2412     60189141 :   if (!node)
    2413              :     return NULL;
    2414     60046079 :   enum availability avail;
    2415     60046079 :   node = node->ultimate_alias_target (&avail);
    2416     60046079 :   if (decl != current_function_decl
    2417     57020278 :       && (avail < AVAIL_AVAILABLE
    2418     51817219 :           || (node->decl != current_function_decl
    2419     51743542 :               && !TREE_ASM_WRITTEN (node->decl))))
    2420              :     return NULL;
    2421              :   /* Allocate if it doesn't exist.  */
    2422     51312432 :   if (node->rtl == NULL)
    2423              :     {
    2424      1352320 :       node->rtl = ggc_cleared_alloc<cgraph_rtl_info> ();
    2425      1352320 :       SET_HARD_REG_SET (node->rtl->function_used_regs);
    2426              :     }
    2427     51312432 :   return node->rtl;
    2428              : }
    2429              : 
    2430              : /* Return a string describing the failure REASON.  */
    2431              : 
    2432              : const char*
    2433         9866 : cgraph_inline_failed_string (cgraph_inline_failed_t reason)
    2434              : {
    2435              : #undef DEFCIFCODE
    2436              : #define DEFCIFCODE(code, type, string)  string,
    2437              : 
    2438         9866 :   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         9866 :   gcc_assert ((unsigned) reason < CIF_N_REASONS);
    2445         9866 :   return cif_string_table[reason];
    2446              : }
    2447              : 
    2448              : /* Return a type describing the failure REASON.  */
    2449              : 
    2450              : cgraph_inline_failed_type_t
    2451     72382154 : cgraph_inline_failed_type (cgraph_inline_failed_t reason)
    2452              : {
    2453              : #undef DEFCIFCODE
    2454              : #define DEFCIFCODE(code, type, string)  type,
    2455              : 
    2456     72382154 :   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     72382154 :   gcc_assert ((unsigned) reason < CIF_N_REASONS);
    2463     72382154 :   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     97044914 : cgraph_function_possibly_inlined_p (tree decl)
    2782              : {
    2783     97044914 :   if (!symtab->global_info_ready)
    2784     89563868 :     return !DECL_UNINLINABLE (decl);
    2785      7481046 :   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    815549727 : cgraph_node::get_availability (symtab_node *ref)
    2792              : {
    2793    815549727 :   if (ref)
    2794              :     {
    2795    570745833 :       cgraph_node *cref = dyn_cast <cgraph_node *> (ref);
    2796    570745833 :       if (cref)
    2797    570745833 :         ref = cref->inlined_to;
    2798              :     }
    2799    815549727 :   enum availability avail;
    2800    815549727 :   if (!analyzed && !in_other_partition)
    2801    488102188 :     avail = AVAIL_NOT_AVAILABLE;
    2802    327447539 :   else if (local)
    2803     96327005 :     avail = AVAIL_LOCAL;
    2804    231120534 :   else if (inlined_to)
    2805      2055689 :     avail = AVAIL_AVAILABLE;
    2806    229064845 :   else if (transparent_alias)
    2807          134 :     ultimate_alias_target (&avail, ref);
    2808    229064711 :   else if (ifunc_resolver
    2809    229064711 :            || lookup_attribute ("noipa", DECL_ATTRIBUTES (decl)))
    2810      3533647 :     avail = AVAIL_INTERPOSABLE;
    2811    225531064 :   else if (!externally_visible)
    2812     32284184 :     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        19930 :   else if ((this == ref && !has_aliases_p ())
    2819    193247652 :            || (ref && get_comdat_group ()
    2820      1066793 :                && get_comdat_group () == ref->get_comdat_group ()))
    2821        22673 :     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    193224207 :   else if (DECL_DECLARED_INLINE_P (decl))
    2826     66166760 :     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    127057447 :   else if (decl_replaceable_p (decl, semantic_interposition)
    2835    127057447 :            && !DECL_EXTERNAL (decl))
    2836      9289444 :     avail = AVAIL_INTERPOSABLE;
    2837    117768003 :   else avail = AVAIL_AVAILABLE;
    2838              : 
    2839    815549727 :   return avail;
    2840              : }
    2841              : 
    2842              : /* Worker for cgraph_node_can_be_local_p.  */
    2843              : static bool
    2844       925584 : cgraph_node_cannot_be_local_p_1 (cgraph_node *node, void *)
    2845              : {
    2846       925584 :   return !(!node->force_output
    2847       904797 :            && !node->ref_by_asm
    2848       904793 :            && !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       904753 :            && !node->symver
    2852       904753 :            && ((DECL_COMDAT (node->decl)
    2853       449035 :                 && !node->forced_by_abi
    2854       430544 :                 && !node->used_from_object_file_p ()
    2855       430544 :                 && !node->same_comdat_group)
    2856       539435 :                || !node->externally_visible)
    2857       517215 :            && !DECL_STATIC_CONSTRUCTOR (node->decl)
    2858       515407 :            && !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      1216020 : cgraph_node::can_be_local_p (void)
    2867              : {
    2868      1216020 :   return (!address_taken
    2869      1216020 :           && !call_for_symbol_thunks_and_aliases (cgraph_node_cannot_be_local_p_1,
    2870      1216020 :                                                 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    159516815 : 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    159516815 :   cgraph_edge *e;
    2885    159516815 :   ipa_ref *ref;
    2886    159516815 :   enum availability avail = AVAIL_AVAILABLE;
    2887              : 
    2888    159516815 :   if (include_overwritable
    2889    159516815 :       || (avail = get_availability ()) > AVAIL_INTERPOSABLE)
    2890              :     {
    2891    159505971 :       if (callback (this, data))
    2892              :         return true;
    2893              :     }
    2894    169905569 :   FOR_EACH_ALIAS (this, ref)
    2895              :     {
    2896     15667089 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2897     15667089 :       if (include_overwritable
    2898     15667089 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
    2899     15665784 :         if (alias->call_for_symbol_thunks_and_aliases (callback, data,
    2900              :                                                      include_overwritable,
    2901              :                                                      exclude_virtual_thunks))
    2902              :           return true;
    2903              :     }
    2904    154238480 :   if (avail <= AVAIL_INTERPOSABLE)
    2905              :     return false;
    2906    164320838 :   for (e = callers; e; e = e->next_caller)
    2907     10093202 :     if (e->caller->thunk
    2908         5888 :         && (include_overwritable
    2909         3592 :             || e->caller->get_availability () > AVAIL_INTERPOSABLE)
    2910     10099090 :         && !(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       952798 : set_nothrow_flag_1 (cgraph_node *node, bool nothrow, bool non_call,
    2955              :                     bool *changed)
    2956              : {
    2957       952798 :   cgraph_edge *e;
    2958              : 
    2959       952798 :   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       952773 :       if (!non_call || node->binds_to_current_def_p ())
    2964              :         {
    2965       947009 :           TREE_NOTHROW (node->decl) = true;
    2966       947009 :           *changed = true;
    2967      2318166 :           for (e = node->callers; e; e = e->next_caller)
    2968      1371157 :             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      1005886 :   FOR_EACH_ALIAS (node, ref)
    2978              :     {
    2979        53088 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    2980        53088 :       if (!nothrow || alias->get_availability () > AVAIL_INTERPOSABLE)
    2981        52663 :         set_nothrow_flag_1 (alias, nothrow, non_call, changed);
    2982              :     }
    2983      2361413 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    2984      1408615 :     if (e->caller->thunk
    2985      1408615 :         && (!nothrow || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    2986          138 :       set_nothrow_flag_1 (e->caller, nothrow, non_call, changed);
    2987       952798 : }
    2988              : 
    2989              : /* Set TREE_NOTHROW on NODE's decl and on aliases of NODE
    2990              :    if any to NOTHROW.  */
    2991              : 
    2992              : bool
    2993       907314 : cgraph_node::set_nothrow_flag (bool nothrow)
    2994              : {
    2995       907314 :   bool changed = false;
    2996       907314 :   bool non_call = opt_for_fn (decl, flag_non_call_exceptions);
    2997              : 
    2998       907314 :   if (!nothrow || get_availability () > AVAIL_INTERPOSABLE)
    2999       899888 :     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       907314 :   return changed;
    3012              : }
    3013              : 
    3014              : /* Worker to set malloc flag.  */
    3015              : static void
    3016        40689 : set_malloc_flag_1 (cgraph_node *node, bool malloc_p, bool *changed)
    3017              : {
    3018        40689 :   if (malloc_p && !DECL_IS_MALLOC (node->decl))
    3019              :     {
    3020        40145 :       DECL_IS_MALLOC (node->decl) = true;
    3021        40145 :       *changed = true;
    3022              :     }
    3023              : 
    3024              :   ipa_ref *ref;
    3025        40690 :   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        89803 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3033        49114 :     if (e->caller->thunk
    3034        49114 :         && (!malloc_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    3035            0 :       set_malloc_flag_1 (e->caller, malloc_p, changed);
    3036        40689 : }
    3037              : 
    3038              : /* Set DECL_IS_MALLOC on NODE's decl and on NODE's aliases if any.  */
    3039              : 
    3040              : bool
    3041        40688 : cgraph_node::set_malloc_flag (bool malloc_p)
    3042              : {
    3043        40688 :   bool changed = false;
    3044              : 
    3045        40688 :   if (!malloc_p || get_availability () > AVAIL_INTERPOSABLE)
    3046        40688 :     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        40688 :   return changed;
    3059              : }
    3060              : 
    3061              : /* Worker to set malloc flag.  */
    3062              : static void
    3063       255285 : add_detected_attribute_1 (cgraph_node *node, const char *attr, bool *changed)
    3064              : {
    3065       255285 :   if (!lookup_attribute (attr, DECL_ATTRIBUTES (node->decl)))
    3066              :     {
    3067       229143 :       DECL_ATTRIBUTES (node->decl) = tree_cons (get_identifier (attr),
    3068       229143 :                                          NULL_TREE, DECL_ATTRIBUTES (node->decl));
    3069       229143 :       *changed = true;
    3070              :     }
    3071              : 
    3072              :   ipa_ref *ref;
    3073       255831 :   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       792469 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3081       537184 :     if (e->caller->thunk
    3082       537184 :         && (e->caller->get_availability () > AVAIL_INTERPOSABLE))
    3083           14 :       add_detected_attribute_1 (e->caller, attr, changed);
    3084       255285 : }
    3085              : 
    3086              : /* Add attribyte ATTR to function and its aliases.  */
    3087              : 
    3088              : bool
    3089       258912 : cgraph_node::add_detected_attribute (const char *attr)
    3090              : {
    3091       258912 :   bool changed = false;
    3092              : 
    3093       258912 :   if (get_availability () > AVAIL_INTERPOSABLE)
    3094       255140 :     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       258912 :   return changed;
    3107              : }
    3108              : 
    3109              : /* Worker to set noreturng flag.  */
    3110              : static void
    3111        27309 : set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed)
    3112              : {
    3113        27309 :   if (noreturn_p && !TREE_THIS_VOLATILE (node->decl))
    3114              :     {
    3115        27309 :       TREE_THIS_VOLATILE (node->decl) = true;
    3116        27309 :       *changed = true;
    3117              :     }
    3118              : 
    3119              :   ipa_ref *ref;
    3120        27954 :   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        43554 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3128        16245 :     if (e->caller->thunk
    3129        16245 :         && (!noreturn_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
    3130           20 :       set_noreturn_flag_1 (e->caller, noreturn_p, changed);
    3131        27309 : }
    3132              : 
    3133              : /* Set TREE_THIS_VOLATILE on NODE's decl and on NODE's aliases if any.  */
    3134              : 
    3135              : bool
    3136        26652 : cgraph_node::set_noreturn_flag (bool noreturn_p)
    3137              : {
    3138        26652 :   bool changed = false;
    3139              : 
    3140        26652 :   if (!noreturn_p || get_availability () > AVAIL_INTERPOSABLE)
    3141        26635 :     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        26652 :   return changed;
    3154              : }
    3155              : 
    3156              : /* Worker to set_const_flag.  */
    3157              : 
    3158              : static void
    3159       993048 : 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       993048 :   if (set_const && !looping)
    3165              :     {
    3166       987034 :       if (DECL_STATIC_CONSTRUCTOR (node->decl))
    3167              :         {
    3168          290 :           DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
    3169          290 :           *changed = true;
    3170              :         }
    3171       987034 :       if (DECL_STATIC_DESTRUCTOR (node->decl))
    3172              :         {
    3173            1 :           DECL_STATIC_DESTRUCTOR (node->decl) = 0;
    3174            1 :           *changed = true;
    3175              :         }
    3176              :     }
    3177       993048 :   if (!set_const)
    3178              :     {
    3179         2206 :       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       990842 :       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       990101 :       else if (node->binds_to_current_def_p ())
    3214              :         {
    3215       172508 :           TREE_READONLY (node->decl) = true;
    3216       172508 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
    3217       172508 :           DECL_PURE_P (node->decl) = false;
    3218       172508 :           *changed = true;
    3219              :         }
    3220              :       else
    3221              :         {
    3222       817593 :           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       817593 :           if (!DECL_PURE_P (node->decl))
    3226              :             {
    3227       389302 :               DECL_PURE_P (node->decl) = true;
    3228       389302 :               DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
    3229       389302 :               *changed = true;
    3230              :             }
    3231       428291 :           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      1101034 :   FOR_EACH_ALIAS (node, ref)
    3241              :     {
    3242       107986 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    3243       107986 :       if (!set_const || alias->get_availability () > AVAIL_INTERPOSABLE)
    3244       107923 :         set_const_flag_1 (alias, set_const, looping, changed);
    3245              :     }
    3246       993144 :   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      2669400 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    3250      1676352 :     if (e->caller->thunk
    3251      1676352 :         && (!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       993048 : }
    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       909703 : cgraph_node::set_const_flag (bool set_const, bool looping)
    3275              : {
    3276       909703 :   bool changed = false;
    3277       909703 :   if (!set_const || get_availability () > AVAIL_INTERPOSABLE)
    3278       884596 :     set_const_flag_1 (this, set_const, looping, &changed);
    3279              :   else
    3280              :     {
    3281              :       ipa_ref *ref;
    3282              : 
    3283        25986 :       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       909703 :   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       355401 : set_pure_flag_1 (cgraph_node *node, void *data)
    3306              : {
    3307       355401 :   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       355401 :   if (info->pure && !info->looping)
    3311              :     {
    3312       288501 :       if (DECL_STATIC_CONSTRUCTOR (node->decl))
    3313              :         {
    3314            0 :           DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
    3315            0 :           info->changed = true;
    3316              :         }
    3317       288501 :       if (DECL_STATIC_DESTRUCTOR (node->decl))
    3318              :         {
    3319            0 :           DECL_STATIC_DESTRUCTOR (node->decl) = 0;
    3320            0 :           info->changed = true;
    3321              :         }
    3322              :     }
    3323       355401 :   if (info->pure)
    3324              :     {
    3325       353195 :       if (!DECL_PURE_P (node->decl) && !TREE_READONLY (node->decl))
    3326              :         {
    3327       352604 :           DECL_PURE_P (node->decl) = true;
    3328       352604 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = info->looping;
    3329       352604 :           info->changed = true;
    3330              :         }
    3331          591 :       else if (DECL_LOOPING_CONST_OR_PURE_P (node->decl)
    3332          591 :                && !info->looping)
    3333              :         {
    3334          314 :           DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
    3335          314 :           info->changed = true;
    3336              :         }
    3337              :     }
    3338              :   else
    3339              :     {
    3340         2206 :       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       355401 :   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       365298 : cgraph_node::set_pure_flag (bool pure, bool looping)
    3358              : {
    3359       365298 :   struct set_pure_flag_info info = {pure, looping, false};
    3360       365298 :   call_for_symbol_thunks_and_aliases (set_pure_flag_1, &info, !pure, true);
    3361       365298 :   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       365298 :   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     14292750 : cgraph_node::cannot_return_p (void)
    3372              : {
    3373     14292750 :   int flags = flags_from_decl_or_type (decl);
    3374     14292750 :   if (!opt_for_fn (decl, flag_exceptions))
    3375      4718709 :     return (flags & ECF_NORETURN) != 0;
    3376              :   else
    3377      9574041 :     return ((flags & (ECF_NORETURN | ECF_NOTHROW))
    3378      9574041 :              == (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      2988509 : cgraph_edge::cannot_lead_to_return_p (void)
    3388              : {
    3389      2988509 :   if (caller->cannot_return_p ())
    3390              :     return true;
    3391      2900830 :   if (indirect_unknown_callee)
    3392              :     {
    3393        86007 :       int flags = indirect_info->ecf_flags;
    3394        86007 :       if (!opt_for_fn (caller->decl, flag_exceptions))
    3395        19656 :         return (flags & ECF_NORETURN) != 0;
    3396              :       else
    3397        66351 :         return ((flags & (ECF_NORETURN | ECF_NOTHROW))
    3398        66351 :                  == (ECF_NORETURN | ECF_NOTHROW));
    3399              :     }
    3400              :   else
    3401      2814823 :     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      5385932 : cgraph_edge::maybe_hot_p (sreal scale)
    3409              : {
    3410              :   /* Never consider calls in functions optimized for size hot.  */
    3411      5385932 :   if (opt_for_fn (caller->decl, optimize_size))
    3412              :     return false;
    3413              : 
    3414              :   /* If reliable IPA count is available, just use it.  */
    3415      5322167 :   profile_count c = count.ipa ();
    3416      5322167 :   if (c.reliable_p ()
    3417      5322167 :       || (c.quality () == AFDO && c.nonzero_p ()))
    3418       719253 :     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      4602914 :   if ((c.quality () == AFDO
    3423      4602914 :        || count.quality () == GUESSED_GLOBAL0_ADJUSTED)
    3424      4602914 :       && 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      4602914 :   if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
    3429      4599791 :       || (callee
    3430      4198148 :           && callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
    3431              :     return false;
    3432      4597670 :   if (caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
    3433      4597670 :       && (callee
    3434      4196027 :           && 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      4541738 :   if (caller->frequency == NODE_FREQUENCY_HOT)
    3443              :     return true;
    3444              : 
    3445              :   /* Use IPA count and if it s not available appy local heuristics.  */
    3446      4541736 :   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      4541736 :   if (!count.initialized_p ())
    3456              :     return true;
    3457      3328287 :   cgraph_node *where = caller->inlined_to ? caller->inlined_to : caller;
    3458      3328287 :   if (!where->count.initialized_p ())
    3459              :     return true;
    3460      3328287 :   c = count * scale;
    3461      3328287 :   if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE)
    3462              :     {
    3463        83411 :       if (c * 2 < where->count * 3)
    3464              :         return false;
    3465              :     }
    3466      3244876 :   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      2130097 : cgraph_edge::maybe_hot_p ()
    3475              : {
    3476      2130097 :   return maybe_hot_p (1);
    3477              : }
    3478              : 
    3479              : /* Worker for cgraph_can_remove_if_no_direct_calls_p.  */
    3480              : 
    3481              : static bool
    3482       671437 : nonremovable_p (cgraph_node *node, void *)
    3483              : {
    3484       671437 :   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       903621 : cgraph_node::can_remove_if_no_direct_calls_p (bool will_inline)
    3492              : {
    3493       903621 :   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       903621 :   if (!externally_visible || !same_comdat_group)
    3498              :     {
    3499       678743 :       if (DECL_EXTERNAL (decl))
    3500              :         return true;
    3501       678743 :       if (address_taken)
    3502              :         return false;
    3503       644455 :       return !call_for_symbol_and_aliases (nonremovable_p, NULL, true);
    3504              :     }
    3505              : 
    3506       224878 :   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       224878 :   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       432077 :   for (int i = 0; iterate_referring (i, ref); i++)
    3517       219695 :     if (ref->referring->get_comdat_group () != get_comdat_group ())
    3518              :       return false;
    3519              : 
    3520       212382 :   struct cgraph_node *target = ultimate_alias_target ();
    3521       212382 :   for (cgraph_node *next = dyn_cast<cgraph_node *> (same_comdat_group);
    3522       639648 :        next != this; next = dyn_cast<cgraph_node *> (next->same_comdat_group))
    3523              :     {
    3524       225539 :       if (!externally_visible)
    3525            0 :         continue;
    3526       225539 :       if (!next->alias
    3527       225539 :           && !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       225539 :       if (next->ultimate_alias_target () != target)
    3532        21450 :         for (cgraph_edge *e = next->callers; e; e = e->next_caller)
    3533         4627 :           if (e->caller->get_comdat_group () != get_comdat_group ()
    3534         4627 :               || 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       223673 :       if (!will_inline)
    3540       224827 :         for (int i = 0; next->iterate_referring (i, ref); i++)
    3541        11194 :           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      3109345 : cgraph_node::will_be_removed_from_program_if_no_direct_calls_p
    3563              :          (bool will_inline)
    3564              : {
    3565      3109345 :   gcc_assert (!inlined_to);
    3566      3109345 :   if (DECL_EXTERNAL (decl))
    3567              :     return true;
    3568              : 
    3569      3109345 :   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      2895344 :       if (!only_called_directly_p ())
    3575              :         return false;
    3576       739072 :       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       739072 :       return true;
    3602              :     }
    3603              :   else
    3604       214001 :     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     16009697 : cgraph_not_only_called_directly_p_1 (cgraph_node *node, void *)
    3612              : {
    3613     16009697 :   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     15901600 : cgraph_node::only_called_directly_p (void)
    3623              : {
    3624     15901600 :   gcc_assert (ultimate_alias_target () == this);
    3625     15901600 :   return !call_for_symbol_and_aliases (cgraph_not_only_called_directly_p_1,
    3626     15901600 :                                        NULL, true);
    3627              : }
    3628              : 
    3629              : /* Returns TRUE iff THIS is a descendant of N in the clone tree.  */
    3630              : 
    3631              : bool
    3632           33 : cgraph_node::is_clone_of (cgraph_node *n) const
    3633              : {
    3634           33 :   for (cgraph_node *walker = clone_of; walker; walker = walker->clone_of)
    3635            0 :     if (walker == n)
    3636              :       return true;
    3637              :   return false;
    3638              : }
    3639              : 
    3640              : /* Collect all callers of NODE.  Worker for collect_callers_of_node.  */
    3641              : 
    3642              : static bool
    3643       132632 : collect_callers_of_node_1 (cgraph_node *node, void *data)
    3644              : {
    3645       132632 :   vec<cgraph_edge *> *redirect_callers = (vec<cgraph_edge *> *)data;
    3646       132632 :   cgraph_edge *cs;
    3647       132632 :   enum availability avail;
    3648       132632 :   node->ultimate_alias_target (&avail);
    3649              : 
    3650       132632 :   if (avail > AVAIL_INTERPOSABLE)
    3651       464205 :     for (cs = node->callers; cs != NULL; cs = cs->next_caller)
    3652       331573 :       if (!cs->indirect_inlining_edge
    3653       331573 :           && !cs->caller->thunk)
    3654       331514 :         redirect_callers->safe_push (cs);
    3655       132632 :   return false;
    3656              : }
    3657              : 
    3658              : /* Collect all callers of cgraph_node and its aliases that are known to lead to
    3659              :    cgraph_node (i.e. are not overwritable).  */
    3660              : 
    3661              : auto_vec<cgraph_edge *>
    3662       130845 : cgraph_node::collect_callers (void)
    3663              : {
    3664       130845 :   auto_vec<cgraph_edge *> redirect_callers;
    3665       130845 :   call_for_symbol_thunks_and_aliases (collect_callers_of_node_1,
    3666              :                                     &redirect_callers, false);
    3667       130845 :   return redirect_callers;
    3668              : }
    3669              : 
    3670              : 
    3671              : /* Return TRUE if NODE2 a clone of NODE or is equivalent to it.  Return
    3672              :    optimistically true if this cannot be determined.  */
    3673              : 
    3674              : static bool
    3675        43832 : clone_of_p (cgraph_node *node, cgraph_node *node2)
    3676              : {
    3677        43832 :   node = node->ultimate_alias_target ();
    3678        43832 :   node2 = node2->ultimate_alias_target ();
    3679              : 
    3680        43832 :   if (node2->clone_of == node
    3681         5265 :       || node2->former_clone_of == node->decl)
    3682              :     return true;
    3683              : 
    3684         5327 :   if (!node->thunk && !node->former_thunk_p ())
    3685              :     {
    3686              :       while (node2
    3687        15608 :              && node->decl != node2->decl
    3688        26014 :              && node->decl != node2->former_clone_of)
    3689        10405 :         node2 = node2->clone_of;
    3690         5203 :       return node2 != NULL;
    3691              :     }
    3692              : 
    3693              :   /* There are no virtual clones of thunks so check former_clone_of or if we
    3694              :      might have skipped thunks because this adjustments are no longer
    3695              :      necessary.  */
    3696           62 :   while (node->thunk || node->former_thunk_p ())
    3697              :     {
    3698           62 :       if (!thunk_info::get (node)->this_adjusting)
    3699              :         return false;
    3700              :       /* In case of instrumented expanded thunks, which can have multiple calls
    3701              :          in them, we do not know how to continue and just have to be
    3702              :          optimistic.  The same applies if all calls have already been inlined
    3703              :          into the thunk.  */
    3704           62 :       if (!node->callees || node->callees->next_callee)
    3705              :         return true;
    3706           59 :       node = node->callees->callee->ultimate_alias_target ();
    3707              : 
    3708           59 :       clone_info *info = clone_info::get (node2);
    3709           59 :       if (!info || !info->param_adjustments
    3710          118 :           || info->param_adjustments->first_param_intact_p ())
    3711            0 :         return false;
    3712           59 :       if (node2->former_clone_of == node->decl
    3713           59 :           || node2->former_clone_of == node->former_clone_of)
    3714              :         return true;
    3715              : 
    3716              :       cgraph_node *n2 = node2;
    3717            0 :       while (n2 && node->decl != n2->decl)
    3718            0 :         n2 = n2->clone_of;
    3719            0 :       if (n2)
    3720              :         return true;
    3721              :     }
    3722              : 
    3723              :   return false;
    3724              : }
    3725              : 
    3726              : /* Verify edge count and frequency.  */
    3727              : 
    3728              : bool
    3729    196756545 : cgraph_edge::verify_count ()
    3730              : {
    3731    196756545 :   bool error_found = false;
    3732    196756545 :   if (!count.verify ())
    3733              :     {
    3734            0 :       error ("caller edge count invalid");
    3735            0 :       error_found = true;
    3736              :     }
    3737    196756545 :   return error_found;
    3738              : }
    3739              : 
    3740              : /* Switch to THIS_CFUN if needed and print STMT to stderr.  */
    3741              : static void
    3742            0 : cgraph_debug_gimple_stmt (function *this_cfun, gimple *stmt)
    3743              : {
    3744            0 :   bool fndecl_was_null = false;
    3745              :   /* debug_gimple_stmt needs correct cfun */
    3746            0 :   if (cfun != this_cfun)
    3747            0 :     set_cfun (this_cfun);
    3748              :   /* ...and an actual current_function_decl */
    3749            0 :   if (!current_function_decl)
    3750              :     {
    3751            0 :       current_function_decl = this_cfun->decl;
    3752            0 :       fndecl_was_null = true;
    3753              :     }
    3754            0 :   debug_gimple_stmt (stmt);
    3755            0 :   if (fndecl_was_null)
    3756            0 :     current_function_decl = NULL;
    3757            0 : }
    3758              : 
    3759              : /* Verify that call graph edge corresponds to DECL from the associated
    3760              :    statement.  Return true if the verification should fail.  */
    3761              : 
    3762              : bool
    3763     96772131 : cgraph_edge::verify_corresponds_to_fndecl (tree decl)
    3764              : {
    3765     96772131 :   cgraph_node *node;
    3766              : 
    3767     96772131 :   if (!decl || callee->inlined_to)
    3768              :     return false;
    3769     93026541 :   if (symtab->state == LTO_STREAMING)
    3770              :     return false;
    3771     93026541 :   node = cgraph_node::get (decl);
    3772              : 
    3773              :   /* We do not know if a node from a different partition is an alias or what it
    3774              :      aliases and therefore cannot do the former_clone_of check reliably.  When
    3775              :      body_removed is set, we have lost all information about what was alias or
    3776              :      thunk of and also cannot proceed.  */
    3777     93026541 :   if (!node
    3778     92915389 :       || node->body_removed
    3779     92067053 :       || node->in_other_partition
    3780     92067053 :       || callee->icf_merged
    3781     91969260 :       || callee->in_other_partition)
    3782              :     return false;
    3783              : 
    3784     91969260 :   node = node->ultimate_alias_target ();
    3785              : 
    3786              :   /* Optimizers can redirect unreachable calls or calls triggering undefined
    3787              :      behavior to __builtin_unreachable or __builtin_unreachable trap.  */
    3788              : 
    3789     91969260 :   if (fndecl_built_in_p (callee->decl, BUILT_IN_UNREACHABLE,
    3790              :                                        BUILT_IN_UNREACHABLE_TRAP))
    3791              :     return false;
    3792              : 
    3793     89245262 :   if (callee->former_clone_of != node->decl
    3794     89242808 :       && (node != callee->ultimate_alias_target ())
    3795     89289094 :       && !clone_of_p (node, callee))
    3796              :     return true;
    3797              :   else
    3798     89245262 :     return false;
    3799              : }
    3800              : 
    3801              : /* Disable warnings about missing quoting in GCC diagnostics for
    3802              :    the verification errors.  Their format strings don't follow GCC
    3803              :    diagnostic conventions and the calls are ultimately followed by
    3804              :    one to internal_error.  */
    3805              : #if __GNUC__ >= 10
    3806              : #  pragma GCC diagnostic push
    3807              : #  pragma GCC diagnostic ignored "-Wformat-diag"
    3808              : #endif
    3809              : 
    3810              : /* Verify consistency of speculative call in NODE corresponding to STMT
    3811              :    and LTO_STMT_UID.  If INDIRECT is set, assume that it is the indirect
    3812              :    edge of call sequence. Return true if error is found.
    3813              : 
    3814              :    This function is called to every component of indirect call (direct edges,
    3815              :    indirect edge and refs).  To save duplicated work, do full testing only
    3816              :    in that case.  */
    3817              : static bool
    3818       430014 : verify_speculative_call (struct cgraph_node *node, gimple *stmt,
    3819              :                          unsigned int lto_stmt_uid,
    3820              :                          struct cgraph_edge *indirect)
    3821              : {
    3822       430014 :   if (indirect == NULL)
    3823              :     {
    3824       500712 :       for (indirect = node->indirect_calls; indirect;
    3825       186890 :            indirect = indirect->next_callee)
    3826       500712 :         if (indirect->call_stmt == stmt
    3827       313988 :             && indirect->lto_stmt_uid == lto_stmt_uid)
    3828              :           break;
    3829       313822 :       if (!indirect)
    3830              :         {
    3831            0 :           error ("missing indirect call in speculative call sequence");
    3832            0 :           return true;
    3833              :         }
    3834       313822 :       if (!indirect->speculative)
    3835              :         {
    3836            0 :           error ("indirect call in speculative call sequence has no "
    3837              :                  "speculative flag");
    3838            0 :           return true;
    3839              :         }
    3840              :       return false;
    3841              :     }
    3842              : 
    3843              :   /* Maximal number of targets.  We probably will never want to have more than
    3844              :      this.  */
    3845              :   const unsigned int num = 256;
    3846              :   cgraph_edge *direct_calls[num];
    3847              :   ipa_ref *refs[num];
    3848              : 
    3849     29861344 :   for (unsigned int i = 0; i < num; i++)
    3850              :     {
    3851     29745152 :       direct_calls[i] = NULL;
    3852     29745152 :       refs[i] = NULL;
    3853              :     }
    3854              : 
    3855       116192 :   cgraph_edge *first_call = NULL;
    3856       116192 :   cgraph_edge *prev_call = NULL;
    3857              : 
    3858      1137500 :   for (cgraph_edge *direct = node->callees; direct;
    3859      1021308 :        direct = direct->next_callee)
    3860      1021308 :     if (direct->call_stmt == stmt && direct->lto_stmt_uid == lto_stmt_uid)
    3861              :       {
    3862       156911 :         if (!first_call)
    3863       116192 :           first_call = direct;
    3864       156911 :         if (prev_call && direct != prev_call->next_callee)
    3865              :           {
    3866            0 :             error ("speculative edges are not adjacent");
    3867            0 :             return true;
    3868              :           }
    3869       156911 :         prev_call = direct;
    3870       156911 :         if (!direct->speculative)
    3871              :           {
    3872            0 :             error ("direct call to %s in speculative call sequence has no "
    3873            0 :                    "speculative flag", direct->callee->dump_name ());
    3874            0 :             return true;
    3875              :           }
    3876       156911 :         if (direct->speculative_id >= num)
    3877              :           {
    3878            0 :             error ("direct call to %s in speculative call sequence has "
    3879              :                    "speculative_id %i out of range",
    3880            0 :                    direct->callee->dump_name (), direct->speculative_id);
    3881            0 :             return true;
    3882              :           }
    3883       156911 :         if (direct_calls[direct->speculative_id])
    3884              :           {
    3885            0 :             error ("duplicate direct call to %s in speculative call sequence "
    3886              :                    "with speculative_id %i",
    3887            0 :                    direct->callee->dump_name (), direct->speculative_id);
    3888            0 :             return true;
    3889              :           }
    3890       156911 :         direct_calls[direct->speculative_id] = direct;
    3891              :       }
    3892              : 
    3893       116192 :   if (first_call->call_stmt
    3894       116192 :       && first_call != node->get_edge (first_call->call_stmt))
    3895              :     {
    3896            0 :       error ("call stmt hash does not point to first direct edge of "
    3897              :              "speculative call sequence");
    3898            0 :       return true;
    3899              :     }
    3900              : 
    3901              :   ipa_ref *ref;
    3902      1458446 :   for (int i = 0; node->iterate_reference (i, ref); i++)
    3903      1342254 :     if (ref->speculative
    3904       262722 :         && ref->stmt == stmt && ref->lto_stmt_uid == lto_stmt_uid)
    3905              :       {
    3906       156911 :         if (ref->speculative_id >= num)
    3907              :           {
    3908            0 :             error ("direct call to %s in speculative call sequence has "
    3909              :                    "speculative_id %i out of range",
    3910            0 :                    ref->referred->dump_name (), ref->speculative_id);
    3911            0 :             return true;
    3912              :           }
    3913       156911 :         if (refs[ref->speculative_id])
    3914              :           {
    3915            0 :             error ("duplicate reference %s in speculative call sequence "
    3916              :                    "with speculative_id %i",
    3917            0 :                    ref->referred->dump_name (), ref->speculative_id);
    3918            0 :             return true;
    3919              :           }
    3920       156911 :         refs[ref->speculative_id] = ref;
    3921              :       }
    3922              : 
    3923              :   int num_targets = 0;
    3924     29861344 :   for (unsigned int i = 0 ; i < num ; i++)
    3925              :     {
    3926     29745152 :       if (refs[i] && !direct_calls[i])
    3927              :         {
    3928            0 :           error ("missing direct call for speculation %i", i);
    3929            0 :           return true;
    3930              :         }
    3931     29745152 :       if (!refs[i] && direct_calls[i])
    3932              :         {
    3933            0 :           error ("missing ref for speculation %i", i);
    3934            0 :           return true;
    3935              :         }
    3936     29745152 :       if (refs[i] != NULL)
    3937       156911 :         num_targets++;
    3938              :     }
    3939              : 
    3940       116192 :   if (num_targets != indirect->num_speculative_call_targets_p ())
    3941              :     {
    3942            0 :       error ("number of speculative targets %i mismatched with "
    3943              :              "num_speculative_call_targets %i",
    3944              :              num_targets,
    3945              :              indirect->num_speculative_call_targets_p ());
    3946            0 :       return true;
    3947              :     }
    3948              :   return false;
    3949              : }
    3950              : 
    3951              : /* Verify cgraph nodes of given cgraph node.  */
    3952              : DEBUG_FUNCTION void
    3953     51959239 : cgraph_node::verify_node (void)
    3954              : {
    3955     51959239 :   cgraph_edge *e;
    3956     51959239 :   function *this_cfun = DECL_STRUCT_FUNCTION (decl);
    3957     51959239 :   basic_block this_block;
    3958     51959239 :   gimple_stmt_iterator gsi;
    3959     51959239 :   bool error_found = false;
    3960     51959239 :   int i;
    3961     51959239 :   ipa_ref *ref = NULL;
    3962              : 
    3963     51959239 :   if (seen_error ())
    3964     51959239 :     return;
    3965              : 
    3966     51959239 :   timevar_push (TV_CGRAPH_VERIFY);
    3967     51959239 :   error_found |= verify_base ();
    3968    157671642 :   for (e = callees; e; e = e->next_callee)
    3969    105712403 :     if (e->aux)
    3970              :       {
    3971            0 :         error ("aux field set for edge %s->%s",
    3972            0 :                identifier_to_locale (e->caller->name ()),
    3973            0 :                identifier_to_locale (e->callee->name ()));
    3974            0 :         error_found = true;
    3975              :       }
    3976     51959239 :   if (!count.verify ())
    3977              :     {
    3978            0 :       error ("cgraph count invalid");
    3979            0 :       error_found = true;
    3980              :     }
    3981     51959239 :   if (inlined_to && same_comdat_group)
    3982              :     {
    3983            0 :       error ("inline clone in same comdat group list");
    3984            0 :       error_found = true;
    3985              :     }
    3986     51959239 :   if (inlined_to && !count.compatible_p (inlined_to->count))
    3987              :     {
    3988            0 :       error ("inline clone count is not compatible");
    3989            0 :       count.debug ();
    3990            0 :       inlined_to->count.debug ();
    3991            0 :       error_found = true;
    3992              :     }
    3993     51959239 :   if (tp_first_run < 0)
    3994              :     {
    3995            0 :       error ("tp_first_run must be non-negative");
    3996            0 :       error_found = true;
    3997              :     }
    3998     51959239 :   if (!definition && !in_other_partition && local)
    3999              :     {
    4000            0 :       error ("local symbols must be defined");
    4001            0 :       error_found = true;
    4002              :     }
    4003     51959239 :   if (inlined_to && externally_visible)
    4004              :     {
    4005            0 :       error ("externally visible inline clone");
    4006            0 :       error_found = true;
    4007              :     }
    4008     51959239 :   if (inlined_to && address_taken)
    4009              :     {
    4010            0 :       error ("inline clone with address taken");
    4011            0 :       error_found = true;
    4012              :     }
    4013     51959239 :   if (inlined_to && force_output)
    4014              :     {
    4015            0 :       error ("inline clone is forced to output");
    4016            0 :       error_found = true;
    4017              :     }
    4018     51959239 :   if (inlined_to && ref_by_asm)
    4019              :     {
    4020            0 :       error ("inline clone is referenced by assembly");
    4021            0 :       error_found = true;
    4022              :     }
    4023     51959239 :   if (symtab->state != LTO_STREAMING)
    4024              :     {
    4025     51848695 :       if (calls_comdat_local && !same_comdat_group)
    4026              :         {
    4027            0 :           error ("calls_comdat_local is set outside of a comdat group");
    4028            0 :           error_found = true;
    4029              :         }
    4030     51848695 :       if (!inlined_to && calls_comdat_local != check_calls_comdat_local_p ())
    4031              :         {
    4032            0 :           error ("invalid calls_comdat_local flag");
    4033            0 :           error_found = true;
    4034              :         }
    4035              :     }
    4036     51959239 :   if (DECL_IS_MALLOC (decl)
    4037     51959239 :       && !POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
    4038              :     {
    4039            0 :       error ("malloc attribute should be used for a function that "
    4040              :              "returns a pointer");
    4041            0 :       error_found = true;
    4042              :     }
    4043     51959239 :   if (definition
    4044     34865549 :       && externally_visible
    4045              :       /* For aliases in lto1 free_lang_data doesn't guarantee preservation
    4046              :          of opt_for_fn (decl, flag_semantic_interposition).  See PR105399.  */
    4047     18812746 :       && (!alias || !in_lto_p)
    4048     51959239 :       && semantic_interposition
    4049     18809851 :          != opt_for_fn (decl, flag_semantic_interposition))
    4050              :     {
    4051            0 :       error ("semantic interposition mismatch");
    4052            0 :       error_found = true;
    4053              :     }
    4054     54276897 :   for (e = indirect_calls; e; e = e->next_callee)
    4055              :     {
    4056      2317658 :       if (e->aux)
    4057              :         {
    4058            0 :           error ("aux field set for indirect edge from %s",
    4059            0 :                  identifier_to_locale (e->caller->name ()));
    4060            0 :           error_found = true;
    4061              :         }
    4062      2317658 :       if (!e->count.compatible_p (count))
    4063              :         {
    4064            0 :           error ("edge count is not compatible with function count");
    4065            0 :           e->count.debug ();
    4066            0 :           count.debug ();
    4067            0 :           error_found = true;
    4068              :         }
    4069      2317658 :       if (inlined_to && !e->count.compatible_p (inlined_to->count))
    4070              :         {
    4071            0 :           error ("edge count is not compatible with inlined to function count");
    4072            0 :           e->count.debug ();
    4073            0 :           count.debug ();
    4074            0 :           error_found = true;
    4075              :         }
    4076      2317658 :       if (!e->indirect_unknown_callee
    4077      2317658 :           || !e->indirect_info)
    4078              :         {
    4079            0 :           error ("An indirect edge from %s is not marked as indirect or has "
    4080              :                  "associated indirect_info, the corresponding statement is: ",
    4081            0 :                  identifier_to_locale (e->caller->name ()));
    4082            0 :           cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4083            0 :           error_found = true;
    4084              :         }
    4085      2317658 :       if (e->call_stmt && e->lto_stmt_uid)
    4086              :         {
    4087            0 :           error ("edge has both call_stmt and lto_stmt_uid set");
    4088            0 :           error_found = true;
    4089              :         }
    4090              :     }
    4091     51959239 :   bool check_comdat = comdat_local_p ();
    4092    140685723 :   for (e = callers; e; e = e->next_caller)
    4093              :     {
    4094     88726484 :       if (e->verify_count ())
    4095            0 :         error_found = true;
    4096     88726484 :       if (check_comdat
    4097     88726484 :           && !in_same_comdat_group_p (e->caller))
    4098              :         {
    4099            0 :           error ("comdat-local function called by %s outside its comdat",
    4100              :                  identifier_to_locale (e->caller->name ()));
    4101            0 :           error_found = true;
    4102              :         }
    4103     88726484 :       if (!e->inline_failed)
    4104              :         {
    4105      8136591 :           if (inlined_to
    4106      8136591 :               != (e->caller->inlined_to
    4107      8136591 :                   ? e->caller->inlined_to : e->caller))
    4108              :             {
    4109            0 :               error ("inlined_to pointer is wrong");
    4110            0 :               error_found = true;
    4111              :             }
    4112      8136591 :           if (callers->next_caller)
    4113              :             {
    4114            0 :               error ("multiple inline callers");
    4115            0 :               error_found = true;
    4116              :             }
    4117              :         }
    4118              :       else
    4119     80589893 :         if (inlined_to)
    4120              :           {
    4121            0 :             error ("inlined_to pointer set for noninline callers");
    4122            0 :             error_found = true;
    4123              :           }
    4124              :     }
    4125    157671642 :   for (e = callees; e; e = e->next_callee)
    4126              :     {
    4127    105712403 :       if (e->verify_count ())
    4128            0 :         error_found = true;
    4129    105712403 :       if (!e->count.compatible_p (count))
    4130              :         {
    4131            0 :           error ("edge count is not compatible with function count");
    4132            0 :           e->count.debug ();
    4133            0 :           count.debug ();
    4134            0 :           error_found = true;
    4135              :         }
    4136    105712403 :       if (gimple_has_body_p (e->caller->decl)
    4137     99242906 :           && !e->caller->inlined_to
    4138     90456128 :           && !e->speculative
    4139     90402987 :           && !e->callback
    4140     90380339 :           && !e->has_callback
    4141              :           /* Optimized out calls are redirected to __builtin_unreachable.  */
    4142     90292128 :           && (e->count.nonzero_p ()
    4143     51967290 :               || ! e->callee->decl
    4144     51967290 :               || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
    4145              :                                      BUILT_IN_UNREACHABLE_TRAP))
    4146              :           && count
    4147     88563941 :               == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
    4148    194268756 :           && (!e->count.ipa_p ()
    4149     40261649 :               && e->count.differs_from_p (gimple_bb (e->call_stmt)->count)))
    4150              :         {
    4151            0 :           error ("caller edge count does not match BB count");
    4152            0 :           fprintf (stderr, "edge count: ");
    4153            0 :           e->count.dump (stderr);
    4154            0 :           fprintf (stderr, "\n bb count: ");
    4155            0 :           gimple_bb (e->call_stmt)->count.dump (stderr);
    4156            0 :           fprintf (stderr, "\n");
    4157            0 :           error_found = true;
    4158              :         }
    4159    105712403 :       if (e->call_stmt && e->lto_stmt_uid)
    4160              :         {
    4161            0 :           error ("edge has both call_stmt and lto_stmt_uid set");
    4162            0 :           error_found = true;
    4163              :         }
    4164    105712403 :       if (e->speculative
    4165    105712403 :           && verify_speculative_call (e->caller, e->call_stmt, e->lto_stmt_uid,
    4166              :                                       NULL))
    4167              :         error_found = true;
    4168              :     }
    4169     54276897 :   for (e = indirect_calls; e; e = e->next_callee)
    4170              :     {
    4171      2317658 :       if (e->verify_count ())
    4172            0 :         error_found = true;
    4173      2317658 :       if (gimple_has_body_p (e->caller->decl)
    4174      2270634 :           && !e->caller->inlined_to
    4175      2041676 :           && !e->speculative
    4176      2002830 :           && e->count.ipa_p ()
    4177              :           && count
    4178       751091 :               == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
    4179      3068745 :           && (!e->count.ipa_p ()
    4180            0 :               && e->count.differs_from_p (gimple_bb (e->call_stmt)->count)))
    4181              :         {
    4182            0 :           error ("indirect call count does not match BB count");
    4183            0 :           fprintf (stderr, "edge count: ");
    4184            0 :           e->count.dump (stderr);
    4185            0 :           fprintf (stderr, "\n bb count: ");
    4186            0 :           gimple_bb (e->call_stmt)->count.dump (stderr);
    4187            0 :           fprintf (stderr, "\n");
    4188            0 :           error_found = true;
    4189              :         }
    4190      2317658 :       if (e->speculative
    4191      2317658 :           && verify_speculative_call (e->caller, e->call_stmt, e->lto_stmt_uid,
    4192              :                                       e))
    4193              :         error_found = true;
    4194              :     }
    4195    117784571 :   for (i = 0; iterate_reference (i, ref); i++)
    4196              :     {
    4197     65825332 :       if (ref->stmt && ref->lto_stmt_uid)
    4198              :         {
    4199            0 :           error ("reference has both stmt and lto_stmt_uid set");
    4200            0 :           error_found = true;
    4201              :         }
    4202     65825332 :       if (ref->speculative
    4203     65825332 :           && verify_speculative_call (this, ref->stmt,
    4204              :                                       ref->lto_stmt_uid, NULL))
    4205              :         error_found = true;
    4206              :     }
    4207              : 
    4208     51959239 :   if (!callers && inlined_to)
    4209              :     {
    4210            0 :       error ("inlined_to pointer is set but no predecessors found");
    4211            0 :       error_found = true;
    4212              :     }
    4213     51959239 :   if (inlined_to == this)
    4214              :     {
    4215            0 :       error ("inlined_to pointer refers to itself");
    4216            0 :       error_found = true;
    4217              :     }
    4218              : 
    4219     51959239 :   if (clone_of)
    4220              :     {
    4221      5949963 :       cgraph_node *first_clone = clone_of->clones;
    4222      5949963 :       if (first_clone != this)
    4223              :         {
    4224      3028612 :           if (prev_sibling_clone->clone_of != clone_of)
    4225              :             {
    4226            0 :               error ("cgraph_node has wrong clone_of");
    4227            0 :               error_found = true;
    4228              :             }
    4229              :         }
    4230              :     }
    4231     51959239 :   if (clones)
    4232              :     {
    4233              :       cgraph_node *n;
    4234      8187728 :       for (n = clones; n; n = n->next_sibling_clone)
    4235      6559012 :         if (n->clone_of != this)
    4236              :           break;
    4237      1628716 :       if (n)
    4238              :         {
    4239            0 :           error ("cgraph_node has wrong clone list");
    4240            0 :           error_found = true;
    4241              :         }
    4242              :     }
    4243     51959239 :   if ((prev_sibling_clone || next_sibling_clone) && !clone_of)
    4244              :     {
    4245            0 :        error ("cgraph_node is in clone list but it is not clone");
    4246            0 :        error_found = true;
    4247              :     }
    4248     51959239 :   if (!prev_sibling_clone && clone_of && clone_of->clones != this)
    4249              :     {
    4250            0 :       error ("cgraph_node has wrong prev_clone pointer");
    4251            0 :       error_found = true;
    4252              :     }
    4253     51959239 :   if (prev_sibling_clone && prev_sibling_clone->next_sibling_clone != this)
    4254              :     {
    4255            0 :       error ("double linked list of clones corrupted");
    4256            0 :       error_found = true;
    4257              :     }
    4258              : 
    4259     51959239 :   if (analyzed && alias)
    4260              :     {
    4261      1404589 :       bool ref_found = false;
    4262      1404589 :       int i;
    4263      1404589 :       ipa_ref *ref = NULL;
    4264              : 
    4265      1404589 :       if (callees)
    4266              :         {
    4267            0 :           error ("Alias has call edges");
    4268            0 :           error_found = true;
    4269              :         }
    4270      2809178 :       for (i = 0; iterate_reference (i, ref); i++)
    4271      1404589 :         if (ref->use != IPA_REF_ALIAS)
    4272              :           {
    4273            0 :             error ("Alias has non-alias reference");
    4274            0 :             error_found = true;
    4275              :           }
    4276      1404589 :         else if (ref_found)
    4277              :           {
    4278            0 :             error ("Alias has more than one alias reference");
    4279            0 :             error_found = true;
    4280              :           }
    4281              :         else
    4282              :           ref_found = true;
    4283      1404589 :       if (!ref_found)
    4284              :         {
    4285            0 :           error ("Analyzed alias has no reference");
    4286            0 :           error_found = true;
    4287              :         }
    4288              :     }
    4289              : 
    4290     51959239 :   if (analyzed && thunk)
    4291              :     {
    4292        21925 :       if (!callees)
    4293              :         {
    4294            0 :           error ("No edge out of thunk node");
    4295            0 :           error_found = true;
    4296              :         }
    4297        21925 :       else if (callees->next_callee)
    4298              :         {
    4299            0 :           error ("More than one edge out of thunk node");
    4300            0 :           error_found = true;
    4301              :         }
    4302        21925 :       if (gimple_has_body_p (decl) && !inlined_to)
    4303              :         {
    4304            0 :           error ("Thunk is not supposed to have body");
    4305            0 :           error_found = true;
    4306              :         }
    4307              :     }
    4308     34841662 :   else if (analyzed && gimple_has_body_p (decl)
    4309     30036370 :            && !TREE_ASM_WRITTEN (decl)
    4310     30036370 :            && (!DECL_EXTERNAL (decl) || inlined_to)
    4311     80913297 :            && !flag_wpa)
    4312              :     {
    4313     28949628 :       if ((this_cfun->curr_properties & PROP_assumptions_done) != 0)
    4314              :         ;
    4315     28949520 :       else if (this_cfun->cfg)
    4316              :         {
    4317     28949520 :           hash_set<gimple *> stmts;
    4318              : 
    4319              :           /* Reach the trees by walking over the CFG, and note the
    4320              :              enclosing basic-blocks in the call edges.  */
    4321    240755017 :           FOR_EACH_BB_FN (this_block, this_cfun)
    4322              :             {
    4323    211805497 :               for (gsi = gsi_start_phis (this_block);
    4324    255431989 :                    !gsi_end_p (gsi); gsi_next (&gsi))
    4325     43626492 :                 stmts.add (gsi_stmt (gsi));
    4326    423610994 :               for (gsi = gsi_start_bb (this_block);
    4327   1275557405 :                    !gsi_end_p (gsi);
    4328   1063751908 :                    gsi_next (&gsi))
    4329              :                 {
    4330   1063751908 :                   gimple *stmt = gsi_stmt (gsi);
    4331   1063751908 :                   stmts.add (stmt);
    4332   1063751908 :                   if (is_gimple_call (stmt))
    4333              :                     {
    4334    103350903 :                       cgraph_edge *e = get_edge (stmt);
    4335    103350903 :                       tree decl = gimple_call_fndecl (stmt);
    4336    103350903 :                       if (e)
    4337              :                         {
    4338     98912961 :                           if (e->aux)
    4339              :                             {
    4340            0 :                               error ("shared call_stmt:");
    4341            0 :                               cgraph_debug_gimple_stmt (this_cfun, stmt);
    4342            0 :                               error_found = true;
    4343              :                             }
    4344     98912961 :                           if (!e->indirect_unknown_callee)
    4345              :                             {
    4346              :                               /* Callback edges violate this assertion
    4347              :                                  because their call statement doesn't exist,
    4348              :                                  their associated statement belongs to the
    4349              :                                  callback-dispatching function.  */
    4350     96772131 :                               if (!e->callback
    4351     96772131 :                                   && e->verify_corresponds_to_fndecl (decl))
    4352              :                                 {
    4353            0 :                                   error ("edge points to wrong declaration:");
    4354            0 :                                   debug_tree (e->callee->decl);
    4355            0 :                                   fprintf (stderr," Instead of:");
    4356            0 :                                   debug_tree (decl);
    4357            0 :                                   error_found = true;
    4358              :                                 }
    4359              :                             }
    4360      2140830 :                           else if (decl)
    4361              :                             {
    4362            0 :                               error ("an indirect edge with unknown callee "
    4363              :                                      "corresponding to a call_stmt with "
    4364              :                                      "a known declaration:");
    4365            0 :                               error_found = true;
    4366            0 :                               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4367              :                             }
    4368     98912961 :                           e->aux = (void *)1;
    4369              :                         }
    4370      4437942 :                       else if (decl)
    4371              :                         {
    4372            0 :                           error ("missing callgraph edge for call stmt:");
    4373            0 :                           cgraph_debug_gimple_stmt (this_cfun, stmt);
    4374            0 :                           error_found = true;
    4375              :                         }
    4376              :                     }
    4377              :                 }
    4378              :               }
    4379     98950416 :             for (i = 0; iterate_reference (i, ref); i++)
    4380     61214199 :               if (ref->stmt && !stmts.contains (ref->stmt))
    4381              :                 {
    4382            0 :                   error ("reference to dead statement");
    4383            0 :                   cgraph_debug_gimple_stmt (this_cfun, ref->stmt);
    4384            0 :                   error_found = true;
    4385              :                 }
    4386     28949520 :         }
    4387              :       else
    4388              :         /* No CFG available?!  */
    4389            0 :         gcc_unreachable ();
    4390              : 
    4391    125783084 :       for (e = callees; e; e = e->next_callee)
    4392              :         {
    4393     96833456 :           if (!e->callback && e->callback_id)
    4394              :             {
    4395            0 :               error ("non-callback edge has callback_id set");
    4396            0 :               error_found = true;
    4397              :             }
    4398              : 
    4399     96833456 :           if (e->callback && e->has_callback)
    4400              :             {
    4401            0 :               error ("edge has both callback and has_callback set");
    4402            0 :               error_found = true;
    4403              :             }
    4404              : 
    4405     96833456 :           if (e->callback)
    4406              :             {
    4407        24155 :               if (!e->get_callback_carrying_edge ())
    4408              :                 {
    4409            0 :                   error ("callback edge %s->%s has no callback-carrying",
    4410            0 :                          identifier_to_locale (e->caller->name ()),
    4411            0 :                          identifier_to_locale (e->callee->name ()));
    4412            0 :                   error_found = true;
    4413              :                 }
    4414              :             }
    4415              : 
    4416     96833456 :           if (e->has_callback
    4417        95211 :               && !callback_is_special_cased (e->callee->decl, e->call_stmt)
    4418     96917922 :               && !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
    4419              :             {
    4420        84454 :               int ncallbacks = 0;
    4421        84454 :               int nfound_edges = 0;
    4422        84454 :               for (tree cb = lookup_attribute (CALLBACK_ATTR_IDENT, DECL_ATTRIBUTES (
    4423              :                                                              e->callee->decl));
    4424       168908 :                    cb; cb = lookup_attribute (CALLBACK_ATTR_IDENT, TREE_CHAIN (cb)),
    4425              :                         ncallbacks++)
    4426              :                 ;
    4427       775811 :               for (cgraph_edge *cbe = callees; cbe; cbe = cbe->next_callee)
    4428              :                 {
    4429       691357 :                   if (cbe->callback && cbe->call_stmt == e->call_stmt
    4430        20775 :                       && cbe->lto_stmt_uid == e->lto_stmt_uid)
    4431              :                     {
    4432        20775 :                       nfound_edges++;
    4433              :                     }
    4434              :                 }
    4435        84454 :               if (ncallbacks < nfound_edges)
    4436              :                 {
    4437            0 :                   error ("callback edge %s->%s callback edge count mismatch, "
    4438              :                          "expected at most %d, found %d",
    4439            0 :                          identifier_to_locale (e->caller->name ()),
    4440            0 :                          identifier_to_locale (e->callee->name ()), ncallbacks,
    4441              :                          nfound_edges);
    4442              :                 }
    4443              :             }
    4444              : 
    4445     96833456 :           if (e->has_callback
    4446     96833456 :               && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
    4447           12 :             for (cgraph_edge *cbe = e->first_callback_edge (); cbe;
    4448            0 :                  cbe = cbe->next_callback_edge ())
    4449            0 :               if (!fndecl_built_in_p (cbe->callee->decl, BUILT_IN_UNREACHABLE))
    4450            0 :                 error ("callback-carrying edge is pointing towards "
    4451              :                        "__builtin_unreachable, but its callback edge %s -> %s "
    4452              :                        "is not",
    4453            0 :                        cbe->caller->name (), cbe->callee->name ());
    4454              : 
    4455     96833456 :           if (!e->aux && !e->speculative && !e->callback && !e->has_callback)
    4456              :             {
    4457            0 :               error ("edge %s->%s has no corresponding call_stmt",
    4458            0 :                      identifier_to_locale (e->caller->name ()),
    4459            0 :                      identifier_to_locale (e->callee->name ()));
    4460            0 :               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4461            0 :               error_found = true;
    4462              :             }
    4463     96833456 :           e->aux = 0;
    4464              :         }
    4465     31198012 :       for (e = indirect_calls; e; e = e->next_callee)
    4466              :         {
    4467      2248384 :           if (!e->aux && !e->speculative)
    4468              :             {
    4469            0 :               error ("an indirect edge from %s has no corresponding call_stmt",
    4470            0 :                      identifier_to_locale (e->caller->name ()));
    4471            0 :               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
    4472            0 :               error_found = true;
    4473              :             }
    4474      2248384 :           e->aux = 0;
    4475              :         }
    4476              :     }
    4477              : 
    4478     51959239 :   if (nested_function_info *info = nested_function_info::get (this))
    4479              :     {
    4480            0 :       if (info->nested != NULL)
    4481              :         {
    4482            0 :           for (cgraph_node *n = info->nested; n != NULL;
    4483            0 :                n = next_nested_function (n))
    4484              :             {
    4485            0 :               nested_function_info *ninfo = nested_function_info::get (n);
    4486            0 :               if (ninfo->origin == NULL)
    4487              :                 {
    4488            0 :                   error ("missing origin for a node in a nested list");
    4489            0 :                   error_found = true;
    4490              :                 }
    4491            0 :               else if (ninfo->origin != this)
    4492              :                 {
    4493            0 :                   error ("origin points to a different parent");
    4494            0 :                   error_found = true;
    4495            0 :                   break;
    4496              :                 }
    4497              :             }
    4498              :         }
    4499            0 :       if (info->next_nested != NULL && info->origin == NULL)
    4500              :         {
    4501            0 :           error ("missing origin for a node in a nested list");
    4502            0 :           error_found = true;
    4503              :         }
    4504              :     }
    4505              : 
    4506     51959239 :   if (error_found)
    4507              :     {
    4508            0 :       dump (stderr);
    4509            0 :       internal_error ("verify_cgraph_node failed");
    4510              :     }
    4511     51959239 :   timevar_pop (TV_CGRAPH_VERIFY);
    4512              : }
    4513              : 
    4514              : /* Verify whole cgraph structure.  */
    4515              : DEBUG_FUNCTION void
    4516          812 : cgraph_node::verify_cgraph_nodes (void)
    4517              : {
    4518          812 :   cgraph_node *node;
    4519              : 
    4520          812 :   if (seen_error ())
    4521              :     return;
    4522              : 
    4523         5120 :   FOR_EACH_FUNCTION (node)
    4524         4332 :     node->verify ();
    4525              : }
    4526              : 
    4527              : #if __GNUC__ >= 10
    4528              : #  pragma GCC diagnostic pop
    4529              : #endif
    4530              : 
    4531              : /* Walk the alias chain to return the function cgraph_node is alias of.
    4532              :    Walk through thunks, too.
    4533              :    When AVAILABILITY is non-NULL, get minimal availability in the chain.
    4534              :    When REF is non-NULL, assume that reference happens in symbol REF
    4535              :    when determining the availability.  */
    4536              : 
    4537              : cgraph_node *
    4538    133400085 : cgraph_node::function_symbol (enum availability *availability,
    4539              :                               struct symtab_node *ref)
    4540              : {
    4541    133400085 :   cgraph_node *node = ultimate_alias_target (availability, ref);
    4542              : 
    4543    266805548 :   while (node->thunk)
    4544              :     {
    4545         5378 :       enum availability a;
    4546              : 
    4547         5378 :       ref = node;
    4548         5378 :       node = node->callees->callee;
    4549         9343 :       node = node->ultimate_alias_target (availability ? &a : NULL, ref);
    4550         5378 :       if (availability && a < *availability)
    4551           32 :         *availability = a;
    4552              :     }
    4553    133400085 :   return node;
    4554              : }
    4555              : 
    4556              : /* Walk the alias chain to return the function cgraph_node is alias of.
    4557              :    Walk through non virtual thunks, too.  Thus we return either a function
    4558              :    or a virtual thunk node.
    4559              :    When AVAILABILITY is non-NULL, get minimal availability in the chain.
    4560              :    When REF is non-NULL, assume that reference happens in symbol REF
    4561              :    when determining the availability.  */
    4562              : 
    4563              : cgraph_node *
    4564     33728254 : cgraph_node::function_or_virtual_thunk_symbol
    4565              :                                 (enum availability *availability,
    4566              :                                  struct symtab_node *ref)
    4567              : {
    4568     33728254 :   cgraph_node *node = ultimate_alias_target (availability, ref);
    4569              : 
    4570     67457572 :   while (node->thunk && !thunk_info::get (node)->virtual_offset_p)
    4571              :     {
    4572         1064 :       enum availability a;
    4573              : 
    4574         1064 :       ref = node;
    4575         1064 :       node = node->callees->callee;
    4576         1064 :       node = node->ultimate_alias_target (availability ? &a : NULL, ref);
    4577         1064 :       if (availability && a < *availability)
    4578          296 :         *availability = a;
    4579              :     }
    4580     33728254 :   return node;
    4581              : }
    4582              : 
    4583              : /* When doing LTO, read cgraph_node's body from disk if it is not already
    4584              :    present.  Also perform any necessary clone materializations.  */
    4585              : 
    4586              : bool
    4587      6178600 : cgraph_node::get_untransformed_body ()
    4588              : {
    4589      6178600 :   lto_file_decl_data *file_data;
    4590      6178600 :   const char *data, *name;
    4591      6178600 :   size_t len;
    4592      6178600 :   tree decl = this->decl;
    4593              : 
    4594              :   /* See if there is clone to be materialized.
    4595              :      (inline clones does not need materialization, but we can be seeing
    4596              :       an inline clone of real clone).  */
    4597      6178600 :   cgraph_node *p = this;
    4598      8882980 :   for (cgraph_node *c = clone_of; c; c = c->clone_of)
    4599              :     {
    4600      2704380 :       if (c->decl != decl)
    4601       132186 :         p->materialize_clone ();
    4602      2704380 :       p = c;
    4603              :     }
    4604              : 
    4605              :   /* Check if body is already there.  Either we have gimple body or
    4606              :      the function is thunk and in that case we set DECL_ARGUMENTS.  */
    4607      6178600 :   if (DECL_ARGUMENTS (decl) || gimple_has_body_p (decl))
    4608      6094693 :     return false;
    4609              : 
    4610       167814 :   gcc_assert (in_lto_p && !DECL_RESULT (decl));
    4611              : 
    4612        83907 :   timevar_push (TV_IPA_LTO_GIMPLE_IN);
    4613              : 
    4614        83907 :   file_data = lto_file_data;
    4615        83907 :   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    4616              : 
    4617              :   /* We may have renamed the declaration, e.g., a static function.  */
    4618        83907 :   name = lto_get_decl_name_mapping (file_data, name);
    4619        83907 :   struct lto_in_decl_state *decl_state
    4620        83907 :          = lto_get_function_in_decl_state (file_data, decl);
    4621              : 
    4622        83907 :   cgraph_node *origin = this;
    4623       168011 :   while (origin->clone_of)
    4624              :     origin = origin->clone_of;
    4625              : 
    4626        83907 :   int stream_order = origin->order - file_data->order_base;
    4627       167814 :   data = lto_get_section_data (file_data, LTO_section_function_body,
    4628              :                                name, stream_order, &len,
    4629        83907 :                                decl_state->compressed);
    4630        83907 :   if (!data)
    4631            0 :     fatal_error (input_location, "%s: section %s.%d is missing",
    4632              :                  file_data->file_name, name, stream_order);
    4633              : 
    4634        83907 :   gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
    4635              : 
    4636        83907 :   if (!quiet_flag)
    4637            0 :     fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
    4638        83907 :   lto_input_function_body (file_data, this, data);
    4639        83907 :   lto_stats.num_function_bodies++;
    4640        83907 :   lto_free_section_data (file_data, LTO_section_function_body, name,
    4641        83907 :                          data, len, decl_state->compressed);
    4642        83907 :   lto_free_function_in_decl_state_for_node (this);
    4643              :   /* Keep lto file data so ipa-inline-analysis knows about cross module
    4644              :      inlining.  */
    4645              : 
    4646        83907 :   timevar_pop (TV_IPA_LTO_GIMPLE_IN);
    4647              : 
    4648        83907 :   return true;
    4649              : }
    4650              : 
    4651              : /* Prepare function body.  When doing LTO, read cgraph_node's body from disk
    4652              :    if it is not already present.  When some IPA transformations are scheduled,
    4653              :    apply them.  */
    4654              : 
    4655              : bool
    4656        28883 : cgraph_node::get_body (void)
    4657              : {
    4658        28883 :   bool updated;
    4659              : 
    4660        28883 :   updated = get_untransformed_body ();
    4661              : 
    4662              :   /* Getting transformed body makes no sense for inline clones;
    4663              :      we should never use this on real clones because they are materialized
    4664              :      early.
    4665              :      TODO: Materializing clones here will likely lead to smaller LTRANS
    4666              :      footprint. */
    4667        28883 :   gcc_assert (!inlined_to && !clone_of);
    4668        28883 :   if (ipa_transforms_to_apply.exists ())
    4669              :     {
    4670        12387 :       opt_pass *saved_current_pass = current_pass;
    4671        12387 :       FILE *saved_dump_file = dump_file;
    4672        12387 :       const char *saved_dump_file_name = dump_file_name;
    4673        12387 :       dump_flags_t saved_dump_flags = dump_flags;
    4674        12387 :       dump_file_name = NULL;
    4675        12387 :       set_dump_file (NULL);
    4676              : 
    4677        12387 :       push_cfun (DECL_STRUCT_FUNCTION (decl));
    4678              : 
    4679        12387 :       update_ssa (TODO_update_ssa_only_virtuals);
    4680        12387 :       execute_all_ipa_transforms (true);
    4681        12387 :       cgraph_edge::rebuild_edges ();
    4682        12387 :       free_dominance_info (CDI_DOMINATORS);
    4683        12387 :       free_dominance_info (CDI_POST_DOMINATORS);
    4684        12387 :       pop_cfun ();
    4685        12387 :       updated = true;
    4686              : 
    4687        12387 :       current_pass = saved_current_pass;
    4688        12387 :       set_dump_file (saved_dump_file);
    4689        12387 :       dump_file_name = saved_dump_file_name;
    4690        12387 :       dump_flags = saved_dump_flags;
    4691              :     }
    4692        28883 :   return updated;
    4693              : }
    4694              : 
    4695              : /* Return the DECL_STRUCT_FUNCTION of the function.  */
    4696              : 
    4697              : struct function *
    4698       102419 : cgraph_node::get_fun () const
    4699              : {
    4700       102419 :   const cgraph_node *node = this;
    4701       102419 :   struct function *fun = DECL_STRUCT_FUNCTION (node->decl);
    4702              : 
    4703       102419 :   while (!fun && node->clone_of)
    4704              :     {
    4705            0 :       node = node->clone_of;
    4706            0 :       fun = DECL_STRUCT_FUNCTION (node->decl);
    4707              :     }
    4708              : 
    4709       102419 :   return fun;
    4710              : }
    4711              : 
    4712              : /* Reset all state within cgraph.cc so that we can rerun the compiler
    4713              :    within the same process.  For use by toplev::finalize.  */
    4714              : 
    4715              : void
    4716       259496 : cgraph_cc_finalize (void)
    4717              : {
    4718       259496 :   nested_function_info::release ();
    4719       259496 :   thunk_info::release ();
    4720       259496 :   clone_info::release ();
    4721       259496 :   symtab = NULL;
    4722              : 
    4723       259496 :   x_cgraph_nodes_queue = NULL;
    4724              : 
    4725       259496 :   cgraph_fnver_htab = NULL;
    4726       259496 :   version_info_node = NULL;
    4727       259496 : }
    4728              : 
    4729              : /* A worker for call_for_symbol_and_aliases.  */
    4730              : 
    4731              : bool
    4732       729712 : cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
    4733              :                                                               void *),
    4734              :                                             void *data,
    4735              :                                             bool include_overwritable)
    4736              : {
    4737       729712 :   ipa_ref *ref;
    4738      1436526 :   FOR_EACH_ALIAS (this, ref)
    4739              :     {
    4740       811034 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    4741       811034 :       if (include_overwritable
    4742       811034 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
    4743       811034 :         if (alias->call_for_symbol_and_aliases (callback, data,
    4744              :                                                 include_overwritable))
    4745              :           return true;
    4746              :     }
    4747              :   return false;
    4748              : }
    4749              : 
    4750              : /* Return true if NODE has thunk.  */
    4751              : 
    4752              : bool
    4753        39112 : cgraph_node::has_thunk_p (cgraph_node *node, void *)
    4754              : {
    4755        73580 :   for (cgraph_edge *e = node->callers; e; e = e->next_caller)
    4756        34468 :     if (e->caller->thunk)
    4757              :       return true;
    4758              :   return false;
    4759              : }
    4760              : 
    4761              : /* Expected frequency of executions within the function.  */
    4762              : 
    4763              : sreal
    4764    225000397 : cgraph_edge::sreal_frequency ()
    4765              : {
    4766    225000397 :   return count.to_sreal_scale (caller->inlined_to
    4767    225000397 :                                ? caller->inlined_to->count
    4768    225000397 :                                : caller->count);
    4769              : }
    4770              : 
    4771              : /* Expected frequency of executions within the function.
    4772              :    If edge is speculative, sum all its indirect targets.  */
    4773              : 
    4774              : sreal
    4775         3993 : cgraph_edge::combined_sreal_frequency ()
    4776              : {
    4777         3993 :   if (!speculative)
    4778         3724 :     return sreal_frequency ();
    4779          269 :   cgraph_edge *e = this;
    4780          269 :   if (e->callee)
    4781            0 :     e = e->speculative_call_indirect_edge ();
    4782          269 :   sreal sum = e->sreal_frequency ();
    4783          269 :   for (e = e->first_speculative_call_target ();
    4784          624 :        e;
    4785          355 :        e = e->next_speculative_call_target ())
    4786          355 :     sum += e->sreal_frequency ();
    4787          269 :   return sum;
    4788              : }
    4789              : 
    4790              : 
    4791              : /* During LTO stream in this can be used to check whether call can possibly
    4792              :    be internal to the current translation unit.  */
    4793              : 
    4794              : bool
    4795       480105 : cgraph_edge::possibly_call_in_translation_unit_p (void)
    4796              : {
    4797       480105 :   gcc_checking_assert (in_lto_p && caller->prevailing_p ());
    4798              : 
    4799              :   /* While incremental linking we may end up getting function body later.  */
    4800       480105 :   if (flag_incremental_link == INCREMENTAL_LINK_LTO)
    4801              :     return true;
    4802              : 
    4803              :   /* We may be smarter here and avoid streaming in indirect calls we can't
    4804              :      track, but that would require arranging streaming the indirect call
    4805              :      summary first.  */
    4806       479878 :   if (!callee)
    4807              :     return true;
    4808              : 
    4809              :   /* If callee is local to the original translation unit, it will be
    4810              :      defined.  */
    4811       477130 :   if (!TREE_PUBLIC (callee->decl) && !DECL_EXTERNAL (callee->decl))
    4812              :     return true;
    4813              : 
    4814              :   /* Otherwise we need to lookup prevailing symbol (symbol table is not merged,
    4815              :      yet) and see if it is a definition.  In fact we may also resolve aliases,
    4816              :      but that is probably not too important.  */
    4817       480980 :   symtab_node *node = callee;
    4818       480980 :   for (int n = 10; node->previous_sharing_asm_name && n ; n--)
    4819        10111 :     node = node->previous_sharing_asm_name;
    4820       470869 :   if (node->previous_sharing_asm_name)
    4821          234 :     node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (callee->decl));
    4822       470869 :   gcc_assert (TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
    4823       470869 :   return node->get_availability () >= AVAIL_INTERPOSABLE;
    4824              : }
    4825              : 
    4826              : /* Return num_speculative_targets of this edge.  */
    4827              : 
    4828              : int
    4829       187921 : cgraph_edge::num_speculative_call_targets_p (void)
    4830              : {
    4831       187921 :   return indirect_info ? indirect_info->num_speculative_call_targets : 0;
    4832              : }
    4833              : 
    4834              : /* Check if function calls comdat local.  This is used to recompute
    4835              :    calls_comdat_local flag after function transformations.  */
    4836              : bool
    4837     48775602 : cgraph_node::check_calls_comdat_local_p ()
    4838              : {
    4839    157181854 :   for (cgraph_edge *e = callees; e; e = e->next_callee)
    4840      3660918 :     if (e->inline_failed
    4841    116895777 :         ? e->callee->comdat_local_p ()
    4842      3660918 :         : e->callee->check_calls_comdat_local_p ())
    4843        50592 :       return true;
    4844              :   return false;
    4845              : }
    4846              : 
    4847              : /* Return true if this node represents a former, i.e. an expanded, thunk.  */
    4848              : 
    4849              : bool
    4850      5049711 : cgraph_node::former_thunk_p (void)
    4851              : {
    4852      5049711 :   if (thunk)
    4853              :     return false;
    4854      5049711 :   thunk_info *i = thunk_info::get (this);
    4855      5049711 :   if (!i)
    4856              :     return false;
    4857           67 :   gcc_checking_assert (i->fixed_offset || i->virtual_offset_p
    4858              :                        || i->indirect_offset);
    4859              :   return true;
    4860              : }
    4861              : 
    4862              : /* A stashed copy of "symtab" for use by selftest::symbol_table_test.
    4863              :    This needs to be a global so that it can be a GC root, and thus
    4864              :    prevent the stashed copy from being garbage-collected if the GC runs
    4865              :    during a symbol_table_test.  */
    4866              : 
    4867              : symbol_table *saved_symtab;
    4868              : 
    4869              : #if CHECKING_P
    4870              : 
    4871              : namespace selftest {
    4872              : 
    4873              : /* class selftest::symbol_table_test.  */
    4874              : 
    4875              : /* Constructor.  Store the old value of symtab, and create a new one.  */
    4876              : 
    4877           64 : symbol_table_test::symbol_table_test ()
    4878              : {
    4879           64 :   gcc_assert (saved_symtab == NULL);
    4880           64 :   saved_symtab = symtab;
    4881           64 :   symtab = new (ggc_alloc<symbol_table> ()) symbol_table ();
    4882           64 : }
    4883              : 
    4884              : /* Destructor.  Restore the old value of symtab.  */
    4885              : 
    4886           64 : symbol_table_test::~symbol_table_test ()
    4887              : {
    4888           64 :   gcc_assert (saved_symtab != NULL);
    4889           64 :   symtab = saved_symtab;
    4890           64 :   saved_symtab = NULL;
    4891           64 : }
    4892              : 
    4893              : /* Verify that symbol_table_test works.  */
    4894              : 
    4895              : static void
    4896            4 : test_symbol_table_test ()
    4897              : {
    4898              :   /* Simulate running two selftests involving symbol tables.  */
    4899           12 :   for (int i = 0; i < 2; i++)
    4900              :     {
    4901            8 :       symbol_table_test stt;
    4902            8 :       tree test_decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
    4903              :                                    get_identifier ("test_decl"),
    4904              :                                    build_function_type_list (void_type_node,
    4905              :                                                              NULL_TREE));
    4906            8 :       cgraph_node *node = cgraph_node::get_create (test_decl);
    4907            8 :       gcc_assert (node);
    4908              : 
    4909              :       /* Verify that the node has order 0 on both iterations,
    4910              :          and thus that nodes have predictable dump names in selftests.  */
    4911            8 :       ASSERT_EQ (node->order, 0);
    4912            8 :       ASSERT_STREQ (node->dump_name (), "test_decl/1");
    4913            8 :     }
    4914            4 : }
    4915              : 
    4916              : /* Run all of the selftests within this file.  */
    4917              : 
    4918              : void
    4919            4 : cgraph_cc_tests ()
    4920              : {
    4921            4 :   test_symbol_table_test ();
    4922            4 : }
    4923              : 
    4924              : } // namespace selftest
    4925              : 
    4926              : #endif /* CHECKING_P */
    4927              : 
    4928              : #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.