LCOV - code coverage report
Current view: top level - gcc - cgraphunit.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.7 % 1215 1126
Test Date: 2026-09-19 16:22:48 Functions: 100.0 % 41 41
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Driver of optimization process
       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 module implements main driver of compilation process.
      22              : 
      23              :    The main scope of this file is to act as an interface in between
      24              :    tree based frontends and the backend.
      25              : 
      26              :    The front-end is supposed to use following functionality:
      27              : 
      28              :     - finalize_function
      29              : 
      30              :       This function is called once front-end has parsed whole body of function
      31              :       and it is certain that the function body nor the declaration will change.
      32              : 
      33              :       (There is one exception needed for implementing GCC extern inline
      34              :         function.)
      35              : 
      36              :     - varpool_finalize_decl
      37              : 
      38              :       This function has same behavior as the above but is used for static
      39              :       variables.
      40              : 
      41              :     - add_asm_node
      42              : 
      43              :       Insert new toplevel ASM statement
      44              : 
      45              :     - finalize_compilation_unit
      46              : 
      47              :       This function is called once (source level) compilation unit is finalized
      48              :       and it will no longer change.
      49              : 
      50              :       The symbol table is constructed starting from the trivially needed
      51              :       symbols finalized by the frontend.  Functions are lowered into
      52              :       GIMPLE representation and callgraph/reference lists are constructed.
      53              :       Those are used to discover other necessary functions and variables.
      54              : 
      55              :       At the end the bodies of unreachable functions are removed.
      56              : 
      57              :       The function can be called multiple times when multiple source level
      58              :       compilation units are combined.
      59              : 
      60              :     - compile
      61              : 
      62              :       This passes control to the back-end.  Optimizations are performed and
      63              :       final assembler is generated.  This is done in the following way. Note
      64              :       that with link time optimization the process is split into three
      65              :       stages (compile time, linktime analysis and parallel linktime as
      66              :       indicated below).
      67              : 
      68              :       Compile time:
      69              : 
      70              :         1) Inter-procedural optimization.
      71              :            (ipa_passes)
      72              : 
      73              :            This part is further split into:
      74              : 
      75              :            a) early optimizations. These are local passes executed in
      76              :               the topological order on the callgraph.
      77              : 
      78              :               The purpose of early optimizations is to optimize away simple
      79              :               things that may otherwise confuse IP analysis. Very simple
      80              :               propagation across the callgraph is done i.e. to discover
      81              :               functions without side effects and simple inlining is performed.
      82              : 
      83              :            b) early small interprocedural passes.
      84              : 
      85              :               Those are interprocedural passes executed only at compilation
      86              :               time.  These include, for example, transactional memory lowering,
      87              :               unreachable code removal and other simple transformations.
      88              : 
      89              :            c) IP analysis stage.  All interprocedural passes do their
      90              :               analysis.
      91              : 
      92              :               Interprocedural passes differ from small interprocedural
      93              :               passes by their ability to operate across whole program
      94              :               at linktime.  Their analysis stage is performed early to
      95              :               both reduce linking times and linktime memory usage by
      96              :               not having to represent whole program in memory.
      97              : 
      98              :            d) LTO streaming.  When doing LTO, everything important gets
      99              :               streamed into the object file.
     100              : 
     101              :        Compile time and or linktime analysis stage (WPA):
     102              : 
     103              :               At linktime units gets streamed back and symbol table is
     104              :               merged.  Function bodies are not streamed in and not
     105              :               available.
     106              :            e) IP propagation stage.  All IP passes execute their
     107              :               IP propagation. This is done based on the earlier analysis
     108              :               without having function bodies at hand.
     109              :            f) Ltrans streaming.  When doing WHOPR LTO, the program
     110              :               is partitioned and streamed into multiple object files.
     111              : 
     112              :        Compile time and/or parallel linktime stage (ltrans)
     113              : 
     114              :               Each of the object files is streamed back and compiled
     115              :               separately.  Now the function bodies becomes available
     116              :               again.
     117              : 
     118              :          2) Virtual clone materialization
     119              :             (cgraph_materialize_clone)
     120              : 
     121              :             IP passes can produce copies of existing functions (such
     122              :             as versioned clones or inline clones) without actually
     123              :             manipulating their bodies by creating virtual clones in
     124              :             the callgraph. At this time the virtual clones are
     125              :             turned into real functions
     126              :          3) IP transformation
     127              : 
     128              :             All IP passes transform function bodies based on earlier
     129              :             decision of the IP propagation.
     130              : 
     131              :          4) late small IP passes
     132              : 
     133              :             Simple IP passes working within single program partition.
     134              : 
     135              :          5) Expansion
     136              :             (expand_all_functions)
     137              : 
     138              :             At this stage functions that needs to be output into
     139              :             assembler are identified and compiled in topological order
     140              :          6) Output of variables and aliases
     141              :             Now it is known what variable references was not optimized
     142              :             out and thus all variables are output to the file.
     143              : 
     144              :             Note that with -fno-toplevel-reorder passes 5 and 6
     145              :             are combined together in cgraph_output_in_order.
     146              : 
     147              :    Finally there are functions to manipulate the callgraph from
     148              :    backend.
     149              :     - cgraph_add_new_function is used to add backend produced
     150              :       functions introduced after the unit is finalized.
     151              :       The functions are enqueue for later processing and inserted
     152              :       into callgraph with cgraph_process_new_functions.
     153              : 
     154              :     - cgraph_function_versioning
     155              : 
     156              :       produces a copy of function into new one (a version)
     157              :       and apply simple transformations
     158              : */
     159              : 
     160              : #include "config.h"
     161              : #include "system.h"
     162              : #include "coretypes.h"
     163              : #include "backend.h"
     164              : #include "target.h"
     165              : #include "rtl.h"
     166              : #include "tree.h"
     167              : #include "gimple.h"
     168              : #include "cfghooks.h"
     169              : #include "regset.h"     /* FIXME: For reg_obstack.  */
     170              : #include "alloc-pool.h"
     171              : #include "tree-pass.h"
     172              : #include "stringpool.h"
     173              : #include "gimple-ssa.h"
     174              : #include "cgraph.h"
     175              : #include "coverage.h"
     176              : #include "lto-streamer.h"
     177              : #include "fold-const.h"
     178              : #include "varasm.h"
     179              : #include "stor-layout.h"
     180              : #include "output.h"
     181              : #include "cfgcleanup.h"
     182              : #include "gimple-iterator.h"
     183              : #include "gimple-fold.h"
     184              : #include "gimplify.h"
     185              : #include "gimplify-me.h"
     186              : #include "tree-cfg.h"
     187              : #include "tree-into-ssa.h"
     188              : #include "tree-ssa.h"
     189              : #include "langhooks.h"
     190              : #include "toplev.h"
     191              : #include "debug.h"
     192              : #include "symbol-summary.h"
     193              : #include "tree-vrp.h"
     194              : #include "sreal.h"
     195              : #include "ipa-cp.h"
     196              : #include "ipa-prop.h"
     197              : #include "gimple-pretty-print.h"
     198              : #include "plugin.h"
     199              : #include "ipa-fnsummary.h"
     200              : #include "ipa-utils.h"
     201              : #include "except.h"
     202              : #include "cfgloop.h"
     203              : #include "context.h"
     204              : #include "pass_manager.h"
     205              : #include "tree-nested.h"
     206              : #include "dbgcnt.h"
     207              : #include "lto-section-names.h"
     208              : #include "attribs.h"
     209              : #include "ipa-inline.h"
     210              : #include "omp-offload.h"
     211              : #include "symtab-thunks.h"
     212              : 
     213              : /* Queue of cgraph nodes scheduled to be added into cgraph.  This is a
     214              :    secondary queue used during optimization to accommodate passes that
     215              :    may generate new functions that need to be optimized and expanded.  */
     216              : vec<cgraph_node *> cgraph_new_nodes;
     217              : 
     218              : static void expand_all_functions (void);
     219              : static void mark_functions_to_output (void);
     220              : static void handle_alias_pairs (void);
     221              : 
     222              : /* Return true if this symbol is a function from the C frontend specified
     223              :    directly in RTL form (with "__RTL").  */
     224              : 
     225              : bool
     226    246001387 : symtab_node::native_rtl_p () const
     227              : {
     228    246001387 :   if (TREE_CODE (decl) != FUNCTION_DECL)
     229              :     return false;
     230    205832543 :   if (!DECL_STRUCT_FUNCTION (decl))
     231              :     return false;
     232    203856436 :   return DECL_STRUCT_FUNCTION (decl)->curr_properties & PROP_rtl;
     233              : }
     234              : 
     235              : /* Determine if symbol declaration is needed.  That is, visible to something
     236              :    either outside this translation unit, something magic in the system
     237              :    configury */
     238              : bool
     239    149938783 : symtab_node::needed_p (void)
     240              : {
     241              :   /* Double check that no one output the function into assembly file
     242              :      early.  */
     243    149938783 :   if (!native_rtl_p ())
     244    149938760 :       gcc_checking_assert
     245              :         (!DECL_ASSEMBLER_NAME_SET_P (decl)
     246              :          || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
     247              : 
     248    149938783 :   if (!definition)
     249              :     return false;
     250              : 
     251    136371797 :   if (DECL_EXTERNAL (decl))
     252              :     return false;
     253              : 
     254              :   /* If the user told us it is used, then it must be so.  */
     255     76766701 :   if (force_output)
     256              :     return true;
     257     75813595 :   if (ref_by_asm)
     258              :     return true;
     259              : 
     260              :   /* ABI forced symbols are needed when they are external.  */
     261     75813593 :   if (forced_by_abi && TREE_PUBLIC (decl))
     262              :     return true;
     263              : 
     264              :   /* Keep constructors, destructors and virtual functions.  */
     265     75777880 :    if (TREE_CODE (decl) == FUNCTION_DECL
     266     75777880 :        && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
     267              :     return true;
     268              : 
     269              :   /* Externally visible variables must be output.  The exception is
     270              :      COMDAT variables that must be output only when they are needed.  */
     271     75767335 :   if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
     272      1919547 :     return true;
     273              : 
     274              :   return false;
     275              : }
     276              : 
     277              : /* Head and terminator of the queue of nodes to be processed while building
     278              :    callgraph.  */
     279              : 
     280              : static symtab_node symtab_terminator (SYMTAB_SYMBOL);
     281              : static symtab_node *queued_nodes = &symtab_terminator;
     282              : 
     283              : /* Add NODE to queue starting at QUEUED_NODES.
     284              :    The queue is linked via AUX pointers and terminated by pointer to 1.  */
     285              : 
     286              : static void
     287     17028658 : enqueue_node (symtab_node *node)
     288              : {
     289     17028658 :   if (node->aux)
     290              :     return;
     291      6498211 :   gcc_checking_assert (queued_nodes);
     292      6498211 :   node->aux = queued_nodes;
     293      6498211 :   queued_nodes = node;
     294              : }
     295              : 
     296              : /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
     297              :    functions into callgraph in a way so they look like ordinary reachable
     298              :    functions inserted into callgraph already at construction time.  */
     299              : 
     300              : void
     301     22078442 : symbol_table::process_new_functions (void)
     302              : {
     303     22078442 :   tree fndecl;
     304              : 
     305     22078442 :   if (!cgraph_new_nodes.exists ())
     306              :     return;
     307              : 
     308        19938 :   handle_alias_pairs ();
     309              :   /*  Note that this queue may grow as its being processed, as the new
     310              :       functions may generate new ones.  */
     311        85617 :   for (unsigned i = 0; i < cgraph_new_nodes.length (); i++)
     312              :     {
     313        45741 :       cgraph_node *node = cgraph_new_nodes[i];
     314        45741 :       fndecl = node->decl;
     315        45741 :       bitmap_obstack_initialize (NULL);
     316        45741 :       switch (state)
     317              :         {
     318        44551 :         case CONSTRUCTION:
     319              :           /* At construction time we just need to finalize function and move
     320              :              it into reachable functions list.  */
     321              : 
     322        44551 :           cgraph_node::finalize_function (fndecl, false);
     323        44551 :           call_cgraph_insertion_hooks (node);
     324        44551 :           enqueue_node (node);
     325        44551 :           break;
     326              : 
     327          997 :         case IPA:
     328          997 :         case IPA_SSA:
     329          997 :         case IPA_SSA_AFTER_INLINING:
     330              :           /* When IPA optimization already started, do all essential
     331              :              transformations that has been already performed on the whole
     332              :              cgraph but not on this function.  */
     333              : 
     334          997 :           gimple_register_cfg_hooks ();
     335          997 :           if (!node->analyzed)
     336          997 :             node->analyze ();
     337          997 :           push_cfun (DECL_STRUCT_FUNCTION (fndecl));
     338          997 :           if ((state == IPA_SSA || state == IPA_SSA_AFTER_INLINING)
     339         1994 :               && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
     340              :             {
     341          997 :               bool summaried_computed = ipa_fn_summaries != NULL;
     342          997 :               g->get_passes ()->execute_early_local_passes ();
     343              :               /* Early passes compute inline parameters to do inlining
     344              :                  and splitting.  This is redundant for functions added late.
     345              :                  Just throw away whatever it did.  */
     346          997 :               if (!summaried_computed)
     347              :                 {
     348          900 :                   ipa_free_fn_summary ();
     349          900 :                   ipa_free_size_summary ();
     350              :                 }
     351              :             }
     352            0 :           else if (ipa_fn_summaries != NULL)
     353            0 :             compute_fn_summary (node, true);
     354          997 :           free_dominance_info (CDI_POST_DOMINATORS);
     355          997 :           free_dominance_info (CDI_DOMINATORS);
     356          997 :           pop_cfun ();
     357          997 :           call_cgraph_insertion_hooks (node);
     358          997 :           break;
     359              : 
     360          193 :         case EXPANSION:
     361              :           /* Functions created during expansion shall be compiled
     362              :              directly.  */
     363          193 :           node->process = 0;
     364          193 :           call_cgraph_insertion_hooks (node);
     365          193 :           node->expand ();
     366          193 :           break;
     367              : 
     368            0 :         default:
     369            0 :           gcc_unreachable ();
     370        45741 :           break;
     371              :         }
     372        45741 :       bitmap_obstack_release (NULL);
     373              :     }
     374              : 
     375        19938 :   cgraph_new_nodes.release ();
     376              : }
     377              : 
     378              : /* As an GCC extension we allow redefinition of the function.  The
     379              :    semantics when both copies of bodies differ is not well defined.
     380              :    We replace the old body with new body so in unit at a time mode
     381              :    we always use new body, while in normal mode we may end up with
     382              :    old body inlined into some functions and new body expanded and
     383              :    inlined in others.
     384              : 
     385              :    ??? It may make more sense to use one body for inlining and other
     386              :    body for expanding the function but this is difficult to do.
     387              : 
     388              :    This is also used to cancel C++ mangling aliases, which can be for
     389              :    functions or variables.  */
     390              : 
     391              : void
     392        37834 : symtab_node::reset (bool preserve_comdat_group)
     393              : {
     394              :   /* Reset our data structures so we can analyze the function again.  */
     395        37834 :   analyzed = false;
     396        37834 :   definition = false;
     397        37834 :   alias = false;
     398        37834 :   transparent_alias = false;
     399        37834 :   weakref = false;
     400        37834 :   cpp_implicit_alias = false;
     401              : 
     402        37834 :   remove_all_references ();
     403        37834 :   if (!preserve_comdat_group)
     404        37357 :     remove_from_same_comdat_group ();
     405              : 
     406        37834 :   if (cgraph_node *cn = dyn_cast <cgraph_node *> (this))
     407              :     {
     408              :       /* If process is set, then we have already begun whole-unit analysis.
     409              :          This is *not* testing for whether we've already emitted the function.
     410              :          That case can be sort-of legitimately seen with real function
     411              :          redefinition errors.  I would argue that the front end should never
     412              :          present us with such a case, but don't enforce that for now.  */
     413        37834 :       gcc_assert (!cn->process);
     414              : 
     415        37834 :       memset (&cn->rtl, 0, sizeof (cn->rtl));
     416        37834 :       cn->inlined_to = NULL;
     417        37834 :       cn->remove_callees ();
     418              :     }
     419        37834 : }
     420              : 
     421              : /* Return true when there are references to the node.  INCLUDE_SELF is
     422              :    true if a self reference counts as a reference.  */
     423              : 
     424              : bool
     425    147224170 : symtab_node::referred_to_p (bool include_self)
     426              : {
     427    147224170 :   ipa_ref *ref = NULL;
     428              : 
     429              :   /* See if there are any references at all.  */
     430    147224170 :   if (iterate_referring (0, ref))
     431              :     return true;
     432              :   /* For functions check also calls.  */
     433    144883860 :   cgraph_node *cn = dyn_cast <cgraph_node *> (this);
     434    108308592 :   if (cn && cn->callers)
     435              :     {
     436      3080103 :       if (include_self)
     437              :         return true;
     438      2066174 :       for (cgraph_edge *e = cn->callers; e; e = e->next_caller)
     439      2065838 :         if (e->caller != this)
     440              :           return true;
     441              :     }
     442              :   return false;
     443              : }
     444              : 
     445              : /* DECL has been parsed.  Take it, queue it, compile it at the whim of the
     446              :    logic in effect.  If NO_COLLECT is true, then our caller cannot stand to have
     447              :    the garbage collector run at the moment.  We would need to either create
     448              :    a new GC context, or just not compile right now.  */
     449              : 
     450              : void
     451     91453009 : cgraph_node::finalize_function (tree decl, bool no_collect)
     452              : {
     453     91453009 :   cgraph_node *node = cgraph_node::get_create (decl);
     454              : 
     455     91453009 :   if (node->definition)
     456              :     {
     457              :       /* Nested functions should only be defined once.  */
     458          150 :       gcc_assert (!DECL_CONTEXT (decl)
     459              :                   || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
     460          150 :       node->reset ();
     461          150 :       node->redefined_extern_inline = true;
     462              :     }
     463              : 
     464              :   /* Set definition first before calling notice_global_symbol so that
     465              :      it is available to notice_global_symbol.  */
     466     91453009 :   node->definition = true;
     467     91453009 :   notice_global_symbol (decl);
     468     91453009 :   node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
     469     91453009 :   node->semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
     470     91453009 :   if (!flag_toplevel_reorder)
     471      4500132 :     node->no_reorder = true;
     472              : 
     473              :   /* With -fkeep-inline-functions we are keeping all inline functions except
     474              :      for extern inline ones.  */
     475     91453009 :   if (flag_keep_inline_functions
     476        25381 :       && DECL_DECLARED_INLINE_P (decl)
     477        25263 :       && !DECL_EXTERNAL (decl)
     478     91455085 :       && !DECL_DISREGARD_INLINE_LIMITS (decl))
     479         1879 :     node->force_output = 1;
     480              : 
     481              :   /* __RTL functions were already output as soon as they were parsed (due
     482              :      to the large amount of global state in the backend).
     483              :      Mark such functions as "force_output" to reflect the fact that they
     484              :      will be in the asm file when considering the symbols they reference.
     485              :      The attempt to output them later on will bail out immediately.  */
     486     91453009 :   if (node->native_rtl_p ())
     487          127 :     node->force_output = 1;
     488              : 
     489              :   /* When not optimizing, also output the static functions. (see
     490              :      PR24561), but don't do so for always_inline functions, functions
     491              :      declared inline and nested functions.  These were optimized out
     492              :      in the original implementation and it is unclear whether we want
     493              :      to change the behavior here.  */
     494    178509557 :   if (((!opt_for_fn (decl, optimize) || flag_keep_static_functions
     495     87056547 :         || node->no_reorder)
     496      4500287 :        && !node->cpp_implicit_alias
     497      4500287 :        && !DECL_DISREGARD_INLINE_LIMITS (decl)
     498      2823680 :        && !DECL_DECLARED_INLINE_P (decl)
     499       511838 :        && !(DECL_CONTEXT (decl)
     500       252556 :             && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
     501     91949587 :       && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
     502       441608 :     node->force_output = 1;
     503              : 
     504              :   /* If we've not yet emitted decl, tell the debug info about it.  */
     505     91453009 :   if (!TREE_ASM_WRITTEN (decl))
     506     91453009 :     (*debug_hooks->deferred_inline_function) (decl);
     507              : 
     508     91453009 :   if (!no_collect)
     509     81164045 :     ggc_collect ();
     510              : 
     511     91453009 :   if (symtab->state == CONSTRUCTION
     512     91453009 :       && (node->needed_p () || node->referred_to_p ()))
     513        44935 :     enqueue_node (node);
     514     91453009 : }
     515              : 
     516              : /* Add the function FNDECL to the call graph.
     517              :    Unlike finalize_function, this function is intended to be used
     518              :    by middle end and allows insertion of new function at arbitrary point
     519              :    of compilation.  The function can be either in high, low or SSA form
     520              :    GIMPLE.
     521              : 
     522              :    The function is assumed to be reachable and have address taken (so no
     523              :    API breaking optimizations are performed on it).
     524              : 
     525              :    Main work done by this function is to enqueue the function for later
     526              :    processing to avoid need the passes to be re-entrant.  */
     527              : 
     528              : void
     529        49720 : cgraph_node::add_new_function (tree fndecl, bool lowered)
     530              : {
     531        49720 :   gcc::pass_manager *passes = g->get_passes ();
     532        49720 :   cgraph_node *node;
     533              : 
     534        49720 :   if (dump_file)
     535              :     {
     536          130 :       struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
     537          130 :       const char *function_type = ((gimple_has_body_p (fndecl))
     538          130 :                                    ? (lowered
     539          130 :                                       ? (gimple_in_ssa_p (fn)
     540              :                                          ? "ssa gimple"
     541              :                                          : "low gimple")
     542              :                                       : "high gimple")
     543          125 :                                    : "to-be-gimplified");
     544          130 :       fprintf (dump_file,
     545              :                "Added new %s function %s to callgraph\n",
     546              :                function_type,
     547              :                fndecl_name (fndecl));
     548              :     }
     549              : 
     550        49720 :   switch (symtab->state)
     551              :     {
     552            0 :       case PARSING:
     553            0 :         cgraph_node::finalize_function (fndecl, false);
     554            0 :         break;
     555        44554 :       case CONSTRUCTION:
     556              :         /* Just enqueue function to be processed at nearest occurrence.  */
     557        44554 :         node = cgraph_node::get_create (fndecl);
     558        44554 :         if (lowered)
     559        43921 :           node->lowered = true;
     560        44554 :         cgraph_new_nodes.safe_push (node);
     561        44554 :         break;
     562              : 
     563         1190 :       case IPA:
     564         1190 :       case IPA_SSA:
     565         1190 :       case IPA_SSA_AFTER_INLINING:
     566         1190 :       case EXPANSION:
     567              :         /* Bring the function into finalized state and enqueue for later
     568              :            analyzing and compilation.  */
     569         1190 :         node = cgraph_node::get_create (fndecl);
     570         1190 :         node->local = false;
     571         1190 :         node->definition = true;
     572         1190 :         node->semantic_interposition = opt_for_fn (fndecl,
     573              :                                                    flag_semantic_interposition);
     574         1190 :         node->force_output = true;
     575         1190 :         if (TREE_PUBLIC (fndecl))
     576           67 :           node->externally_visible = true;
     577         1190 :         if (!lowered && symtab->state == EXPANSION)
     578              :           {
     579            0 :             push_cfun (DECL_STRUCT_FUNCTION (fndecl));
     580            0 :             gimple_register_cfg_hooks ();
     581            0 :             bitmap_obstack_initialize (NULL);
     582            0 :             execute_pass_list (cfun, passes->all_lowering_passes);
     583            0 :             passes->execute_early_local_passes ();
     584            0 :             bitmap_obstack_release (NULL);
     585            0 :             pop_cfun ();
     586              : 
     587            0 :             lowered = true;
     588              :           }
     589            0 :         if (lowered)
     590          282 :           node->lowered = true;
     591         1190 :         cgraph_new_nodes.safe_push (node);
     592         1190 :         break;
     593              : 
     594         3976 :       case FINISHED:
     595              :         /* At the very end of compilation we have to do all the work up
     596              :            to expansion.  */
     597         3976 :         node = cgraph_node::create (fndecl);
     598         3976 :         if (lowered)
     599            0 :           node->lowered = true;
     600         3976 :         node->definition = true;
     601         3976 :         node->semantic_interposition = opt_for_fn (fndecl,
     602              :                                                    flag_semantic_interposition);
     603         3976 :         node->analyze ();
     604         3976 :         push_cfun (DECL_STRUCT_FUNCTION (fndecl));
     605         3976 :         gimple_register_cfg_hooks ();
     606         3976 :         bitmap_obstack_initialize (NULL);
     607         3976 :         if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
     608         3976 :           g->get_passes ()->execute_early_local_passes ();
     609         3976 :         bitmap_obstack_release (NULL);
     610         3976 :         pop_cfun ();
     611         3976 :         node->expand ();
     612         3976 :         break;
     613              : 
     614            0 :       default:
     615            0 :         gcc_unreachable ();
     616              :     }
     617              : 
     618              :   /* Set a personality if required and we already passed EH lowering.  */
     619        49720 :   if (lowered
     620        93923 :       && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
     621              :           == eh_personality_lang))
     622         2052 :     DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
     623        49720 : }
     624              : 
     625              : /* Analyze the function scheduled to be output.  */
     626              : void
     627      3097254 : cgraph_node::analyze (void)
     628              : {
     629      3097254 :   if (native_rtl_p ())
     630              :     {
     631           23 :       analyzed = true;
     632           23 :       return;
     633              :     }
     634              : 
     635      3097231 :   tree decl = this->decl;
     636      3097231 :   location_t saved_loc = input_location;
     637      3097231 :   input_location = DECL_SOURCE_LOCATION (decl);
     638      3097231 :   semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
     639              : 
     640      3097231 :   if (thunk)
     641              :     {
     642         3421 :       thunk_info *info = thunk_info::get (this);
     643         3421 :       cgraph_node *t = cgraph_node::get (info->alias);
     644              : 
     645         3421 :       create_edge (t, NULL, t->count);
     646         3421 :       callees->can_throw_external = !TREE_NOTHROW (t->decl);
     647              :       /* Target code in expand_thunk may need the thunk's target
     648              :          to be analyzed, so recurse here.  */
     649         3421 :       if (!t->analyzed && t->definition)
     650            0 :         t->analyze ();
     651         3421 :       if (t->alias)
     652              :         {
     653         3421 :           t = t->get_alias_target ();
     654         3421 :           if (!t->analyzed && t->definition)
     655         1299 :             t->analyze ();
     656              :         }
     657         3421 :       bool ret = expand_thunk (this, false, false);
     658         3421 :       thunk_info::get (this)->alias = NULL;
     659         3421 :       if (!ret)
     660              :         return;
     661              :     }
     662      3093971 :   if (alias)
     663         5116 :     resolve_alias (cgraph_node::get (alias_target), transparent_alias);
     664      3088855 :   else if (dispatcher_function)
     665              :     {
     666              :       /* Generate the dispatcher body of multi-versioned functions.  */
     667          114 :       cgraph_function_version_info *dispatcher_version_info
     668          114 :         = function_version ();
     669          114 :       if (dispatcher_version_info != NULL
     670          114 :           && (dispatcher_version_info->dispatcher_resolver
     671              :               == NULL_TREE))
     672              :         {
     673          114 :           tree resolver = NULL_TREE;
     674          114 :           gcc_assert (targetm.generate_version_dispatcher_body);
     675          114 :           resolver = targetm.generate_version_dispatcher_body (this);
     676          114 :           gcc_assert (resolver != NULL_TREE);
     677              :         }
     678              :     }
     679              :   else
     680              :     {
     681      3088741 :       push_cfun (DECL_STRUCT_FUNCTION (decl));
     682              : 
     683      3088741 :       assign_assembler_name_if_needed (decl);
     684              : 
     685              :       /* Make sure to gimplify bodies only once.  During analyzing a
     686              :          function we lower it, which will require gimplified nested
     687              :          functions, so we can end up here with an already gimplified
     688              :          body.  */
     689      3088741 :       if (!gimple_has_body_p (decl))
     690      2989699 :         gimplify_function_tree (decl);
     691              : 
     692              :       /* Lower the function.  */
     693      3088741 :       if (!lowered)
     694              :         {
     695      3034604 :           if (first_nested_function (this))
     696         9875 :             lower_nested_functions (decl);
     697              : 
     698      3024729 :           gimple_register_cfg_hooks ();
     699      3024729 :           bitmap_obstack_initialize (NULL);
     700      3024729 :           execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);
     701      3024716 :           compact_blocks ();
     702      3024716 :           bitmap_obstack_release (NULL);
     703      3024716 :           lowered = true;
     704              :         }
     705              : 
     706      3088728 :       pop_cfun ();
     707              :     }
     708      3093958 :   analyzed = true;
     709              : 
     710      3093958 :   input_location = saved_loc;
     711              : }
     712              : 
     713              : /* C++ frontend produce same body aliases all over the place, even before PCH
     714              :    gets streamed out. It relies on us linking the aliases with their function
     715              :    in order to do the fixups, but ipa-ref is not PCH safe.  Consequently we
     716              :    first produce aliases without links, but once C++ FE is sure he won't stream
     717              :    PCH we build the links via this function.  */
     718              : 
     719              : void
     720       206355 : symbol_table::process_same_body_aliases (void)
     721              : {
     722       206355 :   symtab_node *node;
     723    102481736 :   FOR_EACH_SYMBOL (node)
     724    102275381 :     if (node->cpp_implicit_alias && !node->analyzed)
     725      4436291 :       node->resolve_alias
     726      8872582 :         (VAR_P (node->alias_target)
     727            0 :          ? (symtab_node *)varpool_node::get_create (node->alias_target)
     728      4436291 :          : (symtab_node *)cgraph_node::get_create (node->alias_target));
     729       206355 :   cpp_implicit_aliases_done = true;
     730       206355 : }
     731              : 
     732              : /* Process a symver attribute.  */
     733              : 
     734              : static void
     735    147511498 : process_symver_attribute (symtab_node *n)
     736              : {
     737    147511498 :   tree value = lookup_attribute ("symver", DECL_ATTRIBUTES (n->decl));
     738              : 
     739    295022998 :   for (; value != NULL; value = TREE_CHAIN (value))
     740              :     {
     741              :       /* Starting from binutils 2.35 gas supports:
     742              :           # Assign foo to bar@V1 and baz@V2.
     743              :           .symver foo, bar@V1
     744              :           .symver foo, baz@V2
     745              :       */
     746            2 :       const char *purpose = IDENTIFIER_POINTER (TREE_PURPOSE (value));
     747            2 :       if (strcmp (purpose, "symver") != 0)
     748            0 :         continue;
     749              : 
     750            2 :       tree symver = get_identifier_with_length
     751            4 :         (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (value))),
     752            2 :          TREE_STRING_LENGTH (TREE_VALUE (TREE_VALUE (value))));
     753            2 :       symtab_node *def = symtab_node::get_for_asmname (symver);
     754              : 
     755            2 :       if (def)
     756              :         {
     757            0 :           error_at (DECL_SOURCE_LOCATION (n->decl),
     758              :                     "duplicate definition of a symbol version");
     759            0 :           inform (DECL_SOURCE_LOCATION (def->decl),
     760              :                   "same version was previously defined here");
     761            0 :           return;
     762              :         }
     763            2 :       if (!n->definition)
     764              :         {
     765            0 :           error_at (DECL_SOURCE_LOCATION (n->decl),
     766              :                     "symbol needs to be defined to have a version");
     767            0 :           return;
     768              :         }
     769            2 :       if (DECL_COMMON (n->decl))
     770              :         {
     771            0 :           error_at (DECL_SOURCE_LOCATION (n->decl),
     772              :                     "common symbol cannot be versioned");
     773            0 :           return;
     774              :         }
     775            2 :       if (DECL_COMDAT (n->decl))
     776              :         {
     777            0 :           error_at (DECL_SOURCE_LOCATION (n->decl),
     778              :                     "comdat symbol cannot be versioned");
     779            0 :           return;
     780              :         }
     781            2 :       if (n->weakref)
     782              :         {
     783            0 :           error_at (DECL_SOURCE_LOCATION (n->decl),
     784              :                     "%<weakref%> cannot be versioned");
     785            0 :           return;
     786              :         }
     787            2 :       if (!TREE_PUBLIC (n->decl))
     788              :         {
     789            0 :           error_at (DECL_SOURCE_LOCATION (n->decl),
     790              :                     "versioned symbol must be public");
     791            0 :           return;
     792              :         }
     793            2 :       if (DECL_VISIBILITY (n->decl) != VISIBILITY_DEFAULT)
     794              :         {
     795            0 :           error_at (DECL_SOURCE_LOCATION (n->decl),
     796              :                     "versioned symbol must have default visibility");
     797            0 :           return;
     798              :         }
     799              : 
     800              :       /* Create new symbol table entry representing the version.  */
     801            2 :       tree new_decl = copy_node (n->decl);
     802              : 
     803            2 :       DECL_INITIAL (new_decl) = NULL_TREE;
     804            2 :       if (TREE_CODE (new_decl) == FUNCTION_DECL)
     805            2 :         DECL_STRUCT_FUNCTION (new_decl) = NULL;
     806            2 :       SET_DECL_ASSEMBLER_NAME (new_decl, symver);
     807            2 :       TREE_PUBLIC (new_decl) = 1;
     808            2 :       DECL_ATTRIBUTES (new_decl) = NULL;
     809              : 
     810            2 :       symtab_node *symver_node = symtab_node::get_create (new_decl);
     811            2 :       symver_node->alias = true;
     812            2 :       symver_node->definition = true;
     813            2 :       symver_node->symver = true;
     814            2 :       symver_node->create_reference (n, IPA_REF_ALIAS, NULL);
     815            2 :       symver_node->analyzed = true;
     816              :     }
     817              : }
     818              : 
     819              : /* Process attributes common for vars and functions.  */
     820              : 
     821              : static void
     822    147511498 : process_common_attributes (symtab_node *node, tree decl)
     823              : {
     824    147511498 :   tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
     825              : 
     826    147511498 :   if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
     827              :     {
     828            1 :       warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
     829              :                   "%<weakref%> attribute should be accompanied with"
     830              :                   " an %<alias%> attribute");
     831            1 :       DECL_WEAK (decl) = 0;
     832            1 :       DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
     833            1 :                                                  DECL_ATTRIBUTES (decl));
     834              :     }
     835              : 
     836    147511498 :   if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
     837           17 :     node->no_reorder = 1;
     838    147511498 :   process_symver_attribute (node);
     839    147511498 : }
     840              : 
     841              : /* Look for externally_visible and used attributes and mark cgraph nodes
     842              :    accordingly.
     843              : 
     844              :    We cannot mark the nodes at the point the attributes are processed (in
     845              :    handle_*_attribute) because the copy of the declarations available at that
     846              :    point may not be canonical.  For example, in:
     847              : 
     848              :     void f();
     849              :     void f() __attribute__((used));
     850              : 
     851              :    the declaration we see in handle_used_attribute will be the second
     852              :    declaration -- but the front end will subsequently merge that declaration
     853              :    with the original declaration and discard the second declaration.
     854              : 
     855              :    Furthermore, we can't mark these nodes in finalize_function because:
     856              : 
     857              :     void f() {}
     858              :     void f() __attribute__((externally_visible));
     859              : 
     860              :    is valid.
     861              : 
     862              :    So, we walk the nodes at the end of the translation unit, applying the
     863              :    attributes at that point.  */
     864              : 
     865              : static void
     866       775381 : process_function_and_variable_attributes (cgraph_node *first,
     867              :                                           varpool_node *first_var)
     868              : {
     869       775381 :   cgraph_node *node;
     870       775381 :   varpool_node *vnode;
     871              : 
     872    110474484 :   for (node = symtab->first_function (); node != first;
     873    109699103 :        node = symtab->next_function (node))
     874              :     {
     875    109699103 :       tree decl = node->decl;
     876              : 
     877    109699103 :       if (node->alias
     878    109699103 :           && lookup_attribute ("flatten", DECL_ATTRIBUTES (decl)))
     879              :         {
     880            8 :           tree tdecl = node->get_alias_target_tree ();
     881            8 :           if (!tdecl || !DECL_P (tdecl)
     882           16 :               || !lookup_attribute ("flatten", DECL_ATTRIBUTES (tdecl)))
     883            1 :             warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
     884              :                         "%<flatten%> attribute is ignored on aliases");
     885              :         }
     886    109699103 :       if (DECL_PRESERVE_P (decl))
     887         5137 :         node->mark_force_output ();
     888    109693966 :       else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
     889              :         {
     890        41626 :           if (! TREE_PUBLIC (node->decl))
     891            4 :             warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
     892              :                         "%<externally_visible%>"
     893              :                         " attribute have effect only on public objects");
     894              :         }
     895    109699103 :       if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
     896          394 :           && node->definition
     897    109699153 :           && (!node->alias || DECL_INITIAL (decl) != error_mark_node))
     898              :         {
     899              :           /* NODE->DEFINITION && NODE->ALIAS is nonzero for valid weakref
     900              :              function declarations; DECL_INITIAL is non-null for invalid
     901              :              weakref functions that are also defined.  */
     902            3 :           warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
     903              :                       "%<weakref%> attribute ignored"
     904              :                       " because function is defined");
     905            3 :           DECL_WEAK (decl) = 0;
     906            3 :           DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
     907            3 :                                                      DECL_ATTRIBUTES (decl));
     908            3 :           DECL_ATTRIBUTES (decl) = remove_attribute ("alias",
     909            3 :                                                      DECL_ATTRIBUTES (decl));
     910            3 :           node->alias = false;
     911            3 :           node->weakref = false;
     912            3 :           node->transparent_alias = false;
     913              :         }
     914    109699100 :       else if (lookup_attribute ("alias", DECL_ATTRIBUTES (decl))
     915         5491 :           && node->definition
     916    109704238 :           && !node->alias)
     917            1 :         warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
     918              :                     "%<alias%> attribute ignored"
     919              :                     " because function is defined");
     920              : 
     921    109699103 :       if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
     922     45343799 :           && !DECL_DECLARED_INLINE_P (decl)
     923              :           /* redefining extern inline function makes it DECL_UNINLINABLE.  */
     924    109768271 :           && !DECL_UNINLINABLE (decl))
     925        69163 :         warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
     926              :                     "%<always_inline%> function might not be inlinable"
     927              :                     " unless also declared %<inline%>");
     928              : 
     929    109699103 :       process_common_attributes (node, decl);
     930              :     }
     931     38587776 :   for (vnode = symtab->first_variable (); vnode != first_var;
     932     37812395 :        vnode = symtab->next_variable (vnode))
     933              :     {
     934     37812395 :       tree decl = vnode->decl;
     935     37812395 :       if (DECL_EXTERNAL (decl)
     936     37812395 :           && DECL_INITIAL (decl))
     937      2106583 :         varpool_node::finalize_decl (decl);
     938     37812395 :       if (DECL_PRESERVE_P (decl))
     939         3224 :         vnode->force_output = true;
     940     37809171 :       else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
     941              :         {
     942           42 :           if (! TREE_PUBLIC (vnode->decl))
     943            4 :             warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
     944              :                         "%<externally_visible%>"
     945              :                         " attribute have effect only on public objects");
     946              :         }
     947     37812395 :       if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
     948           69 :           && vnode->definition
     949     37812408 :           && DECL_INITIAL (decl))
     950              :         {
     951            1 :           warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
     952              :                       "%<weakref%> attribute ignored"
     953              :                       " because variable is initialized");
     954            1 :           DECL_WEAK (decl) = 0;
     955            1 :           DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
     956            1 :                                                       DECL_ATTRIBUTES (decl));
     957              :         }
     958     37812395 :       process_common_attributes (vnode, decl);
     959              :     }
     960       775381 : }
     961              : 
     962              : /* Mark DECL as finalized.  By finalizing the declaration, frontend instruct the
     963              :    middle end to output the variable to asm file, if needed or externally
     964              :    visible.  */
     965              : 
     966              : void
     967     35445080 : varpool_node::finalize_decl (tree decl)
     968              : {
     969     35445080 :   varpool_node *node = varpool_node::get_create (decl);
     970              : 
     971     35445080 :   gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
     972              : 
     973     35445080 :   if (node->definition)
     974              :     return;
     975              :   /* Set definition first before calling notice_global_symbol so that
     976              :      it is available to notice_global_symbol.  */
     977     35419898 :   node->definition = true;
     978     35419898 :   node->semantic_interposition = flag_semantic_interposition;
     979     35419898 :   notice_global_symbol (decl);
     980     35419898 :   if (!flag_toplevel_reorder)
     981      3450745 :     node->no_reorder = true;
     982     35329327 :   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
     983              :       /* Traditionally we do not eliminate static variables when not
     984              :          optimizing and when not doing toplevel reorder.  */
     985     70745903 :       || (node->no_reorder && !DECL_COMDAT (node->decl)
     986      1091003 :           && !DECL_ARTIFICIAL (node->decl)))
     987       475896 :     node->force_output = true;
     988              : 
     989     35419898 :   if (flag_openmp)
     990              :     {
     991       156170 :       tree attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl));
     992       156170 :       if (attr)
     993              :         {
     994           43 :           tree align = TREE_VALUE (TREE_VALUE (attr));
     995           43 :           if (align)
     996           16 :             SET_DECL_ALIGN (decl, MAX (tree_to_uhwi (align) * BITS_PER_UNIT,
     997              :                                        DECL_ALIGN (decl)));
     998              :         }
     999              :     }
    1000              : 
    1001     35419898 :   if (symtab->state == CONSTRUCTION
    1002     35419898 :       && (node->needed_p () || node->referred_to_p ()))
    1003       247703 :     enqueue_node (node);
    1004     35419898 :   if (symtab->state >= IPA_SSA)
    1005        33259 :     node->analyze ();
    1006              :   /* Some frontends produce various interface variables after compilation
    1007              :      finished.  */
    1008     35419898 :   if (symtab->state == FINISHED
    1009     35415199 :       || (node->no_reorder
    1010      3450083 :           && symtab->state == EXPANSION))
    1011        12769 :     node->assemble_decl ();
    1012              : }
    1013              : 
    1014              : /* EDGE is an polymorphic call.  Mark all possible targets as reachable
    1015              :    and if there is only one target, perform trivial devirtualization.
    1016              :    REACHABLE_CALL_TARGETS collects target lists we already walked to
    1017              :    avoid duplicate work.  */
    1018              : 
    1019              : static void
    1020        18915 : walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
    1021              :                                cgraph_edge *edge)
    1022              : {
    1023        18915 :   unsigned int i;
    1024        18915 :   void *cache_token;
    1025        18915 :   bool final;
    1026        18915 :   vec <cgraph_node *>targets
    1027              :     = possible_polymorphic_call_targets
    1028        18915 :         (edge, &final, &cache_token);
    1029              : 
    1030        18915 :   if (cache_token != NULL && !reachable_call_targets->add (cache_token))
    1031              :     {
    1032        15136 :       if (symtab->dump_file)
    1033           12 :         dump_possible_polymorphic_call_targets
    1034           12 :           (symtab->dump_file, edge);
    1035              : 
    1036        42324 :       for (i = 0; i < targets.length (); i++)
    1037              :         {
    1038              :           /* Do not bother to mark virtual methods in anonymous namespace;
    1039              :              either we will find use of virtual table defining it, or it is
    1040              :              unused.  */
    1041        27188 :           if (targets[i]->definition
    1042        18581 :               && TREE_CODE
    1043              :                   (TREE_TYPE (targets[i]->decl))
    1044              :                    == METHOD_TYPE
    1045        45769 :               && !type_in_anonymous_namespace_p
    1046        18581 :                    (TYPE_METHOD_BASETYPE (TREE_TYPE (targets[i]->decl))))
    1047        17915 :             enqueue_node (targets[i]);
    1048              :         }
    1049              :     }
    1050              : 
    1051              :   /* Very trivial devirtualization; when the type is
    1052              :      final or anonymous (so we know all its derivation)
    1053              :      and there is only one possible virtual call target,
    1054              :      make the edge direct.  */
    1055        18915 :   if (final)
    1056              :     {
    1057           84 :       if (targets.length () <= 1 && dbg_cnt (devirt))
    1058              :         {
    1059            0 :           cgraph_node *target;
    1060            0 :           if (targets.length () == 1)
    1061            0 :             target = targets[0];
    1062              :           else
    1063            0 :             target = cgraph_node::create (builtin_decl_unreachable ());
    1064              : 
    1065            0 :           if (symtab->dump_file)
    1066              :             {
    1067            0 :               fprintf (symtab->dump_file,
    1068              :                        "Devirtualizing call: ");
    1069            0 :               print_gimple_stmt (symtab->dump_file,
    1070            0 :                                  edge->call_stmt, 0,
    1071              :                                  TDF_SLIM);
    1072              :             }
    1073            0 :           if (dump_enabled_p ())
    1074              :             {
    1075            0 :               dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt,
    1076              :                                "devirtualizing call in %s to %s\n",
    1077            0 :                                edge->caller->dump_name (),
    1078              :                                target->dump_name ());
    1079              :             }
    1080              : 
    1081            0 :           edge = cgraph_edge::make_direct (edge, target);
    1082            0 :           gimple *new_call = cgraph_edge::redirect_call_stmt_to_callee (edge);
    1083              : 
    1084            0 :           if (symtab->dump_file)
    1085              :             {
    1086            0 :               fprintf (symtab->dump_file, "Devirtualized as: ");
    1087            0 :               print_gimple_stmt (symtab->dump_file, new_call, 0, TDF_SLIM);
    1088              :             }
    1089              :         }
    1090              :     }
    1091        18915 : }
    1092              : 
    1093              : /* Issue appropriate warnings for the global declaration DECL.  */
    1094              : 
    1095              : static void
    1096    147535372 : check_global_declaration (symtab_node *snode)
    1097              : {
    1098    147535372 :   const char *decl_file;
    1099    147535372 :   tree decl = snode->decl;
    1100              : 
    1101              :   /* Warn about any function declared static but not defined.  We don't
    1102              :      warn about variables, because many programs have static variables
    1103              :      that exist only to get some text into the object file.  */
    1104    147535372 :   if (TREE_CODE (decl) == FUNCTION_DECL
    1105    109722916 :       && DECL_INITIAL (decl) == 0
    1106      1869614 :       && DECL_EXTERNAL (decl)
    1107      1864395 :       && ! DECL_ARTIFICIAL (decl)
    1108    149248092 :       && ! TREE_PUBLIC (decl))
    1109              :     {
    1110          170 :       if (warning_suppressed_p (decl, OPT_Wunused))
    1111              :         ;
    1112          109 :       else if (snode->referred_to_p (/*include_self=*/false))
    1113              :         {
    1114          106 :           if (pedwarn (input_location, 0, "%q+F used but never defined", decl))
    1115           61 :             suppress_warning (decl, OPT_Wunused);
    1116              :         }
    1117            3 :       else if (warning (OPT_Wunused_function,
    1118              :                         "%q+F declared %<static%> but never defined", decl))
    1119            0 :         suppress_warning (decl, OPT_Wunused);
    1120              :     }
    1121              : 
    1122              :   /* Warn about static fns or vars defined but not used.  */
    1123      5090981 :   if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL)
    1124    142926870 :        || (((warn_unused_variable && ! TREE_READONLY (decl))
    1125    142865058 :             || (warn_unused_const_variable > 0 && TREE_READONLY (decl)
    1126         6670 :                 && (warn_unused_const_variable == 2
    1127         6664 :                     || (main_input_filename != NULL
    1128    147541412 :                         && (decl_file = DECL_SOURCE_FILE (decl)) != NULL
    1129         6657 :                         && filename_cmp (main_input_filename,
    1130              :                                          decl_file) == 0))))
    1131        67618 :            && VAR_P (decl)))
    1132      4655662 :       && ! DECL_IN_SYSTEM_HEADER (decl)
    1133       921924 :       && ! snode->referred_to_p (/*include_self=*/false)
    1134              :       /* This TREE_USED check is needed in addition to referred_to_p
    1135              :          above, because the `__unused__' attribute is not being
    1136              :          considered for referred_to_p.  */
    1137       604462 :       && ! TREE_USED (decl)
    1138              :       /* The TREE_USED bit for file-scope decls is kept in the identifier,
    1139              :          to handle multiple external decls in different scopes.  */
    1140       336040 :       && ! (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl)))
    1141       336040 :       && ! DECL_EXTERNAL (decl)
    1142       138496 :       && ! DECL_ARTIFICIAL (decl)
    1143       137730 :       && ! DECL_ABSTRACT_ORIGIN (decl)
    1144       110290 :       && ! TREE_PUBLIC (decl)
    1145              :       /* A volatile variable might be used in some non-obvious way.  */
    1146        18036 :       && (! VAR_P (decl) || ! TREE_THIS_VOLATILE (decl))
    1147              :       /* Global register variables must be declared to reserve them.  */
    1148        18035 :       && ! (VAR_P (decl) && DECL_REGISTER (decl))
    1149              :       /* Global ctors and dtors are called by the runtime.  */
    1150        18035 :       && (TREE_CODE (decl) != FUNCTION_DECL
    1151        17955 :           || (!DECL_STATIC_CONSTRUCTOR (decl)
    1152        17955 :               && !DECL_STATIC_DESTRUCTOR (decl)))
    1153        18035 :       && (! VAR_P (decl) || !warning_suppressed_p (decl, OPT_Wunused_variable))
    1154              :       /* Otherwise, ask the language.  */
    1155    147553394 :       && lang_hooks.decls.warn_unused_global (decl))
    1156          617 :     warning_at (DECL_SOURCE_LOCATION (decl),
    1157          617 :                 (TREE_CODE (decl) == FUNCTION_DECL)
    1158          684 :                 ? OPT_Wunused_function
    1159           67 :                 : (TREE_READONLY (decl)
    1160              :                    ? OPT_Wunused_const_variable_
    1161              :                    : OPT_Wunused_variable),
    1162              :                 "%qD defined but not used", decl);
    1163    147535372 : }
    1164              : 
    1165              : /* Discover all functions and variables that are trivially needed, analyze
    1166              :    them as well as all functions and variables referred by them  */
    1167              : static cgraph_node *first_analyzed;
    1168              : static varpool_node *first_analyzed_var;
    1169              : 
    1170              : /* FIRST_TIME is set to TRUE for the first time we are called for a
    1171              :    translation unit from finalize_compilation_unit() or false
    1172              :    otherwise.  */
    1173              : 
    1174              : static void
    1175       527133 : analyze_functions (bool first_time)
    1176              : {
    1177              :   /* Keep track of already processed nodes when called multiple times for
    1178              :      intermodule optimization.  */
    1179       527133 :   cgraph_node *first_handled = first_analyzed;
    1180       527133 :   varpool_node *first_handled_var = first_analyzed_var;
    1181       527133 :   hash_set<void *> reachable_call_targets;
    1182              : 
    1183       527133 :   symtab_node *node;
    1184       527133 :   symtab_node *next;
    1185       527133 :   int i;
    1186       527133 :   ipa_ref *ref;
    1187       527133 :   bool changed = true;
    1188       527133 :   location_t saved_loc = input_location;
    1189              : 
    1190       527133 :   bitmap_obstack_initialize (NULL);
    1191       527133 :   symtab->state = CONSTRUCTION;
    1192       527133 :   input_location = UNKNOWN_LOCATION;
    1193              : 
    1194       527133 :   thunk_info::process_early_thunks ();
    1195              : 
    1196              :   /* Ugly, but the fixup cannot happen at a time same body alias is created;
    1197              :      C++ FE is confused about the COMDAT groups being right.  */
    1198       527133 :   if (symtab->cpp_implicit_aliases_done)
    1199    149007412 :     FOR_EACH_SYMBOL (node)
    1200    148595229 :       if (node->cpp_implicit_alias)
    1201      8556712 :           node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
    1202       527133 :   build_type_inheritance_graph ();
    1203              : 
    1204       527133 :   if (flag_openmp && first_time)
    1205         9678 :     omp_discover_implicit_declare_target ();
    1206              : 
    1207              :   /* Analysis adds static variables that in turn adds references to new functions.
    1208              :      So we need to iterate the process until it stabilize.  */
    1209      1302501 :   while (changed)
    1210              :     {
    1211       775381 :       changed = false;
    1212       775381 :       process_function_and_variable_attributes (first_analyzed,
    1213              :                                                 first_analyzed_var);
    1214              : 
    1215              :       /* First identify the trivially needed symbols.  */
    1216       775381 :       for (node = symtab->first_symbol ();
    1217    148286881 :            node != first_analyzed && node != first_analyzed_var;
    1218    147511500 :            node = safe_as_a<symtab_node *>(node->next))
    1219              :         {
    1220              :           /* Convert COMDAT group designators to IDENTIFIER_NODEs.  */
    1221    147511500 :           node->get_comdat_group_id ();
    1222    147511500 :           if (node->needed_p ())
    1223              :             {
    1224      2836669 :               enqueue_node (node);
    1225      2836669 :               if (!changed && symtab->dump_file)
    1226           75 :                 fprintf (symtab->dump_file, "Trivially needed symbols:");
    1227      2836669 :               changed = true;
    1228      2836669 :               if (symtab->dump_file)
    1229          128 :                 fprintf (symtab->dump_file, " %s", node->dump_asm_name ());
    1230              :             }
    1231    147511500 :           if (node == first_analyzed
    1232    147511500 :               || node == first_analyzed_var)
    1233              :             break;
    1234              :         }
    1235       775381 :       symtab->process_new_functions ();
    1236       775381 :       first_analyzed_var = symtab->first_variable ();
    1237       775381 :       first_analyzed = symtab->first_function ();
    1238              : 
    1239       775381 :       if (changed && symtab->dump_file)
    1240           75 :         fprintf (symtab->dump_file, "\n");
    1241              : 
    1242              :       /* Lower representation, build callgraph edges and references for all trivially
    1243              :          needed symbols and all symbols referred by them.  */
    1244      7273565 :       while (queued_nodes != &symtab_terminator)
    1245              :         {
    1246      6498197 :           changed = true;
    1247      6498197 :           node = queued_nodes;
    1248      6498197 :           queued_nodes = (symtab_node *)queued_nodes->aux;
    1249      6498197 :           cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
    1250      3435869 :           if (cnode && cnode->definition)
    1251              :             {
    1252      3432628 :               cgraph_edge *edge;
    1253      3432628 :               tree decl = cnode->decl;
    1254              : 
    1255              :               /* ??? It is possible to create extern inline function
    1256              :               and later using weak alias attribute to kill its body.
    1257              :               See gcc.c-torture/compile/20011119-1.c  */
    1258      3432628 :               if (!DECL_STRUCT_FUNCTION (decl)
    1259        15128 :                   && !cnode->alias
    1260         3485 :                   && !cnode->thunk
    1261      3432742 :                   && !cnode->dispatcher_function)
    1262              :                 {
    1263            0 :                   cnode->reset ();
    1264            0 :                   cnode->redefined_extern_inline = true;
    1265            0 :                   continue;
    1266              :                 }
    1267              : 
    1268      3432628 :               if (!cnode->analyzed)
    1269      3071423 :                 cnode->analyze ();
    1270              : 
    1271              :               /* A reference to a default node in a function set implies a
    1272              :                  reference to all versions in the set.  */
    1273      3432615 :               cgraph_function_version_info *node_v = cnode->function_version ();
    1274      3432615 :               if (node_v && is_function_default_version (node->decl))
    1275          129 :                 for (cgraph_function_version_info *fvi = node_v->next;
    1276          750 :                      fvi;
    1277          621 :                      fvi = fvi->next)
    1278          621 :                   enqueue_node (fvi->this_node);
    1279              : 
    1280     13563807 :               for (edge = cnode->callees; edge; edge = edge->next_callee)
    1281     10131192 :                 if (edge->callee->definition
    1282     10131192 :                     && (!DECL_EXTERNAL (edge->callee->decl)
    1283              :                         /* When not optimizing, do not try to analyze extern
    1284              :                            inline functions.  Doing so is pointless.  */
    1285       647195 :                         || opt_for_fn (edge->callee->decl, optimize)
    1286              :                         /* Weakrefs needs to be preserved.  */
    1287         4984 :                         || edge->callee->alias
    1288              :                         /* always_inline functions are inlined even at -O0.  */
    1289         3354 :                         || lookup_attribute
    1290         3354 :                                  ("always_inline",
    1291         3354 :                                   DECL_ATTRIBUTES (edge->callee->decl))
    1292              :                         /* Multiversioned functions needs the dispatcher to
    1293              :                            be produced locally even for extern functions.  */
    1294         2002 :                         || edge->callee->function_version ()))
    1295      5279645 :                    enqueue_node (edge->callee);
    1296      3432615 :               if (opt_for_fn (cnode->decl, optimize)
    1297      3432615 :                   && opt_for_fn (cnode->decl, flag_devirtualize))
    1298              :                 {
    1299      2794358 :                   cgraph_edge *next;
    1300              : 
    1301      2927062 :                   for (edge = cnode->indirect_calls; edge; edge = next)
    1302              :                     {
    1303       132704 :                       next = edge->next_callee;
    1304       132704 :                       if (is_a <cgraph_polymorphic_indirect_info *>
    1305       265408 :                           (edge->indirect_info))
    1306        18915 :                         walk_polymorphic_call_targets (&reachable_call_targets,
    1307              :                                                        edge);
    1308              :                     }
    1309              :                 }
    1310              : 
    1311              :               /* If decl is a clone of an abstract function,
    1312              :                  mark that abstract function so that we don't release its body.
    1313              :                  The DECL_INITIAL() of that abstract function declaration
    1314              :                  will be later needed to output debug info.  */
    1315      3432615 :               if (DECL_ABSTRACT_ORIGIN (decl))
    1316              :                 {
    1317       745964 :                   cgraph_node *origin_node
    1318       745964 :                     = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl));
    1319       745964 :                   origin_node->used_as_abstract_origin = true;
    1320              :                 }
    1321              :               /* Preserve a functions function context node.  It will
    1322              :                  later be needed to output debug info.  */
    1323      3432615 :               if (tree fn = decl_function_context (decl))
    1324              :                 {
    1325       129243 :                   cgraph_node *origin_node = cgraph_node::get_create (fn);
    1326       129243 :                   enqueue_node (origin_node);
    1327              :                 }
    1328              :             }
    1329              :           else
    1330              :             {
    1331      3065569 :               varpool_node *vnode = dyn_cast <varpool_node *> (node);
    1332      3062328 :               if (vnode && vnode->definition && !vnode->analyzed)
    1333      3062321 :                 vnode->analyze ();
    1334              :             }
    1335              : 
    1336      6498184 :           if (node->same_comdat_group)
    1337              :             {
    1338              :               symtab_node *next;
    1339       944412 :               for (next = node->same_comdat_group;
    1340      1624173 :                    next != node;
    1341       944412 :                    next = next->same_comdat_group)
    1342      1888824 :                 if (!next->comdat_local_p ())
    1343       932297 :                   enqueue_node (next);
    1344              :             }
    1345     17939441 :           for (i = 0; node->iterate_reference (i, ref); i++)
    1346     11441257 :             if (ref->referred->definition
    1347     11441257 :                 && (!DECL_EXTERNAL (ref->referred->decl)
    1348        82961 :                     || ((TREE_CODE (ref->referred->decl) != FUNCTION_DECL
    1349        28097 :                          && optimize)
    1350        55478 :                         || (TREE_CODE (ref->referred->decl) == FUNCTION_DECL
    1351        54864 :                             && opt_for_fn (ref->referred->decl, optimize))
    1352         1498 :                     || node->alias
    1353         1006 :                     || ref->referred->alias)))
    1354      7495079 :               enqueue_node (ref->referred);
    1355      6498184 :           symtab->process_new_functions ();
    1356              :         }
    1357              :     }
    1358       527120 :   update_type_inheritance_graph ();
    1359              : 
    1360              :   /* Collect entry points to the unit.  */
    1361       527120 :   if (symtab->dump_file)
    1362              :     {
    1363          150 :       fprintf (symtab->dump_file, "\n\nInitial ");
    1364          150 :       symtab->dump (symtab->dump_file);
    1365              :     }
    1366              : 
    1367       527120 :   if (first_time)
    1368              :     {
    1369       263560 :       symtab_node *snode;
    1370    147798932 :       FOR_EACH_SYMBOL (snode)
    1371    147535372 :         check_global_declaration (snode);
    1372              :     }
    1373              : 
    1374       527120 :   if (symtab->dump_file)
    1375          150 :     fprintf (symtab->dump_file, "\nRemoving unused symbols:");
    1376              : 
    1377       527120 :   for (node = symtab->first_symbol ();
    1378    148062510 :        node != first_handled
    1379    148062510 :        && node != first_handled_var; node = next)
    1380              :     {
    1381    147535390 :       next = safe_as_a<symtab_node *>(node->next);
    1382              :       /* For symbols declared locally we clear TREE_READONLY when emitting
    1383              :          the constructor (if one is needed).  For external declarations we can
    1384              :          not safely assume that the type is readonly because we may be called
    1385              :          during its construction.  */
    1386    147535390 :       if (TREE_CODE (node->decl) == VAR_DECL
    1387     37812457 :           && TYPE_P (TREE_TYPE (node->decl))
    1388     37811402 :           && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (node->decl))
    1389    148276526 :           && DECL_EXTERNAL (node->decl))
    1390       347260 :         TREE_READONLY (node->decl) = 0;
    1391    147535390 :       if (!node->aux && !node->referred_to_p () && !node->ref_by_asm)
    1392              :         {
    1393    138873473 :           if (symtab->dump_file)
    1394           21 :             fprintf (symtab->dump_file, " %s", node->dump_name ());
    1395              : 
    1396              :           /* See if the debugger can use anything before the DECL
    1397              :              passes away.  Perhaps it can notice a DECL that is now a
    1398              :              constant and can tag the early DIE with an appropriate
    1399              :              attribute.
    1400              : 
    1401              :              Otherwise, this is the last chance the debug_hooks have
    1402              :              at looking at optimized away DECLs, since
    1403              :              late_global_decl will subsequently be called from the
    1404              :              contents of the now pruned symbol table.  */
    1405    138873473 :           if (VAR_P (node->decl)
    1406    138873473 :               && !decl_function_context (node->decl))
    1407              :             {
    1408              :               /* We are reclaiming totally unreachable code and variables
    1409              :                  so they effectively appear as readonly.  Show that to
    1410              :                  the debug machinery.  */
    1411     34315178 :               TREE_READONLY (node->decl) = 1;
    1412     34315178 :               node->definition = false;
    1413     34315178 :               (*debug_hooks->late_global_decl) (node->decl);
    1414              :             }
    1415              : 
    1416    138873473 :           node->remove ();
    1417    138873473 :           continue;
    1418              :         }
    1419      8661917 :       if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
    1420              :         {
    1421      5301047 :           tree decl = node->decl;
    1422              : 
    1423      3433609 :           if (cnode->definition && !gimple_has_body_p (decl)
    1424       369421 :               && !cnode->alias
    1425      5305334 :               && !cnode->thunk)
    1426         1027 :             cnode->reset ();
    1427              : 
    1428      5301047 :           gcc_assert (!cnode->definition || cnode->thunk
    1429              :                       || cnode->alias
    1430              :                       || gimple_has_body_p (decl)
    1431              :                       || cnode->native_rtl_p ());
    1432      5301047 :           gcc_assert (cnode->analyzed == cnode->definition);
    1433              :         }
    1434      8661917 :       node->aux = NULL;
    1435              :     }
    1436      9189036 :   for (;node; node = safe_as_a<symtab_node *>(node->next))
    1437      8661916 :     node->aux = NULL;
    1438       527120 :   first_analyzed = symtab->first_function ();
    1439       527120 :   first_analyzed_var = symtab->first_variable ();
    1440       527120 :   if (symtab->dump_file)
    1441              :     {
    1442          150 :       fprintf (symtab->dump_file, "\n\nReclaimed ");
    1443          150 :       symtab->dump (symtab->dump_file);
    1444              :     }
    1445       527120 :   bitmap_obstack_release (NULL);
    1446       527120 :   ggc_collect ();
    1447              :   /* Initialize assembler name hash, in particular we want to trigger C++
    1448              :      mangling and same body alias creation before we free DECL_ARGUMENTS
    1449              :      used by it.  */
    1450       527120 :   if (!seen_error ())
    1451       474227 :     symtab->symtab_initialize_asm_name_hash ();
    1452              : 
    1453       527120 :   input_location = saved_loc;
    1454       527120 : }
    1455              : 
    1456              : /* Check declaration of the type of ALIAS for compatibility with its TARGET
    1457              :    (which may be an ifunc resolver) and issue a diagnostic when they are
    1458              :    not compatible according to language rules (plus a C++ extension for
    1459              :    non-static member functions).  */
    1460              : 
    1461              : static void
    1462         5145 : maybe_diag_incompatible_alias (tree alias, tree target)
    1463              : {
    1464         5145 :   tree altype = TREE_TYPE (alias);
    1465         5145 :   tree targtype = TREE_TYPE (target);
    1466              : 
    1467         5145 :   bool ifunc = cgraph_node::get (alias)->ifunc_resolver;
    1468         5145 :   tree funcptr = altype;
    1469              : 
    1470         5145 :   if (ifunc)
    1471              :     {
    1472              :       /* Handle attribute ifunc first.  */
    1473          118 :       if (TREE_CODE (altype) == METHOD_TYPE)
    1474              :         {
    1475              :           /* Set FUNCPTR to the type of the alias target.  If the type
    1476              :              is a non-static member function of class C, construct a type
    1477              :              of an ordinary function taking C* as the first argument,
    1478              :              followed by the member function argument list, and use it
    1479              :              instead to check for incompatibility.  This conversion is
    1480              :              not defined by the language but an extension provided by
    1481              :              G++.  */
    1482              : 
    1483           21 :           tree rettype = TREE_TYPE (altype);
    1484           21 :           tree args = TYPE_ARG_TYPES (altype);
    1485           21 :           altype = build_function_type (rettype, args);
    1486           21 :           funcptr = altype;
    1487              :         }
    1488              : 
    1489          118 :       targtype = TREE_TYPE (targtype);
    1490              : 
    1491          118 :       if (POINTER_TYPE_P (targtype))
    1492              :         {
    1493          114 :           targtype = TREE_TYPE (targtype);
    1494              : 
    1495              :           /* Only issue Wattribute-alias for conversions to void* with
    1496              :              -Wextra.  */
    1497          114 :           if (VOID_TYPE_P (targtype) && !extra_warnings)
    1498              :             return;
    1499              : 
    1500              :           /* Proceed to handle incompatible ifunc resolvers below.  */
    1501              :         }
    1502              :       else
    1503              :         {
    1504            4 :           funcptr = build_pointer_type (funcptr);
    1505              : 
    1506            4 :           error_at (DECL_SOURCE_LOCATION (target),
    1507              :                     "%<ifunc%> resolver for %qD must return %qT",
    1508              :                  alias, funcptr);
    1509            4 :           inform (DECL_SOURCE_LOCATION (alias),
    1510              :                   "resolver indirect function declared here");
    1511            4 :           return;
    1512              :         }
    1513              :     }
    1514              : 
    1515         5141 :   if ((!FUNC_OR_METHOD_TYPE_P (targtype)
    1516         5141 :        || (prototype_p (altype)
    1517         5015 :            && prototype_p (targtype)
    1518         5013 :            && !types_compatible_p (altype, targtype))))
    1519              :     {
    1520              :       /* Warn for incompatibilities.  Avoid warning for functions
    1521              :          without a prototype to make it possible to declare aliases
    1522              :          without knowing the exact type, as libstdc++ does.  */
    1523           16 :       if (ifunc)
    1524              :         {
    1525            5 :           funcptr = build_pointer_type (funcptr);
    1526              : 
    1527            5 :           auto_diagnostic_group d;
    1528            5 :           if (warning_at (DECL_SOURCE_LOCATION (target),
    1529            5 :                           OPT_Wattribute_alias_,
    1530              :                           "%<ifunc%> resolver for %qD should return %qT",
    1531              :                           alias, funcptr))
    1532            5 :             inform (DECL_SOURCE_LOCATION (alias),
    1533              :                     "resolver indirect function declared here");
    1534            5 :         }
    1535              :       else
    1536              :         {
    1537           11 :           auto_diagnostic_group d;
    1538           11 :           if (warning_at (DECL_SOURCE_LOCATION (alias),
    1539           11 :                             OPT_Wattribute_alias_,
    1540              :                             "%qD alias between functions of incompatible "
    1541              :                             "types %qT and %qT", alias, altype, targtype))
    1542            3 :             inform (DECL_SOURCE_LOCATION (target),
    1543              :                     "aliased declaration here");
    1544           11 :         }
    1545              :     }
    1546              : }
    1547              : 
    1548              : /* Translate the ugly representation of aliases as alias pairs into nice
    1549              :    representation in callgraph.  We don't handle all cases yet,
    1550              :    unfortunately.  */
    1551              : 
    1552              : static void
    1553       547071 : handle_alias_pairs (void)
    1554              : {
    1555       547071 :   alias_pair *p;
    1556       547071 :   unsigned i;
    1557              : 
    1558       552766 :   for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
    1559              :     {
    1560         5695 :       symtab_node *target_node = symtab_node::get_for_asmname (p->target);
    1561              : 
    1562              :       /* Weakrefs with target not defined in current unit are easy to handle:
    1563              :          they behave just as external variables except we need to note the
    1564              :          alias flag to later output the weakref pseudo op into asm file.  */
    1565         5695 :       if (!target_node
    1566         5695 :           && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
    1567              :         {
    1568          402 :           symtab_node *node = symtab_node::get (p->decl);
    1569          402 :           if (node)
    1570              :             {
    1571          402 :               node->alias_target = p->target;
    1572          402 :               node->weakref = true;
    1573          402 :               node->alias = true;
    1574          402 :               node->transparent_alias = true;
    1575              :             }
    1576          402 :           alias_pairs->unordered_remove (i);
    1577          402 :           continue;
    1578          402 :         }
    1579         5293 :       else if (!target_node)
    1580              :         {
    1581            8 :           error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
    1582            8 :           symtab_node *node = symtab_node::get (p->decl);
    1583            8 :           if (node)
    1584            8 :             node->alias = false;
    1585            8 :           alias_pairs->unordered_remove (i);
    1586            8 :           continue;
    1587            8 :         }
    1588              : 
    1589         5285 :       if (DECL_EXTERNAL (target_node->decl)
    1590              :           /* We use local aliases for C++ thunks to force the tailcall
    1591              :              to bind locally.  This is a hack - to keep it working do
    1592              :              the following (which is not strictly correct).  */
    1593           24 :           && (TREE_CODE (target_node->decl) != FUNCTION_DECL
    1594           24 :               || ! DECL_VIRTUAL_P (target_node->decl))
    1595         5309 :           && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
    1596              :         {
    1597            0 :           error ("%q+D aliased to external symbol %qE",
    1598              :                  p->decl, p->target);
    1599              :         }
    1600              : 
    1601         5285 :       if (TREE_CODE (p->decl) == FUNCTION_DECL
    1602         5285 :           && target_node && is_a <cgraph_node *> (target_node))
    1603              :         {
    1604         5145 :           maybe_diag_incompatible_alias (p->decl, target_node->decl);
    1605              : 
    1606         5145 :           maybe_diag_alias_attributes (p->decl, target_node->decl);
    1607              : 
    1608         5145 :           cgraph_node *src_node = cgraph_node::get (p->decl);
    1609         5145 :           if (src_node && src_node->definition)
    1610           18 :             src_node->reset ();
    1611         5145 :           cgraph_node::create_alias (p->decl, target_node->decl);
    1612         5145 :           alias_pairs->unordered_remove (i);
    1613              :         }
    1614          140 :       else if (VAR_P (p->decl)
    1615          140 :                && target_node && is_a <varpool_node *> (target_node))
    1616              :         {
    1617          139 :           varpool_node::create_alias (p->decl, target_node->decl);
    1618          139 :           alias_pairs->unordered_remove (i);
    1619              :         }
    1620              :       else
    1621              :         {
    1622            1 :           error ("%q+D alias between function and variable is not supported",
    1623              :                  p->decl);
    1624            1 :           inform (DECL_SOURCE_LOCATION (target_node->decl),
    1625              :                   "aliased declaration here");
    1626              : 
    1627            1 :           alias_pairs->unordered_remove (i);
    1628              :         }
    1629              :     }
    1630       547071 :   vec_free (alias_pairs);
    1631       547071 : }
    1632              : 
    1633              : 
    1634              : /* Figure out what functions we want to assemble.  */
    1635              : 
    1636              : static void
    1637       237661 : mark_functions_to_output (void)
    1638              : {
    1639       237661 :   bool check_same_comdat_groups = false;
    1640       237661 :   cgraph_node *node;
    1641              : 
    1642       237661 :   if (flag_checking)
    1643      5103578 :     FOR_EACH_FUNCTION (node)
    1644      4865931 :       gcc_assert (!node->process);
    1645              : 
    1646      5103639 :   FOR_EACH_FUNCTION (node)
    1647              :     {
    1648      4865978 :       tree decl = node->decl;
    1649              : 
    1650      4865978 :       gcc_assert (!node->process || node->same_comdat_group);
    1651      4865978 :       if (node->process)
    1652        11772 :         continue;
    1653              : 
    1654              :       /* We need to output all local functions that are used and not
    1655              :          always inlined, as well as those that are reachable from
    1656              :          outside the current compilation unit.  */
    1657      4854206 :       if (node->analyzed
    1658      3037260 :           && !node->thunk
    1659      3035198 :           && !node->alias
    1660      2970529 :           && !node->inlined_to
    1661      1496490 :           && !TREE_ASM_WRITTEN (decl)
    1662      6350696 :           && !DECL_EXTERNAL (decl))
    1663              :         {
    1664      1496490 :           node->process = 1;
    1665      1496490 :           if (node->same_comdat_group)
    1666              :             {
    1667        48378 :               cgraph_node *next;
    1668        48378 :               for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
    1669       130614 :                    next != node;
    1670        82236 :                    next = dyn_cast<cgraph_node *> (next->same_comdat_group))
    1671        80733 :                 if (!next->thunk && !next->alias
    1672       203119 :                     && !next->comdat_local_p ())
    1673        15577 :                   next->process = 1;
    1674              :             }
    1675              :         }
    1676      3357716 :       else if (node->same_comdat_group)
    1677              :         {
    1678        41906 :           if (flag_checking)
    1679      4865978 :             check_same_comdat_groups = true;
    1680              :         }
    1681              :       else
    1682              :         {
    1683              :           /* We should've reclaimed all functions that are not needed.  */
    1684      3315810 :           if (flag_checking
    1685      3315783 :               && !node->inlined_to
    1686      1841597 :               && gimple_has_body_p (decl)
    1687              :               /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
    1688              :                  are inside partition, we can end up not removing the body since we no longer
    1689              :                  have analyzed node pointing to it.  */
    1690       139128 :               && !node->in_other_partition
    1691       139128 :               && !node->alias
    1692       139128 :               && !node->clones
    1693      3315810 :               && !DECL_EXTERNAL (decl))
    1694              :             {
    1695            0 :               node->debug ();
    1696            0 :               internal_error ("failed to reclaim unneeded function");
    1697              :             }
    1698      3315810 :           gcc_assert (node->inlined_to
    1699              :                       || !gimple_has_body_p (decl)
    1700              :                       || node->in_other_partition
    1701              :                       || node->clones
    1702              :                       || DECL_ARTIFICIAL (decl)
    1703              :                       || DECL_EXTERNAL (decl));
    1704              : 
    1705              :         }
    1706              : 
    1707              :     }
    1708       237661 :   if (flag_checking && check_same_comdat_groups)
    1709      1494402 :     FOR_EACH_FUNCTION (node)
    1710      1483314 :       if (node->same_comdat_group && !node->process)
    1711              :         {
    1712        41906 :           tree decl = node->decl;
    1713        41906 :           if (!node->inlined_to
    1714        41906 :               && gimple_has_body_p (decl)
    1715              :               /* FIXME: in an ltrans unit when the offline copy is outside a
    1716              :                  partition but inline copies are inside a partition, we can
    1717              :                  end up not removing the body since we no longer have an
    1718              :                  analyzed node pointing to it.  */
    1719            1 :               && !node->in_other_partition
    1720            1 :               && !node->clones
    1721        41906 :               && !DECL_EXTERNAL (decl))
    1722              :             {
    1723            0 :               node->debug ();
    1724            0 :               internal_error ("failed to reclaim unneeded function in same "
    1725              :                               "comdat group");
    1726              :             }
    1727              :         }
    1728       237661 : }
    1729              : 
    1730              : /* DECL is FUNCTION_DECL.  Initialize datastructures so DECL is a function
    1731              :    in lowered gimple form.  IN_SSA is true if the gimple is in SSA.
    1732              : 
    1733              :    Set current_function_decl and cfun to newly constructed empty function body.
    1734              :    return basic block in the function body.  */
    1735              : 
    1736              : basic_block
    1737        20605 : init_lowered_empty_function (tree decl, bool in_ssa, profile_count count)
    1738              : {
    1739        20605 :   basic_block bb;
    1740        20605 :   edge e;
    1741              : 
    1742        20605 :   current_function_decl = decl;
    1743        20605 :   allocate_struct_function (decl, false);
    1744        20605 :   gimple_register_cfg_hooks ();
    1745        20605 :   init_empty_tree_cfg ();
    1746        20605 :   init_tree_ssa (cfun);
    1747              : 
    1748        20605 :   if (in_ssa)
    1749              :     {
    1750        20402 :       init_ssa_operands (cfun);
    1751        20402 :       cfun->gimple_df->in_ssa_p = true;
    1752        20402 :       cfun->curr_properties |= PROP_ssa;
    1753              :     }
    1754              : 
    1755        20605 :   DECL_INITIAL (decl) = make_node (BLOCK);
    1756        20605 :   BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
    1757              : 
    1758        20605 :   DECL_SAVED_TREE (decl) = error_mark_node;
    1759        20605 :   cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
    1760              :                             | PROP_cfg | PROP_loops);
    1761              : 
    1762        20605 :   set_loops_for_fn (cfun, ggc_cleared_alloc<loops> ());
    1763        20605 :   init_loops_structure (cfun, loops_for_fn (cfun), 1);
    1764        20605 :   loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
    1765              : 
    1766              :   /* Create BB for body of the function and connect it properly.  */
    1767        20605 :   ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = count;
    1768        20605 :   EXIT_BLOCK_PTR_FOR_FN (cfun)->count = count;
    1769        20605 :   bb = create_basic_block (NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1770        20605 :   bb->count = count;
    1771        20605 :   e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
    1772        20605 :   e->probability = profile_probability::always ();
    1773        20605 :   e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
    1774        20605 :   e->probability = profile_probability::always ();
    1775        20605 :   add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
    1776              : 
    1777        20605 :   return bb;
    1778              : }
    1779              : 
    1780              : /* Assemble thunks and aliases associated to node.  */
    1781              : 
    1782              : void
    1783      1577523 : cgraph_node::assemble_thunks_and_aliases (void)
    1784              : {
    1785      1577523 :   cgraph_edge *e;
    1786      1577523 :   ipa_ref *ref;
    1787              : 
    1788      3161021 :   for (e = callers; e;)
    1789      1583498 :     if (e->caller->thunk
    1790         1932 :         && !e->caller->inlined_to)
    1791              :       {
    1792         1908 :         cgraph_node *thunk = e->caller;
    1793              : 
    1794         1908 :         e = e->next_caller;
    1795         1908 :         expand_thunk (thunk, !rtl_dump_and_exit, false);
    1796         1908 :         thunk->assemble_thunks_and_aliases ();
    1797         1908 :       }
    1798              :     else
    1799      1581590 :       e = e->next_caller;
    1800              : 
    1801      1640923 :   FOR_EACH_ALIAS (this, ref)
    1802              :     {
    1803        63400 :       cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    1804        63400 :       if (!alias->transparent_alias)
    1805              :         {
    1806        63394 :           bool saved_written = TREE_ASM_WRITTEN (decl);
    1807              : 
    1808              :           /* Force assemble_alias to really output the alias this time instead
    1809              :              of buffering it in same alias pairs.  */
    1810        63394 :           TREE_ASM_WRITTEN (decl) = 1;
    1811        63394 :           if (alias->symver)
    1812            2 :             do_assemble_symver (alias->decl,
    1813              :                                 DECL_ASSEMBLER_NAME (decl));
    1814              :           else
    1815        63392 :             do_assemble_alias (alias->decl,
    1816              :                                DECL_ASSEMBLER_NAME (decl));
    1817        63394 :           alias->assemble_thunks_and_aliases ();
    1818        63394 :           TREE_ASM_WRITTEN (decl) = saved_written;
    1819              :         }
    1820              :     }
    1821      1577523 : }
    1822              : 
    1823              : /* Expand function specified by node.  */
    1824              : 
    1825              : void
    1826      1512341 : cgraph_node::expand (void)
    1827              : {
    1828      1512341 :   location_t saved_loc;
    1829              : 
    1830              :   /* We ought to not compile any inline clones.  */
    1831      1512341 :   gcc_assert (!inlined_to);
    1832              : 
    1833              :   /* __RTL functions are compiled as soon as they are parsed, so don't
    1834              :      do it again.  */
    1835      1512341 :   if (native_rtl_p ())
    1836              :     return;
    1837              : 
    1838      1512341 :   announce_function (decl);
    1839      1512341 :   process = 0;
    1840      1512341 :   gcc_assert (lowered);
    1841              : 
    1842              :   /* Initialize the default bitmap obstack.  */
    1843      1512341 :   bitmap_obstack_initialize (NULL);
    1844      1512341 :   get_untransformed_body ();
    1845              : 
    1846              :   /* Generate RTL for the body of DECL.  */
    1847              : 
    1848      1512341 :   timevar_push (TV_REST_OF_COMPILATION);
    1849              : 
    1850      1512341 :   gcc_assert (symtab->global_info_ready);
    1851              : 
    1852              :   /* Initialize the RTL code for the function.  */
    1853      1512341 :   saved_loc = input_location;
    1854      1512341 :   input_location = DECL_SOURCE_LOCATION (decl);
    1855              : 
    1856      1512341 :   gcc_assert (DECL_STRUCT_FUNCTION (decl));
    1857      1512341 :   push_cfun (DECL_STRUCT_FUNCTION (decl));
    1858      1512341 :   init_function_start (decl);
    1859              : 
    1860      1512341 :   gimple_register_cfg_hooks ();
    1861              : 
    1862      1512341 :   bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
    1863              : 
    1864      1512341 :   update_ssa (TODO_update_ssa_only_virtuals);
    1865      1512341 :   if (ipa_transforms_to_apply.exists ())
    1866      1491303 :     execute_all_ipa_transforms (false);
    1867              : 
    1868              :   /* Perform all tree transforms and optimizations.  */
    1869              : 
    1870              :   /* Signal the start of passes.  */
    1871      1512341 :   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
    1872              : 
    1873      1512341 :   execute_pass_list (cfun, g->get_passes ()->all_passes);
    1874              : 
    1875              :   /* Signal the end of passes.  */
    1876      1512331 :   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
    1877              : 
    1878      1512331 :   bitmap_obstack_release (&reg_obstack);
    1879              : 
    1880              :   /* Release the default bitmap obstack.  */
    1881      1512331 :   bitmap_obstack_release (NULL);
    1882              : 
    1883              :   /* If requested, warn about function definitions where the function will
    1884              :      return a value (usually of some struct or union type) which itself will
    1885              :      take up a lot of stack space.  */
    1886      1512331 :   if (!DECL_EXTERNAL (decl) && TREE_TYPE (decl))
    1887              :     {
    1888      1512331 :       tree ret_type = TREE_TYPE (TREE_TYPE (decl));
    1889              : 
    1890      1512331 :       if (ret_type && TYPE_SIZE_UNIT (ret_type)
    1891       806001 :           && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
    1892      2318293 :           && compare_tree_int (TYPE_SIZE_UNIT (ret_type),
    1893       805962 :                                warn_larger_than_size) > 0)
    1894              :         {
    1895            0 :           unsigned int size_as_int
    1896            0 :             = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
    1897              : 
    1898            0 :           if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
    1899            0 :             warning (OPT_Wlarger_than_,
    1900              :                      "size of return value of %q+D is %u bytes",
    1901              :                      decl, size_as_int);
    1902              :           else
    1903            0 :             warning (OPT_Wlarger_than_,
    1904              :                      "size of return value of %q+D is larger than %wu bytes",
    1905              :                      decl, warn_larger_than_size);
    1906              :         }
    1907              :     }
    1908              : 
    1909      1512331 :   gimple_set_body (decl, NULL);
    1910      1512331 :   if (DECL_STRUCT_FUNCTION (decl) == 0)
    1911              :     {
    1912              :       /* Stop pointing to the local nodes about to be freed.
    1913              :          But DECL_INITIAL must remain nonzero so we know this
    1914              :          was an actual function definition.  */
    1915           62 :       if (DECL_INITIAL (decl) != 0)
    1916           62 :         DECL_INITIAL (decl) = error_mark_node;
    1917              :     }
    1918              : 
    1919      1512331 :   input_location = saved_loc;
    1920              : 
    1921      1512331 :   ggc_collect ();
    1922      1512331 :   timevar_pop (TV_REST_OF_COMPILATION);
    1923              : 
    1924      1512331 :   if (DECL_STRUCT_FUNCTION (decl)
    1925      1512331 :       && DECL_STRUCT_FUNCTION (decl)->assume_function)
    1926              :     {
    1927              :       /* Assume functions aren't expanded into RTL, on the other side
    1928              :          we don't want to release their body.  */
    1929          110 :       if (cfun)
    1930            0 :         pop_cfun ();
    1931              :       return;
    1932              :     }
    1933              : 
    1934              :   /* Make sure that BE didn't give up on compiling.  */
    1935      1512221 :   gcc_assert (TREE_ASM_WRITTEN (decl));
    1936      1512221 :   if (cfun)
    1937      1512159 :     pop_cfun ();
    1938              : 
    1939              :   /* It would make a lot more sense to output thunks before function body to
    1940              :      get more forward and fewer backward jumps.  This however would need
    1941              :      solving problem with comdats.  See PR48668.  Also aliases must come after
    1942              :      function itself to make one pass assemblers, like one on AIX, happy.
    1943              :      See PR 50689.
    1944              :      FIXME: Perhaps thunks should be move before function IFF they are not in
    1945              :      comdat groups.  */
    1946      1512221 :   assemble_thunks_and_aliases ();
    1947      1512221 :   release_body ();
    1948              : }
    1949              : 
    1950              : /* Node comparator that is responsible for the order that corresponds
    1951              :    to time when a function was launched for the first time.  */
    1952              : 
    1953              : int
    1954       866335 : tp_first_run_node_cmp (const void *pa, const void *pb)
    1955              : {
    1956       866335 :   const cgraph_node *a = *(const cgraph_node * const *) pa;
    1957       866335 :   const cgraph_node *b = *(const cgraph_node * const *) pb;
    1958       866335 :   unsigned int tp_first_run_a = a->tp_first_run;
    1959       866335 :   unsigned int tp_first_run_b = b->tp_first_run;
    1960              : 
    1961       866335 :   if (!opt_for_fn (a->decl, flag_profile_reorder_functions)
    1962       866335 :       || a->no_reorder)
    1963              :     tp_first_run_a = 0;
    1964       866335 :   if (!opt_for_fn (b->decl, flag_profile_reorder_functions)
    1965       866335 :       || b->no_reorder)
    1966              :     tp_first_run_b = 0;
    1967              : 
    1968       866335 :   if (tp_first_run_a == tp_first_run_b)
    1969       864391 :     return a->order - b->order;
    1970              : 
    1971              :   /* Functions with time profile must be before these without profile.  */
    1972         1944 :   tp_first_run_a = (tp_first_run_a - 1) & INT_MAX;
    1973         1944 :   tp_first_run_b = (tp_first_run_b - 1) & INT_MAX;
    1974              : 
    1975         1944 :   return tp_first_run_a - tp_first_run_b;
    1976              : }
    1977              : 
    1978              : /* Expand all functions that must be output.
    1979              : 
    1980              :    Attempt to topologically sort the nodes so function is output when
    1981              :    all called functions are already assembled to allow data to be
    1982              :    propagated across the callgraph.  Use a stack to get smaller distance
    1983              :    between a function and its callees (later we may choose to use a more
    1984              :    sophisticated algorithm for function reordering; we will likely want
    1985              :    to use subsections to make the output functions appear in top-down
    1986              :    order).  */
    1987              : 
    1988              : static void
    1989       237651 : expand_all_functions (void)
    1990              : {
    1991       237651 :   cgraph_node *node;
    1992       237651 :   cgraph_node **order = XCNEWVEC (cgraph_node *,
    1993              :                                          symtab->cgraph_count);
    1994       237651 :   cgraph_node **tp_first_run_order = XCNEWVEC (cgraph_node *,
    1995              :                                          symtab->cgraph_count);
    1996       237651 :   unsigned int expanded_func_count = 0, profiled_func_count = 0;
    1997       237651 :   int order_pos, tp_first_run_order_pos = 0, new_order_pos = 0;
    1998       237651 :   int i;
    1999              : 
    2000       237651 :   order_pos = ipa_reverse_postorder (order);
    2001       237651 :   gcc_assert (order_pos == symtab->cgraph_count);
    2002              : 
    2003              :   /* Garbage collector may remove inline clones we eliminate during
    2004              :      optimization.  So we must be sure to not reference them.  */
    2005      5069267 :   for (i = 0; i < order_pos; i++)
    2006      4831616 :     if (order[i]->process)
    2007              :       {
    2008       963630 :         if (order[i]->tp_first_run
    2009       963630 :             && opt_for_fn (order[i]->decl, flag_profile_reorder_functions))
    2010          255 :           tp_first_run_order[tp_first_run_order_pos++] = order[i];
    2011              :         else
    2012       963375 :           order[new_order_pos++] = order[i];
    2013              :       }
    2014              : 
    2015              :   /* First output functions with time profile in specified order.  */
    2016       237651 :   qsort (tp_first_run_order, tp_first_run_order_pos,
    2017              :          sizeof (cgraph_node *), tp_first_run_node_cmp);
    2018       475557 :   for (i = 0; i < tp_first_run_order_pos; i++)
    2019              :     {
    2020          255 :       node = tp_first_run_order[i];
    2021              : 
    2022          255 :       if (node->process)
    2023              :         {
    2024          255 :           expanded_func_count++;
    2025          255 :           profiled_func_count++;
    2026              : 
    2027          255 :           if (symtab->dump_file)
    2028            0 :             fprintf (symtab->dump_file,
    2029              :                      "Time profile order in expand_all_functions:%s:%d\n",
    2030              :                      node->dump_asm_name (), node->tp_first_run);
    2031          255 :           node->process = 0;
    2032          255 :           node->expand ();
    2033              :         }
    2034              :     }
    2035              : 
    2036              :   /* Output functions in RPO so callees get optimized before callers.  This
    2037              :      makes ipa-ra and other propagators to work.
    2038              :      FIXME: This is far from optimal code layout.
    2039              :      Make multiple passes over the list to defer processing of gc
    2040              :      candidates until all potential uses are seen.  */
    2041              :   int gc_candidates = 0;
    2042              :   int prev_gc_candidates = 0;
    2043              : 
    2044       237698 :   while (1)
    2045              :     {
    2046      1201658 :       for (i = new_order_pos - 1; i >= 0; i--)
    2047              :         {
    2048       963960 :           node = order[i];
    2049              : 
    2050       963960 :           if (node->gc_candidate)
    2051          158 :             gc_candidates++;
    2052       963802 :           else if (node->process)
    2053              :             {
    2054       963315 :               expanded_func_count++;
    2055       963315 :               node->process = 0;
    2056       963315 :               node->expand ();
    2057              :             }
    2058              :         }
    2059       237698 :       if (!gc_candidates || gc_candidates == prev_gc_candidates)
    2060              :         break;
    2061              :       prev_gc_candidates = gc_candidates;
    2062              :       gc_candidates = 0;
    2063              :     }
    2064              : 
    2065              :   /* Free any unused gc_candidate functions.  */
    2066       237651 :   if (gc_candidates)
    2067          374 :     for (i = new_order_pos - 1; i >= 0; i--)
    2068              :       {
    2069          342 :         node = order[i];
    2070          342 :         if (node->gc_candidate)
    2071              :           {
    2072           60 :             struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
    2073           60 :             if (symtab->dump_file)
    2074            8 :               fprintf (symtab->dump_file,
    2075              :                        "Deleting unused function %s\n",
    2076            4 :                        IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
    2077           60 :             node->process = false;
    2078           60 :             free_dominance_info (fn, CDI_DOMINATORS);
    2079           60 :             free_dominance_info (fn, CDI_POST_DOMINATORS);
    2080           60 :             node->release_body (false);
    2081              :           }
    2082              :       }
    2083              : 
    2084       237651 :   if (dump_file)
    2085            0 :     fprintf (dump_file, "Expanded functions with time profile (%s):%u/%u\n",
    2086              :              main_input_filename, profiled_func_count, expanded_func_count);
    2087              : 
    2088       237651 :   if (symtab->dump_file && tp_first_run_order_pos)
    2089            0 :     fprintf (symtab->dump_file, "Expanded functions with time profile:%u/%u\n",
    2090              :              profiled_func_count, expanded_func_count);
    2091              : 
    2092       237651 :   symtab->process_new_functions ();
    2093       237651 :   free_gimplify_stack ();
    2094       237651 :   delete ipa_saved_clone_sources;
    2095       237651 :   ipa_saved_clone_sources = NULL;
    2096       237651 :   free (order);
    2097       237651 :   free (tp_first_run_order);
    2098       237651 : }
    2099              : 
    2100              : /* This is used to sort the node types by the cgraph order number.  */
    2101              : 
    2102              : enum cgraph_order_sort_kind
    2103              : {
    2104              :   ORDER_FUNCTION,
    2105              :   ORDER_VAR,
    2106              :   ORDER_VAR_UNDEF,
    2107              :   ORDER_ASM
    2108              : };
    2109              : 
    2110              : struct cgraph_order_sort
    2111              : {
    2112              :   /* Construct from a cgraph_node.  */
    2113       544632 :   cgraph_order_sort (cgraph_node *node)
    2114       544632 :   : kind (ORDER_FUNCTION), order (node->order)
    2115              :   {
    2116       544632 :     u.f = node;
    2117              :   }
    2118              : 
    2119              :   /* Construct from a varpool_node.  */
    2120      1001204 :   cgraph_order_sort (varpool_node *node)
    2121      2002408 :   : kind (node->definition ? ORDER_VAR : ORDER_VAR_UNDEF), order (node->order)
    2122              :   {
    2123      1001204 :     u.v = node;
    2124              :   }
    2125              : 
    2126              :   /* Construct from a asm_node.  */
    2127        12762 :   cgraph_order_sort (asm_node *node)
    2128        12762 :   : kind (ORDER_ASM), order (node->order)
    2129              :   {
    2130        12762 :     u.a = node;
    2131              :   }
    2132              : 
    2133              :   /* Assembly cgraph_order_sort based on its type.  */
    2134              :   void process ();
    2135              : 
    2136              :   enum cgraph_order_sort_kind kind;
    2137              :   union
    2138              :   {
    2139              :     cgraph_node *f;
    2140              :     varpool_node *v;
    2141              :     asm_node *a;
    2142              :   } u;
    2143              :   int order;
    2144              : };
    2145              : 
    2146              : /* Assembly cgraph_order_sort based on its type.  */
    2147              : 
    2148              : void
    2149      1558568 : cgraph_order_sort::process ()
    2150              : {
    2151      1558568 :   switch (kind)
    2152              :     {
    2153       544602 :     case ORDER_FUNCTION:
    2154       544602 :       u.f->process = 0;
    2155       544602 :       u.f->expand ();
    2156       544602 :       break;
    2157      1000521 :     case ORDER_VAR:
    2158      1000521 :       u.v->assemble_decl ();
    2159      1000521 :       break;
    2160          683 :     case ORDER_VAR_UNDEF:
    2161          683 :       assemble_undefined_decl (u.v->decl);
    2162          683 :       break;
    2163        12762 :     case ORDER_ASM:
    2164        12762 :       assemble_asm (u.a->asm_str);
    2165        12762 :       break;
    2166            0 :     default:
    2167            0 :       gcc_unreachable ();
    2168              :     }
    2169      1558558 : }
    2170              : 
    2171              : /* Compare cgraph_order_sort by order.  */
    2172              : 
    2173              : static int
    2174     63726949 : cgraph_order_cmp (const void *a_p, const void *b_p)
    2175              : {
    2176     63726949 :   const cgraph_order_sort *nodea = (const cgraph_order_sort *)a_p;
    2177     63726949 :   const cgraph_order_sort *nodeb = (const cgraph_order_sort *)b_p;
    2178              : 
    2179     63726949 :   return nodea->order - nodeb->order;
    2180              : }
    2181              : 
    2182              : /* Output all functions, variables, and asm statements in the order
    2183              :    according to their order fields, which is the order in which they
    2184              :    appeared in the file.  This implements -fno-toplevel-reorder.  In
    2185              :    this mode we may output functions and variables which don't really
    2186              :    need to be output.  */
    2187              : 
    2188              : static void
    2189       237661 : output_in_order (void)
    2190              : {
    2191       237661 :   int i;
    2192       237661 :   cgraph_node *cnode;
    2193       237661 :   varpool_node *vnode;
    2194       237661 :   asm_node *anode;
    2195       237661 :   auto_vec<cgraph_order_sort> nodes;
    2196       237661 :   cgraph_order_sort *node;
    2197              : 
    2198      3286694 :   FOR_EACH_DEFINED_FUNCTION (cnode)
    2199      3049033 :     if (cnode->process && !cnode->thunk
    2200      1508262 :         && !cnode->alias && cnode->no_reorder)
    2201       544632 :       nodes.safe_push (cgraph_order_sort (cnode));
    2202              : 
    2203              :   /* There is a similar loop in symbol_table::output_variables.
    2204              :      Please keep them in sync.  */
    2205      3427244 :   FOR_EACH_VARIABLE (vnode)
    2206      3189583 :     if (vnode->no_reorder
    2207      1001226 :         && !DECL_HARD_REGISTER (vnode->decl)
    2208      4190787 :         && !DECL_HAS_VALUE_EXPR_P (vnode->decl))
    2209      1001887 :       nodes.safe_push (cgraph_order_sort (vnode));
    2210              : 
    2211       250423 :   for (anode = symtab->first_asm_symbol (); anode;
    2212        12762 :        anode = safe_as_a<asm_node*>(anode->next))
    2213        12762 :     nodes.safe_push (cgraph_order_sort (anode));
    2214              : 
    2215              :   /* Sort nodes by order.  */
    2216       237661 :   nodes.qsort (cgraph_order_cmp);
    2217              : 
    2218              :   /* In toplevel reorder mode we output all statics; mark them as needed.  */
    2219      1796259 :   FOR_EACH_VEC_ELT (nodes, i, node)
    2220      1558598 :     if (node->kind == ORDER_VAR)
    2221      1000521 :       node->u.v->finalize_named_section_flags ();
    2222              : 
    2223      1796219 :   FOR_EACH_VEC_ELT (nodes, i, node)
    2224      1558568 :     node->process ();
    2225              : 
    2226       237651 :   symtab->clear_asm_symbols ();
    2227       237651 : }
    2228              : 
    2229              : static void
    2230       249962 : ipa_passes (void)
    2231              : {
    2232       249962 :   gcc::pass_manager *passes = g->get_passes ();
    2233              : 
    2234       249962 :   set_cfun (NULL);
    2235       249962 :   current_function_decl = NULL;
    2236       249962 :   gimple_register_cfg_hooks ();
    2237       249962 :   bitmap_obstack_initialize (NULL);
    2238              : 
    2239       249962 :   invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
    2240              : 
    2241       249962 :   if (!in_lto_p)
    2242              :     {
    2243       237109 :       execute_ipa_pass_list (passes->all_small_ipa_passes);
    2244       237109 :       if (seen_error ())
    2245              :         return;
    2246              :     }
    2247              : 
    2248              :   /* This extra symtab_remove_unreachable_nodes pass tends to catch some
    2249              :      devirtualization and other changes where removal iterate.  */
    2250       249813 :   symtab->remove_unreachable_nodes (symtab->dump_file);
    2251              : 
    2252              :   /* If pass_all_early_optimizations was not scheduled, the state of
    2253              :      the cgraph will not be properly updated.  Update it now.  */
    2254       249813 :   if (symtab->state < IPA_SSA)
    2255        12853 :     symtab->state = IPA_SSA;
    2256              : 
    2257       249813 :   if (!in_lto_p)
    2258              :     {
    2259              :       /* Generate coverage variables and constructors.  */
    2260       236960 :       coverage_finish ();
    2261              : 
    2262              :       /* Process new functions added.  */
    2263       236960 :       set_cfun (NULL);
    2264       236960 :       current_function_decl = NULL;
    2265       236960 :       symtab->process_new_functions ();
    2266              : 
    2267       236960 :       execute_ipa_summary_passes
    2268       236960 :         ((ipa_opt_pass_d *) passes->all_regular_ipa_passes);
    2269              :     }
    2270              : 
    2271              :   /* Some targets need to handle LTO assembler output specially.  */
    2272       249813 :   if (flag_generate_lto || flag_generate_offload)
    2273        23539 :     targetm.asm_out.lto_start ();
    2274              : 
    2275       249813 :   if (!in_lto_p
    2276        12853 :       || flag_incremental_link == INCREMENTAL_LINK_LTO)
    2277              :     {
    2278       236997 :       if (!quiet_flag)
    2279            0 :         fprintf (stderr, "Streaming LTO\n");
    2280       236997 :       if (g->have_offload)
    2281              :         {
    2282            0 :           section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
    2283            0 :           lto_stream_offload_p = true;
    2284            0 :           ipa_write_summaries ();
    2285            0 :           lto_stream_offload_p = false;
    2286              :         }
    2287       236997 :       if (flag_lto)
    2288              :         {
    2289        23539 :           section_name_prefix = LTO_SECTION_NAME_PREFIX;
    2290        23539 :           lto_stream_offload_p = false;
    2291        23539 :           ipa_write_summaries ();
    2292              :         }
    2293              :     }
    2294              : 
    2295       249813 :   if (flag_generate_lto || flag_generate_offload)
    2296        23539 :     targetm.asm_out.lto_end ();
    2297              : 
    2298       249813 :   if (!flag_ltrans
    2299       241480 :       && ((in_lto_p && flag_incremental_link != INCREMENTAL_LINK_LTO)
    2300       236997 :           || !flag_lto || flag_fat_lto_objects))
    2301       229336 :     execute_ipa_pass_list (passes->all_regular_ipa_passes);
    2302       249813 :   invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
    2303              : 
    2304       249813 :   bitmap_obstack_release (NULL);
    2305              : }
    2306              : 
    2307              : 
    2308              : /* Weakrefs may be associated to external decls and thus not output
    2309              :    at expansion time.  Emit all necessary aliases.  */
    2310              : 
    2311              : void
    2312       237651 : symbol_table::output_weakrefs (void)
    2313              : {
    2314       237651 :   symtab_node *node;
    2315      6799715 :   FOR_EACH_SYMBOL (node)
    2316      6562064 :     if (node->alias
    2317        70121 :         && !TREE_ASM_WRITTEN (node->decl)
    2318         1402 :         && node->weakref)
    2319              :       {
    2320          127 :         tree target;
    2321              : 
    2322              :         /* Weakrefs are special by not requiring target definition in current
    2323              :            compilation unit.  It is thus bit hard to work out what we want to
    2324              :            alias.
    2325              :            When alias target is defined, we need to fetch it from symtab reference,
    2326              :            otherwise it is pointed to by alias_target.  */
    2327          127 :         if (node->alias_target)
    2328          122 :           target = (DECL_P (node->alias_target)
    2329          122 :                     ? DECL_ASSEMBLER_NAME (node->alias_target)
    2330              :                     : node->alias_target);
    2331            5 :         else if (node->analyzed)
    2332            5 :           target = DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl);
    2333              :         else
    2334            0 :           gcc_unreachable ();
    2335          127 :         do_assemble_alias (node->decl, target);
    2336              :       }
    2337       237651 : }
    2338              : 
    2339              : /* Perform simple optimizations based on callgraph.  */
    2340              : 
    2341              : void
    2342       276413 : symbol_table::compile (void)
    2343              : {
    2344       276413 :   if (seen_error ())
    2345              :     return;
    2346              : 
    2347       249962 :   symtab_node::checking_verify_symtab_nodes ();
    2348              : 
    2349       249962 :   symtab_node::check_ifunc_callee_symtab_nodes ();
    2350              : 
    2351       249962 :   timevar_push (TV_CGRAPHOPT);
    2352       249962 :   if (pre_ipa_mem_report)
    2353            0 :     dump_memory_report ("Memory consumption before IPA");
    2354       249962 :   if (!quiet_flag)
    2355            0 :     fprintf (stderr, "Performing interprocedural optimizations\n");
    2356       249962 :   state = IPA;
    2357              : 
    2358              :   /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE.  */
    2359       249962 :   if (flag_generate_lto || flag_generate_offload)
    2360        23551 :     lto_streamer_hooks_init ();
    2361              : 
    2362              :   /* Don't run the IPA passes if there was any error or sorry messages.  */
    2363       249962 :   if (!seen_error ())
    2364              :   {
    2365       249962 :     timevar_start (TV_CGRAPH_IPA_PASSES);
    2366       249962 :     ipa_passes ();
    2367       249962 :     timevar_stop (TV_CGRAPH_IPA_PASSES);
    2368              :   }
    2369              :   /* Do nothing else if any IPA pass found errors or if we are just streaming LTO.  */
    2370       249962 :   if (seen_error ()
    2371       249962 :       || ((!in_lto_p || flag_incremental_link == INCREMENTAL_LINK_LTO)
    2372       236989 :           && flag_lto && !flag_fat_lto_objects))
    2373              :     {
    2374        12301 :       timevar_pop (TV_CGRAPHOPT);
    2375        12301 :       return;
    2376              :     }
    2377              : 
    2378       237661 :   global_info_ready = true;
    2379       237661 :   if (dump_file)
    2380              :     {
    2381           72 :       fprintf (dump_file, "Optimized ");
    2382           72 :       symtab->dump (dump_file);
    2383              :     }
    2384       237661 :   if (post_ipa_mem_report)
    2385            0 :     dump_memory_report ("Memory consumption after IPA");
    2386       237661 :   timevar_pop (TV_CGRAPHOPT);
    2387              : 
    2388              :   /* Output everything.  */
    2389       237661 :   switch_to_section (text_section);
    2390       237661 :   (*debug_hooks->assembly_start) ();
    2391       237661 :   if (!quiet_flag)
    2392            0 :     fprintf (stderr, "Assembling functions:\n");
    2393       237661 :   symtab_node::checking_verify_symtab_nodes ();
    2394              : 
    2395       237661 :   bitmap_obstack_initialize (NULL);
    2396       237661 :   execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
    2397       237661 :   bitmap_obstack_release (NULL);
    2398       237661 :   mark_functions_to_output ();
    2399              : 
    2400              :   /* When weakref support is missing, we automatically translate all
    2401              :      references to NODE to references to its ultimate alias target.
    2402              :      The renaming mechanism uses flag IDENTIFIER_TRANSPARENT_ALIAS and
    2403              :      TREE_CHAIN.
    2404              : 
    2405              :      Set up this mapping before we output any assembler but once we are sure
    2406              :      that all symbol renaming is done.
    2407              : 
    2408              :      FIXME: All this ugliness can go away if we just do renaming at gimple
    2409              :      level by physically rewriting the IL.  At the moment we can only redirect
    2410              :      calls, so we need infrastructure for renaming references as well.  */
    2411              : #ifndef ASM_OUTPUT_WEAKREF
    2412              :   symtab_node *node;
    2413              : 
    2414              :   FOR_EACH_SYMBOL (node)
    2415              :     if (node->alias
    2416              :         && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
    2417              :       {
    2418              :         tree id = DECL_ASSEMBLER_NAME (node->decl);
    2419              :         gcc_assert (!IDENTIFIER_INTERNAL_P (id));
    2420              :         IDENTIFIER_TRANSPARENT_ALIAS (id) = 1;
    2421              :         TREE_CHAIN (id)
    2422              :            = (node->alias_target ? node->alias_target
    2423              :               : DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
    2424              :       }
    2425              : #endif
    2426              : 
    2427       237661 :   state = EXPANSION;
    2428              : 
    2429              :   /* Output first asm statements and anything ordered. The process
    2430              :      flag is cleared for these nodes, so we skip them later.  */
    2431       237661 :   output_in_order ();
    2432              : 
    2433       237651 :   timevar_start (TV_CGRAPH_FUNC_EXPANSION);
    2434       237651 :   expand_all_functions ();
    2435       237651 :   timevar_stop (TV_CGRAPH_FUNC_EXPANSION);
    2436              : 
    2437       237651 :   output_variables ();
    2438              : 
    2439       237651 :   process_new_functions ();
    2440       237651 :   state = FINISHED;
    2441       237651 :   output_weakrefs ();
    2442              : 
    2443       237651 :   if (dump_file)
    2444              :     {
    2445           72 :       fprintf (dump_file, "\nFinal ");
    2446           72 :       symtab->dump (dump_file);
    2447              :     }
    2448       237651 :   if (!flag_checking)
    2449              :     return;
    2450       237637 :   symtab_node::verify_symtab_nodes ();
    2451              :   /* Double check that all inline clones are gone and that all
    2452              :      function bodies have been released from memory.  */
    2453       237637 :   if (!seen_error ())
    2454              :     {
    2455       237350 :       cgraph_node *node;
    2456       237350 :       bool error_found = false;
    2457              : 
    2458      1811421 :       FOR_EACH_DEFINED_FUNCTION (node)
    2459      1574071 :         if (node->inlined_to
    2460      1574071 :             || gimple_has_body_p (node->decl))
    2461              :           {
    2462          110 :             if (DECL_STRUCT_FUNCTION (node->decl)
    2463          110 :                 && (DECL_STRUCT_FUNCTION (node->decl)->curr_properties
    2464          110 :                     & PROP_assumptions_done) != 0)
    2465          110 :               continue;
    2466            0 :             error_found = true;
    2467            0 :             node->debug ();
    2468              :           }
    2469       237350 :       if (error_found)
    2470            0 :         internal_error ("nodes with unreleased memory found");
    2471              :     }
    2472              : }
    2473              : 
    2474              : /* Earlydebug dump file, flags, and number.  */
    2475              : 
    2476              : static int debuginfo_early_dump_nr;
    2477              : static FILE *debuginfo_early_dump_file;
    2478              : static dump_flags_t debuginfo_early_dump_flags;
    2479              : 
    2480              : /* Debug dump file, flags, and number.  */
    2481              : 
    2482              : static int debuginfo_dump_nr;
    2483              : static FILE *debuginfo_dump_file;
    2484              : static dump_flags_t debuginfo_dump_flags;
    2485              : 
    2486              : /* Register the debug and earlydebug dump files.  */
    2487              : 
    2488              : void
    2489       294587 : debuginfo_early_init (void)
    2490              : {
    2491       294587 :   gcc::dump_manager *dumps = g->get_dumps ();
    2492       294587 :   debuginfo_early_dump_nr = dumps->dump_register (".earlydebug", "earlydebug",
    2493              :                                                   "earlydebug", DK_tree,
    2494              :                                                   OPTGROUP_NONE,
    2495              :                                                   false);
    2496       294587 :   debuginfo_dump_nr = dumps->dump_register (".debug", "debug",
    2497              :                                              "debug", DK_tree,
    2498              :                                              OPTGROUP_NONE,
    2499              :                                              false);
    2500       294587 : }
    2501              : 
    2502              : /* Initialize the debug and earlydebug dump files.  */
    2503              : 
    2504              : void
    2505       286955 : debuginfo_init (void)
    2506              : {
    2507       286955 :   gcc::dump_manager *dumps = g->get_dumps ();
    2508       286955 :   debuginfo_dump_file = dump_begin (debuginfo_dump_nr, NULL);
    2509       286955 :   debuginfo_dump_flags = dumps->get_dump_file_info (debuginfo_dump_nr)->pflags;
    2510       286955 :   debuginfo_early_dump_file = dump_begin (debuginfo_early_dump_nr, NULL);
    2511       286955 :   debuginfo_early_dump_flags
    2512       286955 :     = dumps->get_dump_file_info (debuginfo_early_dump_nr)->pflags;
    2513       286955 : }
    2514              : 
    2515              : /* Finalize the debug and earlydebug dump files.  */
    2516              : 
    2517              : void
    2518       285052 : debuginfo_fini (void)
    2519              : {
    2520       285052 :   if (debuginfo_dump_file)
    2521           49 :     dump_end (debuginfo_dump_nr, debuginfo_dump_file);
    2522       285052 :   if (debuginfo_early_dump_file)
    2523           49 :     dump_end (debuginfo_early_dump_nr, debuginfo_early_dump_file);
    2524       285052 : }
    2525              : 
    2526              : /* Set dump_file to the debug dump file.  */
    2527              : 
    2528              : void
    2529       237364 : debuginfo_start (void)
    2530              : {
    2531       237364 :   set_dump_file (debuginfo_dump_file);
    2532       237364 : }
    2533              : 
    2534              : /* Undo setting dump_file to the debug dump file.  */
    2535              : 
    2536              : void
    2537       237364 : debuginfo_stop (void)
    2538              : {
    2539       237364 :   set_dump_file (NULL);
    2540       237364 : }
    2541              : 
    2542              : /* Set dump_file to the earlydebug dump file.  */
    2543              : 
    2544              : void
    2545       249962 : debuginfo_early_start (void)
    2546              : {
    2547       249962 :   set_dump_file (debuginfo_early_dump_file);
    2548       249962 : }
    2549              : 
    2550              : /* Undo setting dump_file to the earlydebug dump file.  */
    2551              : 
    2552              : void
    2553       249962 : debuginfo_early_stop (void)
    2554              : {
    2555       249962 :   set_dump_file (NULL);
    2556       249962 : }
    2557              : 
    2558              : /* Analyze the whole compilation unit once it is parsed completely.  */
    2559              : 
    2560              : void
    2561       263573 : symbol_table::finalize_compilation_unit (void)
    2562              : {
    2563       263573 :   timevar_push (TV_CGRAPH);
    2564              : 
    2565              :   /* If we're here there's no current function anymore.  Some frontends
    2566              :      are lazy in clearing these.  */
    2567       263573 :   current_function_decl = NULL;
    2568       263573 :   set_cfun (NULL);
    2569              : 
    2570              :   /* Do not skip analyzing the functions if there were errors, we
    2571              :      miss diagnostics for following functions otherwise.  */
    2572              : 
    2573              :   /* Emit size functions we didn't inline.  */
    2574       263573 :   finalize_size_functions ();
    2575              : 
    2576              :   /* Mark alias targets necessary and emit diagnostics.  */
    2577       263573 :   handle_alias_pairs ();
    2578              : 
    2579       263573 :   if (!quiet_flag)
    2580              :     {
    2581            0 :       fprintf (stderr, "\nAnalyzing compilation unit\n");
    2582            0 :       fflush (stderr);
    2583              :     }
    2584              : 
    2585       263573 :   if (flag_dump_passes)
    2586            5 :     dump_passes ();
    2587              : 
    2588       263573 :   analyze_toplevel_extended_asm ();
    2589              : 
    2590              :   /* Gimplify and lower all functions, compute reachability and
    2591              :      remove unreachable nodes.  */
    2592       263573 :   analyze_functions (/*first_time=*/true);
    2593              : 
    2594              :   /* Mark alias targets necessary and emit diagnostics.  */
    2595       263560 :   handle_alias_pairs ();
    2596              : 
    2597              :   /* Gimplify and lower thunks.  */
    2598       263560 :   analyze_functions (/*first_time=*/false);
    2599              : 
    2600              :   /* All nested functions should be lowered now.  */
    2601       263560 :   nested_function_info::release ();
    2602              : 
    2603              :   /* Offloading requires LTO infrastructure.  */
    2604       263560 :   if (!in_lto_p && g->have_offload)
    2605            0 :     flag_generate_offload = 1;
    2606              : 
    2607       263560 :   if (!seen_error ())
    2608              :     {
    2609       237109 :       timevar_push (TV_SYMOUT);
    2610              : 
    2611              :       /* Give the frontends the chance to emit early debug based on
    2612              :          what is still reachable in the TU.  */
    2613       237109 :       (*lang_hooks.finalize_early_debug) ();
    2614              : 
    2615              :       /* Clean up anything that needs cleaning up after initial debug
    2616              :          generation.  */
    2617       237109 :       debuginfo_early_start ();
    2618       237109 :       (*debug_hooks->early_finish) (main_input_filename);
    2619       237109 :       debuginfo_early_stop ();
    2620              : 
    2621       237109 :       timevar_pop (TV_SYMOUT);
    2622              :     }
    2623              : 
    2624              :   /* Finally drive the pass manager.  */
    2625       263560 :   compile ();
    2626              : 
    2627       263550 :   timevar_pop (TV_CGRAPH);
    2628       263550 : }
    2629              : 
    2630              : /* Reset all state within cgraphunit.cc so that we can rerun the compiler
    2631              :    within the same process.  For use by toplev::finalize.  */
    2632              : 
    2633              : void
    2634       264541 : cgraphunit_cc_finalize (void)
    2635              : {
    2636       264541 :   gcc_assert (cgraph_new_nodes.length () == 0);
    2637       264541 :   cgraph_new_nodes.truncate (0);
    2638              : 
    2639       264541 :   queued_nodes = &symtab_terminator;
    2640              : 
    2641       264541 :   first_analyzed = NULL;
    2642       264541 :   first_analyzed_var = NULL;
    2643       264541 : }
    2644              : 
    2645              : /* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this
    2646              :    kind of wrapper method.  */
    2647              : 
    2648              : void
    2649        18605 : cgraph_node::create_wrapper (cgraph_node *target)
    2650              : {
    2651              :   /* Preserve DECL_RESULT so we get right by reference flag.  */
    2652        18605 :   tree decl_result = DECL_RESULT (decl);
    2653              : 
    2654              :   /* Remove the function's body but keep arguments to be reused
    2655              :      for thunk.  */
    2656        18605 :   release_body (true);
    2657        18605 :   reset ();
    2658              : 
    2659        18605 :   DECL_UNINLINABLE (decl) = false;
    2660        18605 :   DECL_RESULT (decl) = decl_result;
    2661        18605 :   DECL_INITIAL (decl) = NULL;
    2662        18605 :   allocate_struct_function (decl, false);
    2663        18605 :   set_cfun (NULL);
    2664              : 
    2665              :   /* Turn alias into thunk and expand it into GIMPLE representation.  */
    2666        18605 :   definition = true;
    2667        18605 :   semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
    2668              : 
    2669              :   /* Create empty thunk, but be sure we did not keep former thunk around.
    2670              :      In that case we would need to preserve the info.  */
    2671        18605 :   gcc_checking_assert (!thunk_info::get (this));
    2672        18605 :   thunk_info::get_create (this);
    2673        18605 :   thunk = true;
    2674        18605 :   create_edge (target, NULL, count);
    2675        18605 :   callees->can_throw_external = !TREE_NOTHROW (target->decl);
    2676              : 
    2677        18605 :   tree arguments = DECL_ARGUMENTS (decl);
    2678              : 
    2679        51051 :   while (arguments)
    2680              :     {
    2681        32446 :       TREE_ADDRESSABLE (arguments) = false;
    2682        32446 :       arguments = TREE_CHAIN (arguments);
    2683              :     }
    2684              : 
    2685              :   /* Forced GIMPLE thunks are normally ignored because they are created
    2686              :      after early debug.  ICF wrappers retain the original function decl and
    2687              :      its early DIE, so preserve its original debug state.  */
    2688        18605 :   bool ignored_p = DECL_IGNORED_P (decl);
    2689        18605 :   expand_thunk (this, false, true);
    2690        18605 :   DECL_IGNORED_P (decl) = ignored_p;
    2691        18605 :   thunk_info::remove (this);
    2692              : 
    2693              :   /* Inline summary set-up.  */
    2694        18605 :   analyze ();
    2695        18605 :   inline_analyze_function (this);
    2696        18605 : }
        

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.