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

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.