LCOV - code coverage report
Current view: top level - gcc - passes.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 80.4 % 1322 1063
Test Date: 2026-02-28 14:20:25 Functions: 88.0 % 108 95
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Top level of GCC compilers (cc1, cc1plus, etc.)
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : /* This is the top level of cc1/c++.
      21              :    It parses command args, opens files, invokes the various passes
      22              :    in the proper order, and counts the time used by each.
      23              :    Error messages and low-level interface to malloc also handled here.  */
      24              : 
      25              : #define INCLUDE_LIST
      26              : #include "config.h"
      27              : #include "system.h"
      28              : #include "coretypes.h"
      29              : #include "backend.h"
      30              : #include "target.h"
      31              : #include "rtl.h"
      32              : #include "tree.h"
      33              : #include "gimple.h"
      34              : #include "cfghooks.h"
      35              : #include "df.h"
      36              : #include "memmodel.h"
      37              : #include "tm_p.h"
      38              : #include "ssa.h"
      39              : #include "emit-rtl.h"
      40              : #include "cgraph.h"
      41              : #include "lto-streamer.h"
      42              : #include "fold-const.h"
      43              : #include "varasm.h"
      44              : #include "output.h"
      45              : #include "graph.h"
      46              : #include "debug.h"
      47              : #include "cfgloop.h"
      48              : #include "value-prof.h"
      49              : #include "tree-cfg.h"
      50              : #include "tree-ssa-loop-manip.h"
      51              : #include "tree-into-ssa.h"
      52              : #include "tree-dfa.h"
      53              : #include "tree-ssa.h"
      54              : #include "tree-pass.h"
      55              : #include "plugin.h"
      56              : #include "ipa-utils.h"
      57              : #include "tree-pretty-print.h" /* for dump_function_header */
      58              : #include "context.h"
      59              : #include "pass_manager.h"
      60              : #include "cfgrtl.h"
      61              : #include "tree-ssa-live.h"  /* For remove_unused_locals.  */
      62              : #include "tree-cfgcleanup.h"
      63              : #include "insn-addr.h" /* for INSN_ADDRESSES_ALLOC.  */
      64              : #include "diagnostic-core.h" /* for fnotice */
      65              : #include "stringpool.h"
      66              : #include "attribs.h"
      67              : #include "topics/pass-events.h"
      68              : #include "channels.h"
      69              : 
      70              : /* Reserved TODOs */
      71              : #define TODO_verify_il                  (1u << 31)
      72              : 
      73              : using namespace gcc;
      74              : 
      75              : /* This is used for debugging.  It allows the current pass to printed
      76              :    from anywhere in compilation.
      77              :    The variable current_pass is also used for statistics and plugins.  */
      78              : opt_pass *current_pass;
      79              : 
      80              : /* Most passes are single-instance (within their context) and thus don't
      81              :    need to implement cloning, but passes that support multiple instances
      82              :    *must* provide their own implementation of the clone method.
      83              : 
      84              :    Handle this by providing a default implemenation, but make it a fatal
      85              :    error to call it.  */
      86              : 
      87              : opt_pass *
      88            0 : opt_pass::clone ()
      89              : {
      90            0 :   internal_error ("pass %s does not support cloning", name);
      91              : }
      92              : 
      93              : void
      94            0 : opt_pass::set_pass_param (unsigned int, bool)
      95              : {
      96            0 :   internal_error ("pass %s needs a %<set_pass_param%> implementation "
      97              :                   "to handle the extra argument in %<NEXT_PASS%>", name);
      98              : }
      99              : 
     100              : bool
     101    108192016 : opt_pass::gate (function *)
     102              : {
     103    108192016 :   return true;
     104              : }
     105              : 
     106              : unsigned int
     107     15340769 : opt_pass::execute (function *)
     108              : {
     109     15340769 :   return 0;
     110              : }
     111              : 
     112    112574691 : opt_pass::opt_pass (const pass_data &data, context *ctxt)
     113              :   : pass_data (data),
     114    112574691 :     sub (NULL),
     115    112574691 :     next (NULL),
     116    112574691 :     static_pass_number (0),
     117    112574691 :     m_ctxt (ctxt)
     118              : {
     119    112574691 : }
     120              : 
     121              : 
     122              : void
     123         4802 : pass_manager::execute_early_local_passes ()
     124              : {
     125         4802 :   execute_pass_list (cfun, m_pass_build_ssa_passes_1->sub);
     126         4802 :   execute_pass_list (cfun, m_pass_local_optimization_passes_1->sub);
     127         4802 : }
     128              : 
     129              : unsigned int
     130        74443 : pass_manager::execute_pass_mode_switching ()
     131              : {
     132        74443 :   return m_pass_mode_switching_1->execute (cfun);
     133              : }
     134              : 
     135              : 
     136              : /* Call from anywhere to find out what pass this is.  Useful for
     137              :    printing out debugging information deep inside an service
     138              :    routine.  */
     139              : void
     140            0 : print_current_pass (FILE *file)
     141              : {
     142            0 :   if (current_pass)
     143            0 :     fprintf (file, "current pass = %s (%d)\n",
     144              :              current_pass->name, current_pass->static_pass_number);
     145              :   else
     146            0 :     fprintf (file, "no current pass.\n");
     147            0 : }
     148              : 
     149              : 
     150              : /* Call from the debugger to get the current pass name.  */
     151              : DEBUG_FUNCTION void
     152            0 : debug_pass (void)
     153              : {
     154            0 :   print_current_pass (stderr);
     155            0 : }
     156              : 
     157              : 
     158              : 
     159              : /* Global variables used to communicate with passes.  */
     160              : bool in_gimple_form;
     161              : 
     162              : 
     163              : /* This is called from various places for FUNCTION_DECL, VAR_DECL,
     164              :    and TYPE_DECL nodes.
     165              : 
     166              :    This does nothing for local (non-static) variables, unless the
     167              :    variable is a register variable with DECL_ASSEMBLER_NAME set.  In
     168              :    that case, or if the variable is not an automatic, it sets up the
     169              :    RTL and outputs any assembler code (label definition, storage
     170              :    allocation and initialization).
     171              : 
     172              :    DECL is the declaration.  TOP_LEVEL is nonzero
     173              :    if this declaration is not within a function.  */
     174              : 
     175              : void
     176    452141885 : rest_of_decl_compilation (tree decl,
     177              :                           int top_level,
     178              :                           int at_end)
     179              : {
     180    452141885 :   bool finalize = true;
     181              : 
     182              :   /* We deferred calling assemble_alias so that we could collect
     183              :      other attributes such as visibility.  Emit the alias now.  */
     184    452141885 :   if (!in_lto_p)
     185              :   {
     186    451900516 :     tree alias;
     187    451900516 :     alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
     188    451900516 :     if (alias)
     189              :       {
     190         5674 :         alias = TREE_VALUE (TREE_VALUE (alias));
     191         5674 :         alias = get_identifier (TREE_STRING_POINTER (alias));
     192              :         /* A quirk of the initial implementation of aliases required that the
     193              :            user add "extern" to all of them.  Which is silly, but now
     194              :            historical.  Do note that the symbol is in fact locally defined.  */
     195         5674 :         DECL_EXTERNAL (decl) = 0;
     196         5674 :         TREE_STATIC (decl) = 1;
     197         5674 :         assemble_alias (decl, alias);
     198         5674 :         finalize = false;
     199              :       }
     200              :   }
     201              : 
     202              :   /* Can't defer this, because it needs to happen before any
     203              :      later function definitions are processed.  */
     204    452141885 :   if (HAS_DECL_ASSEMBLER_NAME_P (decl)
     205    452141884 :       && DECL_ASSEMBLER_NAME_SET_P (decl)
     206    480354462 :       && DECL_REGISTER (decl))
     207         1274 :     make_decl_rtl (decl);
     208              : 
     209              :   /* Forward declarations for nested functions are not "external",
     210              :      but we need to treat them as if they were.  */
     211    412024047 :   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
     212    469435276 :       || TREE_CODE (decl) == FUNCTION_DECL)
     213              :     {
     214    435073524 :       timevar_push (TV_VARCONST);
     215              : 
     216              :       /* Don't output anything when a tentative file-scope definition
     217              :          is seen.  But at end of compilation, do output code for them.
     218              : 
     219              :          We do output all variables and rely on
     220              :          callgraph code to defer them except for forward declarations
     221              :          (see gcc.c-torture/compile/920624-1.c) */
     222    435073524 :       if ((at_end
     223    237685080 :            || !DECL_DEFER_OUTPUT (decl)
     224     15691304 :            || DECL_INITIAL (decl))
     225    419393737 :           && (!VAR_P (decl) || !DECL_HAS_VALUE_EXPR_P (decl))
     226    854466544 :           && !DECL_EXTERNAL (decl))
     227              :         {
     228              :           /* When reading LTO unit, we also read varpool, so do not
     229              :              rebuild it.  */
     230     36352326 :           if (in_lto_p && !at_end)
     231              :             ;
     232     36148445 :           else if (finalize && TREE_CODE (decl) != FUNCTION_DECL)
     233     35474216 :             varpool_node::finalize_decl (decl);
     234              :         }
     235              : 
     236              : #ifdef ASM_FINISH_DECLARE_OBJECT
     237    435073524 :       if (decl == last_assemble_variable_decl)
     238              :         {
     239            0 :           ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
     240              :                                      top_level, at_end);
     241              :         }
     242              : #endif
     243              : 
     244              :       /* Now that we have activated any function-specific attributes
     245              :          that might affect function decl, particularly align, relayout it.  */
     246    435073524 :       if (TREE_CODE (decl) == FUNCTION_DECL)
     247    394176617 :         targetm.target_option.relayout_function (decl);
     248              : 
     249    435073524 :       timevar_pop (TV_VARCONST);
     250              :     }
     251     17068361 :   else if (TREE_CODE (decl) == TYPE_DECL
     252              :            /* Like in rest_of_type_compilation, avoid confusing the debug
     253              :               information machinery when there are errors.  */
     254     17068361 :            && !seen_error ())
     255              :     {
     256     16882336 :       timevar_push (TV_SYMOUT);
     257     16882336 :       debug_hooks->type_decl (decl, !top_level);
     258     16882336 :       timevar_pop (TV_SYMOUT);
     259              :     }
     260              : 
     261              :   /* Let cgraph know about the existence of variables.  */
     262    452141885 :   if (in_lto_p && !at_end)
     263              :     ;
     264     40163885 :   else if (VAR_P (decl) && !DECL_EXTERNAL (decl)
     265    488200582 :            && TREE_STATIC (decl))
     266     36298878 :     varpool_node::get_create (decl);
     267              : 
     268              :   /* Generate early debug for global variables.  Any local variables will
     269              :      be handled by either handling reachable functions from
     270              :      finalize_compilation_unit (and by consequence, locally scoped
     271              :      symbols), or by rest_of_type_compilation below.
     272              : 
     273              :      For Go's hijack of the debug_hooks to implement -fdump-go-spec, pick up
     274              :      function prototypes.  Go's debug_hooks will not forward them to the
     275              :      wrapped hooks.  */
     276    452141885 :   if (!in_lto_p
     277    451900516 :       && (TREE_CODE (decl) != FUNCTION_DECL
     278              :           /* This will pick up function prototypes with no bodies,
     279              :              which are not visible in finalize_compilation_unit()
     280              :              while iterating with FOR_EACH_*_FUNCTION through the
     281              :              symbol table.  */
     282    394006978 :           || (flag_dump_go_spec != NULL
     283         1898 :               && !DECL_SAVED_TREE (decl)
     284         1898 :               && DECL_STRUCT_FUNCTION (decl) == NULL))
     285              : 
     286              :       /* We need to check both decl_function_context and
     287              :          current_function_decl here to make sure local extern
     288              :          declarations end up with the correct context.
     289              : 
     290              :          For local extern declarations, decl_function_context is
     291              :          empty, but current_function_decl is set to the function where
     292              :          the extern was declared .  Without the check for
     293              :          !current_function_decl below, the local extern ends up
     294              :          incorrectly with a top-level context.
     295              : 
     296              :          For example:
     297              : 
     298              :          namespace S
     299              :          {
     300              :            int
     301              :            f()
     302              :            {
     303              :              {
     304              :                int i = 42;
     305              :                {
     306              :                  extern int i; // Local extern declaration.
     307              :                  return i;
     308              :                }
     309              :              }
     310              :            }
     311              :          }
     312              :       */
     313     57895436 :       && !decl_function_context (decl)
     314     53802797 :       && !current_function_decl
     315     53745789 :       && DECL_SOURCE_LOCATION (decl) != BUILTINS_LOCATION
     316     51010451 :       && (!decl_type_context (decl)
     317              :           /* If we created a varpool node for the decl make sure to
     318              :              call early_global_decl.  Otherwise we miss changes
     319              :              introduced by member definitions like
     320              :                 struct A { static int staticdatamember; };
     321              :                 int A::staticdatamember;
     322              :              and thus have incomplete early debug and late debug
     323              :              called from varpool node removal fails to handle it
     324              :              properly.  */
     325     14285236 :           || (finalize
     326     14285233 :               && VAR_P (decl)
     327     12660540 :               && TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
     328              :       /* Avoid confusing the debug information machinery when there are
     329              :          errors.  */
     330    500298404 :       && !seen_error ())
     331     47126102 :     (*debug_hooks->early_global_decl) (decl);
     332    452141885 : }
     333              : 
     334              : /* Called after finishing a record, union or enumeral type.  */
     335              : 
     336              : void
     337     59973198 : rest_of_type_compilation (tree type, int toplev)
     338              : {
     339              :   /* Avoid confusing the debug information machinery when there are
     340              :      errors.  */
     341     59973198 :   if (seen_error ())
     342              :     return;
     343              : 
     344     59059922 :   timevar_push (TV_SYMOUT);
     345     59059922 :   debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev);
     346     59059922 :   timevar_pop (TV_SYMOUT);
     347              : }
     348              : 
     349              : 
     350              : 
     351              : void
     352       276762 : pass_manager::
     353              : finish_optimization_passes (void)
     354              : {
     355       276762 :   int i;
     356       276762 :   struct dump_file_info *dfi;
     357       276762 :   char *name;
     358       276762 :   gcc::dump_manager *dumps = m_ctxt->get_dumps ();
     359              : 
     360       276762 :   timevar_push (TV_DUMP);
     361              : 
     362              :   /* Do whatever is necessary to finish printing the graphs.  */
     363    102389133 :   for (i = TDI_end; (dfi = dumps->get_dump_file_info (i)) != NULL; ++i)
     364    101835609 :     if (dfi->graph_dump_initialized)
     365              :       {
     366          165 :         name = dumps->get_dump_file_name (dfi);
     367          165 :         finish_graph_dump_file (name);
     368          165 :         free (name);
     369              :       }
     370              : 
     371       276762 :   timevar_pop (TV_DUMP);
     372       276762 : }
     373              : 
     374              : static unsigned int
     375       229887 : execute_build_ssa_passes (void)
     376              : {
     377              :   /* Once this pass (and its sub-passes) are complete, all functions
     378              :      will be in SSA form.  Technically this state change is happening
     379              :      a tad early, since the sub-passes have not yet run, but since
     380              :      none of the sub-passes are IPA passes and do not create new
     381              :      functions, this is ok.  We're setting this value for the benefit
     382              :      of IPA passes that follow.  */
     383            0 :   if (symtab->state < IPA_SSA)
     384       229887 :     symtab->state = IPA_SSA;
     385       229887 :   return 0;
     386              : }
     387              : 
     388              : namespace {
     389              : 
     390              : const pass_data pass_data_build_ssa_passes =
     391              : {
     392              :   SIMPLE_IPA_PASS, /* type */
     393              :   "build_ssa_passes", /* name */
     394              :   OPTGROUP_NONE, /* optinfo_flags */
     395              :   TV_EARLY_LOCAL, /* tv_id */
     396              :   0, /* properties_required */
     397              :   0, /* properties_provided */
     398              :   0, /* properties_destroyed */
     399              :   0, /* todo_flags_start */
     400              :   /* todo_flags_finish is executed before subpases. For this reason
     401              :      it makes no sense to remove unreachable functions here.  */
     402              :   0, /* todo_flags_finish */
     403              : };
     404              : 
     405              : class pass_build_ssa_passes : public simple_ipa_opt_pass
     406              : {
     407              : public:
     408       285722 :   pass_build_ssa_passes (gcc::context *ctxt)
     409       571444 :     : simple_ipa_opt_pass (pass_data_build_ssa_passes, ctxt)
     410              :   {}
     411              : 
     412              :   /* opt_pass methods: */
     413       229960 :   bool gate (function *) final override
     414              :     {
     415              :       /* Don't bother doing anything if the program has errors.  */
     416       229960 :       return (!seen_error () && !in_lto_p);
     417              :     }
     418              : 
     419       229887 :   unsigned int execute (function *) final override
     420              :     {
     421       229887 :       return execute_build_ssa_passes ();
     422              :     }
     423              : 
     424              : }; // class pass_build_ssa_passes
     425              : 
     426              : const pass_data pass_data_local_optimization_passes =
     427              : {
     428              :   SIMPLE_IPA_PASS, /* type */
     429              :   "opt_local_passes", /* name */
     430              :   OPTGROUP_NONE, /* optinfo_flags */
     431              :   TV_NONE, /* tv_id */
     432              :   0, /* properties_required */
     433              :   0, /* properties_provided */
     434              :   0, /* properties_destroyed */
     435              :   0, /* todo_flags_start */
     436              :   0, /* todo_flags_finish */
     437              : };
     438              : 
     439              : class pass_local_optimization_passes : public simple_ipa_opt_pass
     440              : {
     441              : public:
     442       285722 :   pass_local_optimization_passes (gcc::context *ctxt)
     443       571444 :     : simple_ipa_opt_pass (pass_data_local_optimization_passes, ctxt)
     444              :   {}
     445              : 
     446              :   /* opt_pass methods: */
     447       229960 :   bool gate (function *) final override
     448              :     {
     449              :       /* Don't bother doing anything if the program has errors.  */
     450       229960 :       return (!seen_error () && !in_lto_p);
     451              :     }
     452              : 
     453              : }; // class pass_local_optimization_passes
     454              : 
     455              : const pass_data pass_data_ipa_remove_symbols =
     456              : {
     457              :   SIMPLE_IPA_PASS, /* type */
     458              :   "remove_symbols", /* name */
     459              :   OPTGROUP_NONE, /* optinfo_flags */
     460              :   TV_NONE, /* tv_id */
     461              :   0, /* properties_required */
     462              :   0, /* properties_provided */
     463              :   0, /* properties_destroyed */
     464              :   0, /* todo_flags_start */
     465              :   TODO_remove_functions | TODO_dump_symtab, /* todo_flags_finish */
     466              : };
     467              : 
     468              : class pass_ipa_remove_symbols : public simple_ipa_opt_pass
     469              : {
     470              : public:
     471       285722 :   pass_ipa_remove_symbols (gcc::context *ctxt)
     472       571444 :     : simple_ipa_opt_pass (pass_data_ipa_remove_symbols, ctxt)
     473              :   {}
     474              : 
     475              :   /* opt_pass methods: */
     476       229960 :   bool gate (function *) final override
     477              :     {
     478              :       /* Don't bother doing anything if the program has errors.  */
     479       229960 :       return (!seen_error () && !in_lto_p);
     480              :     }
     481              : 
     482              : }; // class pass_local_optimization_passes
     483              : 
     484              : } // anon namespace
     485              : 
     486              : simple_ipa_opt_pass *
     487       285722 : make_pass_build_ssa_passes (gcc::context *ctxt)
     488              : {
     489       285722 :   return new pass_build_ssa_passes (ctxt);
     490              : }
     491              : 
     492              : simple_ipa_opt_pass *
     493       285722 : make_pass_local_optimization_passes (gcc::context *ctxt)
     494              : {
     495       285722 :   return new pass_local_optimization_passes (ctxt);
     496              : }
     497              : 
     498              : simple_ipa_opt_pass *
     499       285722 : make_pass_ipa_remove_symbols (gcc::context *ctxt)
     500              : {
     501       285722 :   return new pass_ipa_remove_symbols (ctxt);
     502              : }
     503              : 
     504              : namespace {
     505              : 
     506              : const pass_data pass_data_all_early_optimizations =
     507              : {
     508              :   GIMPLE_PASS, /* type */
     509              :   "early_optimizations", /* name */
     510              :   OPTGROUP_NONE, /* optinfo_flags */
     511              :   TV_NONE, /* tv_id */
     512              :   0, /* properties_required */
     513              :   0, /* properties_provided */
     514              :   0, /* properties_destroyed */
     515              :   0, /* todo_flags_start */
     516              :   0, /* todo_flags_finish */
     517              : };
     518              : 
     519              : class pass_all_early_optimizations : public gimple_opt_pass
     520              : {
     521              : public:
     522       285722 :   pass_all_early_optimizations (gcc::context *ctxt)
     523       571444 :     : gimple_opt_pass (pass_data_all_early_optimizations, ctxt)
     524              :   {}
     525              : 
     526              :   /* opt_pass methods: */
     527      2848482 :   bool gate (function *) final override
     528              :     {
     529      2848482 :       return (optimize >= 1
     530              :               /* Don't bother doing anything if the program has errors.  */
     531      2848482 :               && !seen_error ());
     532              :     }
     533              : 
     534              : }; // class pass_all_early_optimizations
     535              : 
     536              : } // anon namespace
     537              : 
     538              : static gimple_opt_pass *
     539       285722 : make_pass_all_early_optimizations (gcc::context *ctxt)
     540              : {
     541       285722 :   return new pass_all_early_optimizations (ctxt);
     542              : }
     543              : 
     544              : namespace {
     545              : 
     546              : const pass_data pass_data_all_optimizations =
     547              : {
     548              :   GIMPLE_PASS, /* type */
     549              :   "*all_optimizations", /* name */
     550              :   OPTGROUP_NONE, /* optinfo_flags */
     551              :   TV_OPTIMIZE, /* tv_id */
     552              :   0, /* properties_required */
     553              :   0, /* properties_provided */
     554              :   0, /* properties_destroyed */
     555              :   0, /* todo_flags_start */
     556              :   0, /* todo_flags_finish */
     557              : };
     558              : 
     559              : class pass_all_optimizations : public gimple_opt_pass
     560              : {
     561              : public:
     562       285722 :   pass_all_optimizations (gcc::context *ctxt)
     563       571444 :     : gimple_opt_pass (pass_data_all_optimizations, ctxt)
     564              :   {}
     565              : 
     566              :   /* opt_pass methods: */
     567      1472258 :   bool gate (function *) final override
     568              :   {
     569      1472258 :     return optimize >= 1 && !optimize_debug;
     570              :   }
     571              : 
     572              : }; // class pass_all_optimizations
     573              : 
     574              : } // anon namespace
     575              : 
     576              : static gimple_opt_pass *
     577       285722 : make_pass_all_optimizations (gcc::context *ctxt)
     578              : {
     579       285722 :   return new pass_all_optimizations (ctxt);
     580              : }
     581              : 
     582              : namespace {
     583              : 
     584              : const pass_data pass_data_all_optimizations_g =
     585              : {
     586              :   GIMPLE_PASS, /* type */
     587              :   "*all_optimizations_g", /* name */
     588              :   OPTGROUP_NONE, /* optinfo_flags */
     589              :   TV_OPTIMIZE, /* tv_id */
     590              :   0, /* properties_required */
     591              :   0, /* properties_provided */
     592              :   0, /* properties_destroyed */
     593              :   0, /* todo_flags_start */
     594              :   0, /* todo_flags_finish */
     595              : };
     596              : 
     597              : class pass_all_optimizations_g : public gimple_opt_pass
     598              : {
     599              : public:
     600       285722 :   pass_all_optimizations_g (gcc::context *ctxt)
     601       571444 :     : gimple_opt_pass (pass_data_all_optimizations_g, ctxt)
     602              :   {}
     603              : 
     604              :   /* opt_pass methods: */
     605      1472258 :   bool gate (function *) final override
     606              :   {
     607      1472258 :     return optimize >= 1 && optimize_debug;
     608              :   }
     609              : 
     610              : }; // class pass_all_optimizations_g
     611              : 
     612              : } // anon namespace
     613              : 
     614              : static gimple_opt_pass *
     615       285722 : make_pass_all_optimizations_g (gcc::context *ctxt)
     616              : {
     617       285722 :   return new pass_all_optimizations_g (ctxt);
     618              : }
     619              : 
     620              : namespace {
     621              : 
     622              : const pass_data pass_data_rest_of_compilation =
     623              : {
     624              :   RTL_PASS, /* type */
     625              :   "*rest_of_compilation", /* name */
     626              :   OPTGROUP_NONE, /* optinfo_flags */
     627              :   TV_REST_OF_COMPILATION, /* tv_id */
     628              :   PROP_rtl, /* properties_required */
     629              :   0, /* properties_provided */
     630              :   0, /* properties_destroyed */
     631              :   0, /* todo_flags_start */
     632              :   0, /* todo_flags_finish */
     633              : };
     634              : 
     635              : class pass_rest_of_compilation : public rtl_opt_pass
     636              : {
     637              : public:
     638       285722 :   pass_rest_of_compilation (gcc::context *ctxt)
     639       571444 :     : rtl_opt_pass (pass_data_rest_of_compilation, ctxt)
     640              :   {}
     641              : 
     642              :   /* opt_pass methods: */
     643      1472162 :   bool gate (function *) final override
     644              :     {
     645              :       /* Early return if there were errors.  We can run afoul of our
     646              :          consistency checks, and there's not really much point in fixing them.  */
     647      1472162 :       return !(rtl_dump_and_exit || flag_syntax_only || seen_error ());
     648              :     }
     649              : 
     650              : }; // class pass_rest_of_compilation
     651              : 
     652              : } // anon namespace
     653              : 
     654              : static rtl_opt_pass *
     655       285722 : make_pass_rest_of_compilation (gcc::context *ctxt)
     656              : {
     657       285722 :   return new pass_rest_of_compilation (ctxt);
     658              : }
     659              : 
     660              : namespace {
     661              : 
     662              : /* A container pass (only) for '!targetm.no_register_allocation' targets, for
     663              :    passes to run if reload completed (..., but not run them if it failed, for
     664              :    example for an invalid 'asm').  See also 'pass_late_compilation'.  */
     665              : 
     666              : const pass_data pass_data_postreload =
     667              : {
     668              :   RTL_PASS, /* type */
     669              :   "*all-postreload", /* name */
     670              :   OPTGROUP_NONE, /* optinfo_flags */
     671              :   TV_POSTRELOAD, /* tv_id */
     672              :   PROP_rtl, /* properties_required */
     673              :   0, /* properties_provided */
     674              :   0, /* properties_destroyed */
     675              :   0, /* todo_flags_start */
     676              :   0, /* todo_flags_finish */
     677              : };
     678              : 
     679              : class pass_postreload : public rtl_opt_pass
     680              : {
     681              : public:
     682       285722 :   pass_postreload (gcc::context *ctxt)
     683       571444 :     : rtl_opt_pass (pass_data_postreload, ctxt)
     684              :   {}
     685              : 
     686              :   /* opt_pass methods: */
     687      1471370 :   bool gate (function *) final override
     688              :   {
     689      1471370 :     if (reload_completed)
     690      1471365 :       gcc_checking_assert (!targetm.no_register_allocation);
     691      1471370 :     return reload_completed;
     692              :   }
     693              : 
     694              : }; // class pass_postreload
     695              : 
     696              : } // anon namespace
     697              : 
     698              : static rtl_opt_pass *
     699       285722 : make_pass_postreload (gcc::context *ctxt)
     700              : {
     701       285722 :   return new pass_postreload (ctxt);
     702              : }
     703              : 
     704              : namespace {
     705              : 
     706              : /* A container pass like 'pass_postreload', but for passes to run also for
     707              :    'targetm.no_register_allocation' targets.  */
     708              : 
     709              : const pass_data pass_data_late_compilation =
     710              : {
     711              :   RTL_PASS, /* type */
     712              :   "*all-late_compilation", /* name */
     713              :   OPTGROUP_NONE, /* optinfo_flags */
     714              :   TV_LATE_COMPILATION, /* tv_id */
     715              :   PROP_rtl, /* properties_required */
     716              :   0, /* properties_provided */
     717              :   0, /* properties_destroyed */
     718              :   0, /* todo_flags_start */
     719              :   0, /* todo_flags_finish */
     720              : };
     721              : 
     722              : class pass_late_compilation : public rtl_opt_pass
     723              : {
     724              : public:
     725       285722 :   pass_late_compilation (gcc::context *ctxt)
     726       571444 :     : rtl_opt_pass (pass_data_late_compilation, ctxt)
     727              :   {}
     728              : 
     729              :   /* opt_pass methods: */
     730      1471370 :   bool gate (function *) final override
     731              :   {
     732      1471370 :     return reload_completed || targetm.no_register_allocation;
     733              :   }
     734              : 
     735              : }; // class pass_late_compilation
     736              : 
     737              : } // anon namespace
     738              : 
     739              : static rtl_opt_pass *
     740       285722 : make_pass_late_compilation (gcc::context *ctxt)
     741              : {
     742       285722 :   return new pass_late_compilation (ctxt);
     743              : }
     744              : 
     745              : /* Pre-SLP scalar cleanup, it has several cleanup passes like FRE, DSE.  */
     746              : 
     747              : namespace {
     748              : 
     749              : const pass_data pass_data_pre_slp_scalar_cleanup =
     750              : {
     751              :   GIMPLE_PASS, /* type */
     752              :   "*pre_slp_scalar_cleanup", /* name */
     753              :   OPTGROUP_LOOP, /* optinfo_flags */
     754              :   TV_SCALAR_CLEANUP, /* tv_id */
     755              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
     756              :   0, /* properties_provided */
     757              :   0, /* properties_destroyed */
     758              :   0, /* todo_flags_start */
     759              :   0, /* todo_flags_finish */
     760              : };
     761              : 
     762              : class pass_pre_slp_scalar_cleanup : public gimple_opt_pass
     763              : {
     764              : public:
     765       285722 :   pass_pre_slp_scalar_cleanup (gcc::context *ctxt)
     766       571444 :     : gimple_opt_pass (pass_data_pre_slp_scalar_cleanup, ctxt)
     767              :   {
     768              :   }
     769              : 
     770              :   bool
     771       241458 :   gate (function *fun) final override
     772              :   {
     773       241458 :     return flag_tree_slp_vectorize
     774       241458 :            && (fun->pending_TODOs & PENDING_TODO_force_next_scalar_cleanup);
     775              :   }
     776              : 
     777              :   unsigned int
     778        31959 :   execute (function *fun) final override
     779              :   {
     780        31959 :     fun->pending_TODOs &= ~PENDING_TODO_force_next_scalar_cleanup;
     781        31959 :     return 0;
     782              :   }
     783              : 
     784              : }; // class pass_pre_slp_scalar_cleanup
     785              : 
     786              : } // anon namespace
     787              : 
     788              : gimple_opt_pass *
     789       285722 : make_pass_pre_slp_scalar_cleanup (gcc::context *ctxt)
     790              : {
     791       285722 :   return new pass_pre_slp_scalar_cleanup (ctxt);
     792              : }
     793              : 
     794              : /* Set the static pass number of pass PASS to ID and record that
     795              :    in the mapping from static pass number to pass.  */
     796              : 
     797              : void
     798    103717259 : pass_manager::
     799              : set_pass_for_id (int id, opt_pass *pass)
     800              : {
     801    103717259 :   pass->static_pass_number = id;
     802    103717259 :   if (passes_by_id_size <= id)
     803              :     {
     804    103717259 :       passes_by_id = XRESIZEVEC (opt_pass *, passes_by_id, id + 1);
     805    103717259 :       memset (passes_by_id + passes_by_id_size, 0,
     806    103717259 :               (id + 1 - passes_by_id_size) * sizeof (void *));
     807    103717259 :       passes_by_id_size = id + 1;
     808              :     }
     809    103717259 :   passes_by_id[id] = pass;
     810    103717259 : }
     811              : 
     812              : /* Return the pass with the static pass number ID.  */
     813              : 
     814              : opt_pass *
     815           14 : pass_manager::get_pass_for_id (int id) const
     816              : {
     817           14 :   if (id >= passes_by_id_size)
     818              :     return NULL;
     819           14 :   return passes_by_id[id];
     820              : }
     821              : 
     822              : /* Iterate over the pass tree allocating dump file numbers.  We want
     823              :    to do this depth first, and independent of whether the pass is
     824              :    enabled or not.  */
     825              : 
     826              : void
     827          173 : register_one_dump_file (opt_pass *pass)
     828              : {
     829          173 :   g->get_passes ()->register_one_dump_file (pass);
     830          173 : }
     831              : 
     832              : void
     833    103717259 : pass_manager::register_one_dump_file (opt_pass *pass)
     834              : {
     835    103717259 :   char *dot_name, *flag_name, *glob_name;
     836    103717259 :   const char *name, *full_name, *prefix;
     837              : 
     838              :   /* Buffer big enough to format a 32-bit UINT_MAX into.  */
     839    103717259 :   char num[11];
     840    103717259 :   dump_kind dkind;
     841    103717259 :   int id;
     842    103717259 :   optgroup_flags_t optgroup_flags = OPTGROUP_NONE;
     843    103717259 :   gcc::dump_manager *dumps = m_ctxt->get_dumps ();
     844              : 
     845              :   /* See below in next_pass_1.  */
     846    103717259 :   num[0] = '\0';
     847    103717259 :   if (pass->static_pass_number != -1)
     848     62573118 :     sprintf (num, "%u", ((int) pass->static_pass_number < 0
     849              :                          ? 1 : pass->static_pass_number));
     850              : 
     851              :   /* The name is both used to identify the pass for the purposes of plugins,
     852              :      and to specify dump file name and option.
     853              :      The latter two might want something short which is not quite unique; for
     854              :      that reason, we may have a disambiguating prefix, followed by a space
     855              :      to mark the start of the following dump file name / option string.  */
     856    103717259 :   name = strchr (pass->name, ' ');
     857    103717259 :   name = name ? name + 1 : pass->name;
     858    103717259 :   dot_name = concat (".", name, num, NULL);
     859    103717259 :   if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
     860              :     {
     861              :       prefix = "ipa-";
     862              :       dkind = DK_ipa;
     863              :       optgroup_flags |= OPTGROUP_IPA;
     864              :     }
     865     92288366 :   else if (pass->type == GIMPLE_PASS)
     866              :     {
     867              :       prefix = "tree-";
     868              :       dkind = DK_tree;
     869              :     }
     870              :   else
     871              :     {
     872     28000756 :       prefix = "rtl-";
     873     28000756 :       dkind = DK_rtl;
     874              :     }
     875              : 
     876    103717259 :   flag_name = concat (prefix, name, num, NULL);
     877    103717259 :   glob_name = concat (prefix, name, NULL);
     878    103717259 :   optgroup_flags |= pass->optinfo_flags;
     879              :   /* For any passes that do not have an optgroup set, and which are not
     880              :      IPA passes setup above, set the optgroup to OPTGROUP_OTHER so that
     881              :      any dump messages are emitted properly under -fopt-info(-optall).  */
     882    103717259 :   if (optgroup_flags == OPTGROUP_NONE)
     883     76002210 :     optgroup_flags = OPTGROUP_OTHER;
     884    103717259 :   id = dumps->dump_register (dot_name, flag_name, glob_name, dkind,
     885              :                              optgroup_flags,
     886              :                              true);
     887    103717259 :   set_pass_for_id (id, pass);
     888    103717259 :   full_name = concat (prefix, pass->name, num, NULL);
     889    103717259 :   register_pass_name (pass, full_name);
     890    103717259 :   free (const_cast<char *> (full_name));
     891    103717259 : }
     892              : 
     893              : /* Register the dump files for the pass_manager starting at PASS. */
     894              : 
     895              : void
     896      7428772 : pass_manager::register_dump_files (opt_pass *pass)
     897              : {
     898    112574468 :   do
     899              :     {
     900    112574468 :       if (pass->name && pass->name[0] != '*')
     901    103717086 :         register_one_dump_file (pass);
     902              : 
     903    112574468 :       if (pass->sub)
     904      6000162 :         register_dump_files (pass->sub);
     905              : 
     906    112574468 :       pass = pass->next;
     907              :     }
     908    112574468 :   while (pass);
     909      7428772 : }
     910              : 
     911              : /* Register PASS with NAME.  */
     912              : 
     913              : void
     914    103717259 : pass_manager::register_pass_name (opt_pass *pass, const char *name)
     915              : {
     916    103717259 :   if (!m_name_to_pass_map)
     917       285722 :     m_name_to_pass_map = new hash_map<free_string_hash, opt_pass *> (256);
     918              : 
     919    103717259 :   if (m_name_to_pass_map->get (name))
     920       285723 :     return; /* Ignore plugin passes.  */
     921              : 
     922    103431536 :   const char *unique_name = xstrdup (name);
     923    103431536 :   m_name_to_pass_map->put (unique_name, pass);
     924              : }
     925              : 
     926              : /* Map from pass id to canonicalized pass name.  */
     927              : 
     928              : typedef const char *char_ptr;
     929              : static vec<char_ptr> pass_tab;
     930              : 
     931              : /* Callback function for traversing NAME_TO_PASS_MAP.  */
     932              : 
     933              : bool
     934         1810 : passes_pass_traverse (const char *const &name, opt_pass *const &pass, void *)
     935              : {
     936         1810 :   gcc_assert (pass->static_pass_number > 0);
     937         1810 :   gcc_assert (pass_tab.exists ());
     938              : 
     939         1810 :   pass_tab[pass->static_pass_number] = name;
     940              : 
     941         1810 :   return 1;
     942              : }
     943              : 
     944              : /* The function traverses NAME_TO_PASS_MAP and creates a pass info
     945              :    table for dumping purpose.  */
     946              : 
     947              : void
     948            5 : pass_manager::create_pass_tab (void) const
     949              : {
     950            5 :   if (!flag_dump_passes)
     951              :     return;
     952              : 
     953            5 :   pass_tab.safe_grow_cleared (passes_by_id_size + 1, true);
     954         1815 :   m_name_to_pass_map->traverse <void *, passes_pass_traverse> (NULL);
     955              : }
     956              : 
     957              : static bool override_gate_status (opt_pass *, tree, bool);
     958              : 
     959              : /* Dump the instantiated name for PASS. IS_ON indicates if PASS
     960              :    is turned on or not.  */
     961              : 
     962              : static void
     963         1970 : dump_one_pass (opt_pass *pass, int pass_indent)
     964              : {
     965         1970 :   int indent = 3 * pass_indent;
     966         1970 :   const char *pn;
     967         1970 :   bool is_on, is_really_on;
     968              : 
     969         1970 :   is_on = pass->gate (cfun);
     970         1970 :   is_really_on = override_gate_status (pass, current_function_decl, is_on);
     971              : 
     972         1970 :   if (pass->static_pass_number <= 0)
     973          155 :     pn = pass->name;
     974              :   else
     975         1815 :     pn = pass_tab[pass->static_pass_number];
     976              : 
     977         3087 :   fprintf (stderr, "%*s%-40s%*s:%s%s\n", indent, " ", pn,
     978              :            (15 - indent < 0 ? 0 : 15 - indent), " ",
     979              :            is_on ? "  ON" : "  OFF",
     980              :            ((!is_on) == (!is_really_on) ? ""
     981            0 :             : (is_really_on ? " (FORCED_ON)" : " (FORCED_OFF)")));
     982         1970 : }
     983              : 
     984              : /* Dump pass list PASS with indentation INDENT.  */
     985              : 
     986              : static void
     987          130 : dump_pass_list (opt_pass *pass, int indent)
     988              : {
     989         1970 :   do
     990              :     {
     991         1970 :       dump_one_pass (pass, indent);
     992         1970 :       if (pass->sub)
     993          105 :         dump_pass_list (pass->sub, indent + 1);
     994         1970 :       pass = pass->next;
     995              :     }
     996         1970 :   while (pass);
     997          130 : }
     998              : 
     999              : /* Dump all optimization passes.  */
    1000              : 
    1001              : void
    1002            5 : dump_passes (void)
    1003              : {
    1004            5 :   g->get_passes ()->dump_passes ();
    1005            5 : }
    1006              : 
    1007              : void
    1008            5 : pass_manager::dump_passes () const
    1009              : {
    1010            5 :   push_dummy_function (true);
    1011            5 :   cgraph_node *node = cgraph_node::get_create (current_function_decl);
    1012              : 
    1013            5 :   create_pass_tab ();
    1014              : 
    1015            5 :   dump_pass_list (all_lowering_passes, 1);
    1016            5 :   dump_pass_list (all_small_ipa_passes, 1);
    1017            5 :   dump_pass_list (all_regular_ipa_passes, 1);
    1018            5 :   dump_pass_list (all_late_ipa_passes, 1);
    1019            5 :   dump_pass_list (all_passes, 1);
    1020              : 
    1021            5 :   node->remove ();
    1022            5 :   pop_dummy_function ();
    1023            5 : }
    1024              : 
    1025              : /* Returns the pass with NAME.  */
    1026              : 
    1027              : opt_pass *
    1028          209 : pass_manager::get_pass_by_name (const char *name)
    1029              : {
    1030          209 :   opt_pass **p = m_name_to_pass_map->get (name);
    1031          209 :   if (p)
    1032          209 :     return *p;
    1033              : 
    1034              :   return NULL;
    1035              : }
    1036              : 
    1037              : 
    1038              : /* Range [start, last].  */
    1039              : 
    1040              : struct uid_range
    1041              : {
    1042              :   unsigned int start;
    1043              :   unsigned int last;
    1044              :   const char *assem_name;
    1045              :   struct uid_range *next;
    1046              : };
    1047              : 
    1048              : typedef struct uid_range *uid_range_p;
    1049              : 
    1050              : 
    1051              : static vec<uid_range_p> enabled_pass_uid_range_tab;
    1052              : static vec<uid_range_p> disabled_pass_uid_range_tab;
    1053              : 
    1054              : 
    1055              : /* Parse option string for -fdisable- and -fenable-
    1056              :    The syntax of the options:
    1057              : 
    1058              :    -fenable-<pass_name>
    1059              :    -fdisable-<pass_name>
    1060              : 
    1061              :    -fenable-<pass_name>=s1:e1,s2:e2,...
    1062              :    -fdisable-<pass_name>=s1:e1,s2:e2,...
    1063              : */
    1064              : 
    1065              : static void
    1066          209 : enable_disable_pass (const char *arg, bool is_enable)
    1067              : {
    1068          209 :   opt_pass *pass;
    1069          209 :   char *range_str, *phase_name;
    1070          209 :   char *argstr = xstrdup (arg);
    1071          209 :   vec<uid_range_p> *tab = 0;
    1072              : 
    1073          209 :   range_str = strchr (argstr,'=');
    1074          209 :   if (range_str)
    1075              :     {
    1076            9 :       *range_str = '\0';
    1077            9 :       range_str++;
    1078              :     }
    1079              : 
    1080          209 :   phase_name = argstr;
    1081          209 :   if (!*phase_name)
    1082              :     {
    1083            0 :       if (is_enable)
    1084            0 :         error ("unrecognized option %<-fenable%>");
    1085              :       else
    1086            0 :         error ("unrecognized option %<-fdisable%>");
    1087            0 :       free (argstr);
    1088            0 :       return;
    1089              :     }
    1090          209 :   pass = g->get_passes ()->get_pass_by_name (phase_name);
    1091          209 :   if (!pass || pass->static_pass_number == -1)
    1092              :     {
    1093            0 :       if (is_enable)
    1094            0 :         error ("unknown pass %s specified in %<-fenable%>", phase_name);
    1095              :       else
    1096            0 :         error ("unknown pass %s specified in %<-fdisable%>", phase_name);
    1097            0 :       free (argstr);
    1098            0 :       return;
    1099              :     }
    1100              : 
    1101          209 :   if (is_enable)
    1102              :     tab = &enabled_pass_uid_range_tab;
    1103              :   else
    1104          205 :     tab = &disabled_pass_uid_range_tab;
    1105              : 
    1106          209 :   if ((unsigned) pass->static_pass_number >= tab->length ())
    1107          196 :     tab->safe_grow_cleared (pass->static_pass_number + 1, true);
    1108              : 
    1109          209 :   if (!range_str)
    1110              :     {
    1111          200 :       uid_range_p slot;
    1112          200 :       uid_range_p new_range = XCNEW (struct uid_range);
    1113              : 
    1114          200 :       new_range->start = 0;
    1115          200 :       new_range->last = (unsigned)-1;
    1116              : 
    1117          200 :       slot = (*tab)[pass->static_pass_number];
    1118          200 :       new_range->next = slot;
    1119          200 :       (*tab)[pass->static_pass_number] = new_range;
    1120          200 :       if (is_enable)
    1121            1 :         inform (UNKNOWN_LOCATION, "enable pass %s for functions in the range "
    1122              :                 "of [%u, %u]", phase_name, new_range->start, new_range->last);
    1123              :       else
    1124          199 :         inform (UNKNOWN_LOCATION, "disable pass %s for functions in the range "
    1125              :                 "of [%u, %u]", phase_name, new_range->start, new_range->last);
    1126              :     }
    1127              :   else
    1128              :     {
    1129           10 :       char *next_range = NULL;
    1130              :       char *one_range = range_str;
    1131           10 :       char *end_val = NULL;
    1132              : 
    1133           10 :       do
    1134              :         {
    1135           10 :           uid_range_p slot;
    1136           10 :           uid_range_p new_range;
    1137           10 :           char *invalid = NULL;
    1138           10 :           long start;
    1139           10 :           char *func_name = NULL;
    1140              : 
    1141           10 :           next_range = strchr (one_range, ',');
    1142           10 :           if (next_range)
    1143              :             {
    1144            1 :               *next_range = '\0';
    1145            1 :               next_range++;
    1146              :             }
    1147              : 
    1148           10 :           end_val = strchr (one_range, ':');
    1149           10 :           if (end_val)
    1150              :             {
    1151            1 :               *end_val = '\0';
    1152            1 :               end_val++;
    1153              :             }
    1154           10 :           start = strtol (one_range, &invalid, 10);
    1155           10 :           if (*invalid || start < 0)
    1156              :             {
    1157            9 :               if (end_val || (one_range[0] >= '0'
    1158            9 :                               && one_range[0] <= '9'))
    1159              :                 {
    1160            0 :                   error ("Invalid range %s in option %s",
    1161              :                          one_range,
    1162              :                          is_enable ? "-fenable" : "-fdisable");
    1163            0 :                   free (argstr);
    1164            0 :                   return;
    1165              :                 }
    1166              :               func_name = one_range;
    1167              :             }
    1168           10 :           if (!end_val)
    1169              :             {
    1170            9 :               new_range = XCNEW (struct uid_range);
    1171            9 :               if (!func_name)
    1172              :                 {
    1173            0 :                   new_range->start = (unsigned) start;
    1174            0 :                   new_range->last = (unsigned) start;
    1175              :                 }
    1176              :               else
    1177              :                 {
    1178            9 :                   new_range->start = (unsigned) -1;
    1179            9 :                   new_range->last = (unsigned) -1;
    1180            9 :                   new_range->assem_name = xstrdup (func_name);
    1181              :                 }
    1182              :             }
    1183              :           else
    1184              :             {
    1185            1 :               long last = strtol (end_val, &invalid, 10);
    1186            1 :               if (*invalid || last < start)
    1187              :                 {
    1188            0 :                   error ("Invalid range %s in option %s",
    1189              :                          end_val,
    1190              :                          is_enable ? "-fenable" : "-fdisable");
    1191            0 :                   free (argstr);
    1192            0 :                   return;
    1193              :                 }
    1194            1 :               new_range = XCNEW (struct uid_range);
    1195            1 :               new_range->start = (unsigned) start;
    1196            1 :               new_range->last = (unsigned) last;
    1197              :             }
    1198              : 
    1199           10 :           slot = (*tab)[pass->static_pass_number];
    1200           10 :           new_range->next = slot;
    1201           10 :           (*tab)[pass->static_pass_number] = new_range;
    1202           10 :           if (is_enable)
    1203              :             {
    1204            3 :               if (new_range->assem_name)
    1205            3 :                 inform (UNKNOWN_LOCATION,
    1206              :                         "enable pass %s for function %s",
    1207              :                         phase_name, new_range->assem_name);
    1208              :               else
    1209            0 :                 inform (UNKNOWN_LOCATION,
    1210              :                         "enable pass %s for functions in the range of [%u, %u]",
    1211              :                         phase_name, new_range->start, new_range->last);
    1212              :             }
    1213              :           else
    1214              :             {
    1215            7 :               if (new_range->assem_name)
    1216            6 :                 inform (UNKNOWN_LOCATION,
    1217              :                         "disable pass %s for function %s",
    1218              :                         phase_name, new_range->assem_name);
    1219              :               else
    1220            1 :                 inform (UNKNOWN_LOCATION,
    1221              :                         "disable pass %s for functions in the range of [%u, %u]",
    1222              :                         phase_name, new_range->start, new_range->last);
    1223              :             }
    1224              : 
    1225           10 :           one_range = next_range;
    1226           10 :         } while (next_range);
    1227              :     }
    1228              : 
    1229          209 :   free (argstr);
    1230              : }
    1231              : 
    1232              : /* Enable pass specified by ARG.  */
    1233              : 
    1234              : void
    1235            4 : enable_pass (const char *arg)
    1236              : {
    1237            4 :   enable_disable_pass (arg, true);
    1238            4 : }
    1239              : 
    1240              : /* Disable pass specified by ARG.  */
    1241              : 
    1242              : void
    1243          205 : disable_pass (const char *arg)
    1244              : {
    1245          205 :   enable_disable_pass (arg, false);
    1246          205 : }
    1247              : 
    1248              : /* Returns true if PASS is explicitly enabled/disabled for FUNC.  */
    1249              : 
    1250              : static bool
    1251    933968434 : is_pass_explicitly_enabled_or_disabled (opt_pass *pass,
    1252              :                                         tree func,
    1253              :                                         vec<uid_range_p> tab)
    1254              : {
    1255    933968434 :   uid_range_p slot, range;
    1256    933968434 :   int cgraph_uid;
    1257    933968434 :   const char *aname = NULL;
    1258              : 
    1259    933968434 :   if (!tab.exists ()
    1260        78124 :       || (unsigned) pass->static_pass_number >= tab.length ()
    1261    933968434 :       || pass->static_pass_number == -1)
    1262              :     return false;
    1263              : 
    1264        20264 :   slot = tab[pass->static_pass_number];
    1265        20264 :   if (!slot)
    1266              :     return false;
    1267              : 
    1268          312 :   cgraph_uid = func ? cgraph_node::get (func)->get_uid () : 0;
    1269          308 :   if (func && DECL_ASSEMBLER_NAME_SET_P (func))
    1270          308 :     aname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func));
    1271              : 
    1272          312 :   range = slot;
    1273          323 :   while (range)
    1274              :     {
    1275          314 :       if ((unsigned) cgraph_uid >= range->start
    1276          294 :           && (unsigned) cgraph_uid <= range->last)
    1277              :         return true;
    1278           20 :       if (range->assem_name && aname
    1279           20 :           && !strcmp (range->assem_name, aname))
    1280              :         return true;
    1281           11 :       range = range->next;
    1282              :     }
    1283              : 
    1284              :   return false;
    1285              : }
    1286              : 
    1287              : 
    1288              : /* Update static_pass_number for passes (and the flag
    1289              :    TODO_mark_first_instance).
    1290              : 
    1291              :    Passes are constructed with static_pass_number preinitialized to 0
    1292              : 
    1293              :    This field is used in two different ways: initially as instance numbers
    1294              :    of their kind, and then as ids within the entire pass manager.
    1295              : 
    1296              :    Within pass_manager::pass_manager:
    1297              : 
    1298              :    * In add_pass_instance(), as called by next_pass_1 in
    1299              :      NEXT_PASS in init_optimization_passes
    1300              : 
    1301              :    * When the initial instance of a pass within a pass manager is seen,
    1302              :      it is flagged, and its static_pass_number is set to -1
    1303              : 
    1304              :    * On subsequent times that it is seen, the static pass number
    1305              :      is decremented each time, so that if there are e.g. 4 dups,
    1306              :      they have static_pass_number -4, 2, 3, 4 respectively (note
    1307              :      how the initial one is negative and gives the count); these
    1308              :      can be thought of as instance numbers of the specific pass
    1309              : 
    1310              :    * Within the register_dump_files () traversal, set_pass_for_id()
    1311              :      is called on each pass, using these instance numbers to create
    1312              :      dumpfile switches, and then overwriting them with a pass id,
    1313              :      which are global to the whole pass manager (based on
    1314              :      (TDI_end + current value of extra_dump_files_in_use) )  */
    1315              : 
    1316              : static void
    1317    112574641 : add_pass_instance (opt_pass *new_pass, bool track_duplicates,
    1318              :                    opt_pass *initial_pass)
    1319              : {
    1320              :   /* Are we dealing with the first pass of its kind, or a clone?  */
    1321    112574641 :   if (new_pass != initial_pass)
    1322              :     {
    1323              :       /* We're dealing with a clone.  */
    1324     25714980 :       new_pass->todo_flags_start &= ~TODO_mark_first_instance;
    1325              : 
    1326              :       /* Indicate to register_dump_files that this pass has duplicates,
    1327              :          and so it should rename the dump file.  The first instance will
    1328              :          be -1, and be number of duplicates = -static_pass_number - 1.
    1329              :          Subsequent instances will be > 0 and just the duplicate number.  */
    1330     25714980 :       if ((new_pass->name && new_pass->name[0] != '*') || track_duplicates)
    1331              :         {
    1332     23714926 :           initial_pass->static_pass_number -= 1;
    1333     23714926 :           new_pass->static_pass_number = -initial_pass->static_pass_number;
    1334              :         }
    1335              :     }
    1336              :   else
    1337              :     {
    1338              :       /* We're dealing with the first pass of its kind.  */
    1339     86859661 :       new_pass->todo_flags_start |= TODO_mark_first_instance;
    1340     86859661 :       new_pass->static_pass_number = -1;
    1341              : 
    1342     86859661 :       invoke_plugin_callbacks (PLUGIN_NEW_PASS, new_pass);
    1343              :     }
    1344    112574641 : }
    1345              : 
    1346              : /* Add a pass to the pass list. Duplicate the pass if it's already
    1347              :    in the list.  */
    1348              : 
    1349              : static opt_pass **
    1350    112574468 : next_pass_1 (opt_pass **list, opt_pass *pass, opt_pass *initial_pass)
    1351              : {
    1352              :   /* Every pass should have a name so that plugins can refer to them.  */
    1353    112574468 :   gcc_assert (pass->name != NULL);
    1354              : 
    1355    112574468 :   add_pass_instance (pass, false, initial_pass);
    1356    112574468 :   *list = pass;
    1357              : 
    1358    112574468 :   return &(*list)->next;
    1359              : }
    1360              : 
    1361              : /* List node for an inserted pass instance. We need to keep track of all
    1362              :    the newly-added pass instances (with 'added_pass_nodes' defined below)
    1363              :    so that we can register their dump files after pass-positioning is finished.
    1364              :    Registering dumping files needs to be post-processed or the
    1365              :    static_pass_number of the opt_pass object would be modified and mess up
    1366              :    the dump file names of future pass instances to be added.  */
    1367              : 
    1368              : struct pass_list_node
    1369              : {
    1370              :   opt_pass *pass;
    1371              :   struct pass_list_node *next;
    1372              : };
    1373              : 
    1374              : static struct pass_list_node *added_pass_nodes = NULL;
    1375              : static struct pass_list_node *prev_added_pass_node;
    1376              : 
    1377              : /* Insert the pass at the proper position. Return true if the pass
    1378              :    is successfully added.
    1379              : 
    1380              :    NEW_PASS_INFO - new pass to be inserted
    1381              :    PASS_LIST - root of the pass list to insert the new pass to  */
    1382              : 
    1383              : static bool
    1384         3670 : position_pass (struct register_pass_info *new_pass_info, opt_pass **pass_list)
    1385              : {
    1386         3670 :   opt_pass *pass = *pass_list, *prev_pass = NULL;
    1387         3670 :   bool success = false;
    1388              : 
    1389        56145 :   for ( ; pass; prev_pass = pass, pass = pass->next)
    1390              :     {
    1391              :       /* Check if the current pass is of the same type as the new pass and
    1392              :          matches the name and the instance number of the reference pass.  */
    1393        52475 :       if (pass->type == new_pass_info->pass->type
    1394        32771 :           && pass->name
    1395        32771 :           && !strcmp (pass->name, new_pass_info->reference_pass_name)
    1396          173 :           && ((new_pass_info->ref_pass_instance_number == 0)
    1397          173 :               || (new_pass_info->ref_pass_instance_number ==
    1398          173 :                   pass->static_pass_number)
    1399          173 :               || (new_pass_info->ref_pass_instance_number == 1
    1400          173 :                   && pass->todo_flags_start & TODO_mark_first_instance)))
    1401              :         {
    1402          173 :           opt_pass *new_pass;
    1403          173 :           struct pass_list_node *new_pass_node;
    1404              : 
    1405          173 :           if (new_pass_info->ref_pass_instance_number == 0)
    1406              :             {
    1407            0 :               new_pass = new_pass_info->pass->clone ();
    1408            0 :               add_pass_instance (new_pass, true, new_pass_info->pass);
    1409              :             }
    1410              :           else
    1411              :             {
    1412          173 :               new_pass = new_pass_info->pass;
    1413          173 :               add_pass_instance (new_pass, true, new_pass);
    1414              :             }
    1415              : 
    1416              :           /* Insert the new pass instance based on the positioning op.  */
    1417          173 :           switch (new_pass_info->pos_op)
    1418              :             {
    1419          160 :               case PASS_POS_INSERT_AFTER:
    1420          160 :                 new_pass->next = pass->next;
    1421          160 :                 pass->next = new_pass;
    1422              : 
    1423              :                 /* Skip newly inserted pass to avoid repeated
    1424              :                    insertions in the case where the new pass and the
    1425              :                    existing one have the same name.  */
    1426          160 :                 pass = new_pass;
    1427          160 :                 break;
    1428           13 :               case PASS_POS_INSERT_BEFORE:
    1429           13 :                 new_pass->next = pass;
    1430           13 :                 if (prev_pass)
    1431           13 :                   prev_pass->next = new_pass;
    1432              :                 else
    1433            0 :                   *pass_list = new_pass;
    1434              :                 break;
    1435            0 :               case PASS_POS_REPLACE:
    1436            0 :                 new_pass->next = pass->next;
    1437            0 :                 if (prev_pass)
    1438            0 :                   prev_pass->next = new_pass;
    1439              :                 else
    1440            0 :                   *pass_list = new_pass;
    1441            0 :                 new_pass->sub = pass->sub;
    1442            0 :                 new_pass->tv_id = pass->tv_id;
    1443            0 :                 pass = new_pass;
    1444            0 :                 break;
    1445            0 :               default:
    1446            0 :                 error ("invalid pass positioning operation");
    1447            0 :                 return false;
    1448              :             }
    1449              : 
    1450              :           /* Save the newly added pass (instance) in the added_pass_nodes
    1451              :              list so that we can register its dump file later. Note that
    1452              :              we cannot register the dump file now because doing so will modify
    1453              :              the static_pass_number of the opt_pass object and therefore
    1454              :              mess up the dump file name of future instances.  */
    1455          173 :           new_pass_node = XCNEW (struct pass_list_node);
    1456          173 :           new_pass_node->pass = new_pass;
    1457          173 :           if (!added_pass_nodes)
    1458          173 :             added_pass_nodes = new_pass_node;
    1459              :           else
    1460            0 :             prev_added_pass_node->next = new_pass_node;
    1461          173 :           prev_added_pass_node = new_pass_node;
    1462              : 
    1463          173 :           success = true;
    1464              :         }
    1465              : 
    1466        52475 :       if (pass->sub && position_pass (new_pass_info, &pass->sub))
    1467              :         success = true;
    1468              :     }
    1469              : 
    1470              :   return success;
    1471              : }
    1472              : 
    1473              : /* Hooks a new pass into the pass lists.
    1474              : 
    1475              :    PASS_INFO   - pass information that specifies the opt_pass object,
    1476              :                  reference pass, instance number, and how to position
    1477              :                  the pass  */
    1478              : 
    1479              : void
    1480          173 : register_pass (struct register_pass_info *pass_info)
    1481              : {
    1482          173 :   g->get_passes ()->register_pass (pass_info);
    1483          173 : }
    1484              : 
    1485              : void
    1486            0 : register_pass (opt_pass* pass, pass_positioning_ops pos,
    1487              :                const char* ref_pass_name, int ref_pass_inst_number)
    1488              : {
    1489            0 :   register_pass_info i;
    1490            0 :   i.pass = pass;
    1491            0 :   i.reference_pass_name = ref_pass_name;
    1492            0 :   i.ref_pass_instance_number = ref_pass_inst_number;
    1493            0 :   i.pos_op = pos;
    1494              : 
    1495            0 :   g->get_passes ()->register_pass (&i);
    1496            0 : }
    1497              : 
    1498              : void
    1499          173 : pass_manager::register_pass (struct register_pass_info *pass_info)
    1500              : {
    1501          173 :   bool all_instances, success;
    1502              : 
    1503              :   /* The checks below could fail in buggy plugins.  Existing GCC
    1504              :      passes should never fail these checks, so we mention plugin in
    1505              :      the messages.  */
    1506          173 :   if (!pass_info->pass)
    1507            0 :       fatal_error (input_location, "plugin cannot register a missing pass");
    1508              : 
    1509          173 :   if (!pass_info->pass->name)
    1510            0 :       fatal_error (input_location, "plugin cannot register an unnamed pass");
    1511              : 
    1512          173 :   if (!pass_info->reference_pass_name)
    1513            0 :       fatal_error
    1514            0 :         (input_location,
    1515              :          "plugin cannot register pass %qs without reference pass name",
    1516              :          pass_info->pass->name);
    1517              : 
    1518              :   /* Try to insert the new pass to the pass lists.  We need to check
    1519              :      all five lists as the reference pass could be in one (or all) of
    1520              :      them.  */
    1521          173 :   all_instances = pass_info->ref_pass_instance_number == 0;
    1522          173 :   success = position_pass (pass_info, &all_lowering_passes);
    1523          173 :   if (!success || all_instances)
    1524          172 :     success |= position_pass (pass_info, &all_small_ipa_passes);
    1525          173 :   if (!success || all_instances)
    1526          134 :     success |= position_pass (pass_info, &all_regular_ipa_passes);
    1527          173 :   if (!success || all_instances)
    1528          121 :     success |= position_pass (pass_info, &all_late_ipa_passes);
    1529          173 :   if (!success || all_instances)
    1530          121 :     success |= position_pass (pass_info, &all_passes);
    1531          121 :   if (!success)
    1532            0 :     fatal_error
    1533            0 :       (input_location,
    1534              :        "pass %qs not found but is referenced by new pass %qs",
    1535            0 :        pass_info->reference_pass_name, pass_info->pass->name);
    1536              : 
    1537              :   /* OK, we have successfully inserted the new pass. We need to register
    1538              :      the dump files for the newly added pass and its duplicates (if any).
    1539              :      While doing so, we also delete the pass_list_node
    1540              :      objects created during pass positioning.  */
    1541          173 :   gcc::dump_manager *dumps = m_ctxt->get_dumps ();
    1542          519 :   while (added_pass_nodes)
    1543              :     {
    1544          173 :       struct pass_list_node *next_node = added_pass_nodes->next;
    1545              : 
    1546              :       /* Handle -fdump-* and -fopt-info.  */
    1547          173 :       dumps->register_pass (added_pass_nodes->pass);
    1548              : 
    1549          173 :       XDELETE (added_pass_nodes);
    1550          173 :       added_pass_nodes = next_node;
    1551              :     }
    1552          173 : }
    1553              : 
    1554              : /* Construct the pass tree.  The sequencing of passes is driven by
    1555              :    the cgraph routines:
    1556              : 
    1557              :    finalize_compilation_unit ()
    1558              :        for each node N in the cgraph
    1559              :            cgraph_analyze_function (N)
    1560              :                cgraph_lower_function (N) -> all_lowering_passes
    1561              : 
    1562              :    If we are optimizing, compile is then invoked:
    1563              : 
    1564              :    compile ()
    1565              :        ipa_passes ()                    -> all_small_ipa_passes
    1566              :                                         -> Analysis of all_regular_ipa_passes
    1567              :         * possible LTO streaming at compilation time *
    1568              :                                         -> Execution of all_regular_ipa_passes
    1569              :         * possible LTO streaming at link time *
    1570              :                                         -> all_late_ipa_passes
    1571              :        expand_all_functions ()
    1572              :            for each node N in the cgraph
    1573              :                expand_function (N)      -> Transformation of all_regular_ipa_passes
    1574              :                                         -> all_passes
    1575              : */
    1576              : 
    1577       285722 : pass_manager::pass_manager (context *ctxt)
    1578       285722 : : all_passes (NULL), all_small_ipa_passes (NULL), all_lowering_passes (NULL),
    1579       285722 :   all_regular_ipa_passes (NULL),
    1580       285722 :   all_late_ipa_passes (NULL), passes_by_id (NULL), passes_by_id_size (0),
    1581       285722 :   m_ctxt (ctxt), m_name_to_pass_map (NULL)
    1582              : {
    1583       285722 :   opt_pass **p;
    1584              : 
    1585              :   /* Zero-initialize pass members.  */
    1586              : #define INSERT_PASSES_AFTER(PASS)
    1587              : #define PUSH_INSERT_PASSES_WITHIN(PASS, NUM)
    1588              : #define POP_INSERT_PASSES()
    1589              : #define NEXT_PASS(PASS, NUM) m_ ## PASS ## _ ## NUM = NULL
    1590              : #define NEXT_PASS_WITH_ARG(PASS, NUM, ARG) NEXT_PASS (PASS, NUM)
    1591              : #define NEXT_PASS_WITH_ARGS(PASS, NUM, ...) NEXT_PASS (PASS, NUM)
    1592              : #define TERMINATE_PASS_LIST(PASS)
    1593              : #include "pass-instances.def"
    1594              : 
    1595              :   /* Initialize the pass_lists array.  */
    1596              : #define DEF_PASS_LIST(LIST) pass_lists[PASS_LIST_NO_##LIST] = &LIST;
    1597       285722 :   GCC_PASS_LISTS
    1598              : #undef DEF_PASS_LIST
    1599              : 
    1600              :   /* Build the tree of passes.  */
    1601              : 
    1602              : #define INSERT_PASSES_AFTER(PASS)               \
    1603              :   {                                             \
    1604              :     opt_pass **p_start;                         \
    1605              :     p_start = p = &(PASS);
    1606              : 
    1607              : #define TERMINATE_PASS_LIST(PASS)               \
    1608              :     gcc_assert (p_start == &PASS);          \
    1609              :     *p = NULL;                                  \
    1610              :   }
    1611              : 
    1612              : #define PUSH_INSERT_PASSES_WITHIN(PASS, NUM) \
    1613              :   { \
    1614              :     opt_pass **p = &(m_ ## PASS ## _ ## NUM)->sub;
    1615              : 
    1616              : #define POP_INSERT_PASSES() \
    1617              :   }
    1618              : 
    1619              : #define NEXT_PASS(PASS, NUM) \
    1620              :   do { \
    1621              :     gcc_assert (m_ ## PASS ## _ ## NUM == NULL); \
    1622              :     if ((NUM) == 1)                              \
    1623              :       m_ ## PASS ## _1 = make_##PASS (m_ctxt);          \
    1624              :     else                                         \
    1625              :       {                                          \
    1626              :         gcc_assert (m_ ## PASS ## _1);                 \
    1627              :         m_ ## PASS ## _ ## NUM = m_ ## PASS ## _1->clone (); \
    1628              :       }                                          \
    1629              :     p = next_pass_1 (p, m_ ## PASS ## _ ## NUM, m_ ## PASS ## _1);  \
    1630              :   } while (0)
    1631              : 
    1632              : #define NEXT_PASS_WITH_ARG(PASS, NUM, ARG)              \
    1633              :     do {                                                \
    1634              :       NEXT_PASS (PASS, NUM);                            \
    1635              :       m_ ## PASS ## _ ## NUM->set_pass_param (0, ARG);       \
    1636              :     } while (0)
    1637              : 
    1638              : #define NEXT_PASS_WITH_ARGS(PASS, NUM, ...)             \
    1639              :     do {                                                \
    1640              :       NEXT_PASS (PASS, NUM);                            \
    1641              :       static constexpr bool values[] = { __VA_ARGS__ }; \
    1642              :       unsigned i = 0;                                   \
    1643              :       for (bool value : values)                         \
    1644              :         {                                               \
    1645              :           m_ ## PASS ## _ ## NUM->set_pass_param (i, value); \
    1646              :           i++;                                          \
    1647              :         }                                               \
    1648              :     } while (0)
    1649              : 
    1650              : #include "pass-instances.def"
    1651              : 
    1652              :   /* Register the passes with the tree dump code.  */
    1653       285722 :   register_dump_files (all_lowering_passes);
    1654       285722 :   register_dump_files (all_small_ipa_passes);
    1655       285722 :   register_dump_files (all_regular_ipa_passes);
    1656       285722 :   register_dump_files (all_late_ipa_passes);
    1657       285722 :   register_dump_files (all_passes);
    1658       285722 : }
    1659              : 
    1660              : static void
    1661    102391835 : delete_pass_tree (opt_pass *pass)
    1662              : {
    1663    203500565 :   while (pass)
    1664              :     {
    1665              :       /* Recurse into child passes.  */
    1666    101108730 :       delete_pass_tree (pass->sub);
    1667              : 
    1668    101108730 :       opt_pass *next = pass->next;
    1669              : 
    1670              :       /* Delete this pass.  */
    1671    101108730 :       delete pass;
    1672              : 
    1673              :       /* Iterate onto sibling passes.  */
    1674    101108730 :       pass = next;
    1675              :     }
    1676    102391835 : }
    1677              : 
    1678       256621 : pass_manager::~pass_manager ()
    1679              : {
    1680       256621 :   XDELETEVEC (passes_by_id);
    1681              : 
    1682              :   /* Call delete_pass_tree on each of the pass_lists.  */
    1683              : #define DEF_PASS_LIST(LIST) \
    1684              :     delete_pass_tree (*pass_lists[PASS_LIST_NO_##LIST]);
    1685       256621 :   GCC_PASS_LISTS
    1686              : #undef DEF_PASS_LIST
    1687              : 
    1688       513242 :   delete m_name_to_pass_map;
    1689       256621 : }
    1690              : 
    1691              : /* If we are in IPA mode (i.e., current_function_decl is NULL), call
    1692              :    function CALLBACK for every function in the call graph.  Otherwise,
    1693              :    call CALLBACK on the current function.  */
    1694              : 
    1695              : static void
    1696   1209430310 : do_per_function (void (*callback) (function *, void *data), void *data)
    1697              : {
    1698   1209430310 :   if (current_function_decl)
    1699   1191115254 :     callback (cfun, data);
    1700              :   else
    1701              :     {
    1702     18315056 :       struct cgraph_node *node;
    1703    229449647 :       FOR_EACH_DEFINED_FUNCTION (node)
    1704    211134403 :         if (node->analyzed && (gimple_has_body_p (node->decl) && !in_lto_p)
    1705    393441370 :             && (!node->clone_of || node->decl != node->clone_of->decl))
    1706    159951484 :           callback (DECL_STRUCT_FUNCTION (node->decl), data);
    1707              :     }
    1708   1209430310 : }
    1709              : 
    1710              : /* Hook called when NODE is removed and therefore should be
    1711              :    excluded from order vector.  DATA is a hash set with removed nodes.  */
    1712              : 
    1713              : static void
    1714      3169377 : remove_cgraph_node_from_order (cgraph_node *node, void *data)
    1715              : {
    1716      3169377 :   hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
    1717      3169377 :   removed_nodes->add (node);
    1718      3169377 : }
    1719              : 
    1720              : /* Hook called when NODE is insert and therefore should be
    1721              :    excluded from removed_nodes.  DATA is a hash set with removed nodes.  */
    1722              : 
    1723              : static void
    1724        46846 : insert_cgraph_node_to_order (cgraph_node *node, void *data)
    1725              : {
    1726        46846 :   hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
    1727        46846 :   removed_nodes->remove (node);
    1728        46846 : }
    1729              : 
    1730              : /* Hook called when NODE is duplicated and therefore should be
    1731              :    excluded from removed_nodes.  DATA is a hash set with removed nodes.  */
    1732              : 
    1733              : static void
    1734      1887568 : duplicate_cgraph_node_to_order (cgraph_node *node, cgraph_node *node2,
    1735              :                                 void *data)
    1736              : {
    1737      1887568 :   hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
    1738      1887568 :   gcc_checking_assert (!removed_nodes->contains (node));
    1739      1887568 :   removed_nodes->remove (node2);
    1740      1887568 : }
    1741              : 
    1742              : 
    1743              : /* If we are in IPA mode (i.e., current_function_decl is NULL), call
    1744              :    function CALLBACK for every function in the call graph.  Otherwise,
    1745              :    call CALLBACK on the current function.
    1746              :    This function is global so that plugins can use it.  */
    1747              : void
    1748       462382 : do_per_function_toporder (void (*callback) (function *, void *data), void *data)
    1749              : {
    1750       462382 :   int i;
    1751              : 
    1752       462382 :   if (current_function_decl)
    1753            0 :     callback (cfun, data);
    1754              :   else
    1755              :     {
    1756       462382 :       hash_set<cgraph_node *> removed_nodes;
    1757       462382 :       unsigned nnodes = symtab->cgraph_count;
    1758       462382 :       cgraph_node **order = XNEWVEC (cgraph_node *, nnodes);
    1759              : 
    1760       462382 :       nnodes = ipa_reverse_postorder (order);
    1761     10513684 :       for (i = nnodes - 1; i >= 0; i--)
    1762     10051302 :         order[i]->process = 1;
    1763       462382 :       cgraph_node_hook_list *removal_hook
    1764       462382 :         = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
    1765              :                                            &removed_nodes);
    1766       462382 :       cgraph_node_hook_list *insertion_hook
    1767       462382 :         = symtab->add_cgraph_insertion_hook (insert_cgraph_node_to_order,
    1768              :                                              &removed_nodes);
    1769       462382 :       cgraph_2node_hook_list *duplication_hook
    1770       462382 :         = symtab->add_cgraph_duplication_hook (duplicate_cgraph_node_to_order,
    1771              :                                                &removed_nodes);
    1772     10513684 :       for (i = nnodes - 1; i >= 0; i--)
    1773              :         {
    1774     10051302 :           cgraph_node *node = order[i];
    1775              : 
    1776              :           /* Function could be inlined and removed as unreachable.  */
    1777     10051302 :           if (node == NULL || removed_nodes.contains (node))
    1778          107 :             continue;
    1779              : 
    1780     10051195 :           node->process = 0;
    1781     10051195 :           if (node->has_gimple_body_p ())
    1782              :             {
    1783      5702099 :               struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
    1784      5702099 :               push_cfun (fn);
    1785      5702099 :               callback (fn, data);
    1786      5702099 :               pop_cfun ();
    1787              :             }
    1788              :         }
    1789       462382 :       symtab->remove_cgraph_removal_hook (removal_hook);
    1790       462382 :       symtab->remove_cgraph_insertion_hook (insertion_hook);
    1791       462382 :       symtab->remove_cgraph_duplication_hook (duplication_hook);
    1792              : 
    1793       462382 :       free (order);
    1794       462382 :     }
    1795       462382 : }
    1796              : 
    1797              : /* Helper function to perform function body dump.  */
    1798              : 
    1799              : static void
    1800        55378 : execute_function_dump (function *fn, void *data)
    1801              : {
    1802        55378 :   opt_pass *pass = (opt_pass *)data;
    1803              : 
    1804        55378 :   if (dump_file)
    1805              :     {
    1806        55378 :       push_cfun (fn);
    1807              : 
    1808        55378 :       if (fn->curr_properties & PROP_gimple)
    1809        51178 :         dump_function_to_file (fn->decl, dump_file, dump_flags);
    1810              :       else
    1811         4200 :         print_rtl_with_bb (dump_file, get_insns (), dump_flags);
    1812              : 
    1813              :       /* Flush the file.  If verification fails, we won't be able to
    1814              :          close the file before aborting.  */
    1815        55378 :       fflush (dump_file);
    1816              : 
    1817        55378 :       if ((fn->curr_properties & PROP_cfg)
    1818        55378 :           && (dump_flags & TDF_GRAPH))
    1819              :         {
    1820          231 :           gcc::dump_manager *dumps = g->get_dumps ();
    1821          231 :           struct dump_file_info *dfi
    1822          231 :             = dumps->get_dump_file_info (pass->static_pass_number);
    1823          231 :           if (!dfi->graph_dump_initialized)
    1824              :             {
    1825           62 :               clean_graph_dump_file (dump_file_name);
    1826           62 :               dfi->graph_dump_initialized = true;
    1827              :             }
    1828          231 :           print_graph_cfg (dump_file_name, fn);
    1829              :         }
    1830              : 
    1831        55378 :       pop_cfun ();
    1832              :     }
    1833        55378 : }
    1834              : 
    1835              : /* This function is called when an internal compiler error is encountered.
    1836              :    Ensure that function dump is made available before compiler is aborted.  */
    1837              : 
    1838              : void
    1839           22 : emergency_dump_function ()
    1840              : {
    1841           22 :   if (!current_pass)
    1842              :     return;
    1843           14 :   enum opt_pass_type pt = current_pass->type;
    1844           14 :   fnotice (stderr, "during %s pass: %s\n",
    1845              :            pt == GIMPLE_PASS ? "GIMPLE" : pt == RTL_PASS ? "RTL" : "IPA",
    1846              :            current_pass->name);
    1847           14 :   if (!dump_file || !cfun)
    1848              :     return;
    1849            0 :   fnotice (stderr, "dump file: %s\n", dump_file_name);
    1850            0 :   fprintf (dump_file, "\n\n\nEMERGENCY DUMP:\n\n");
    1851            0 :   execute_function_dump (cfun, current_pass);
    1852              : 
    1853              :   /* Normally the passmanager will close the graphs as a pass could be wanting
    1854              :      to print multiple digraphs. But during an emergency dump there can only be
    1855              :      one and we must finish the graph manually.  */
    1856            0 :   if ((cfun->curr_properties & PROP_cfg)
    1857            0 :       && (dump_flags & TDF_GRAPH))
    1858            0 :     finish_graph_dump_file (dump_file_name);
    1859              : 
    1860            0 :   if (symtab && current_pass->type == IPA_PASS)
    1861            0 :     symtab->dump (dump_file);
    1862              : }
    1863              : 
    1864              : static struct profile_record *profile_record;
    1865              : 
    1866              : /* Do profile consistency book-keeping for the pass with static number INDEX.
    1867              :    RUN is true if the pass really runs, or FALSE
    1868              :    if we are only book-keeping on passes that may have selectively disabled
    1869              :    themselves on a given function.  */
    1870              : 
    1871              : static void
    1872            0 : check_profile_consistency (int index, bool run)
    1873              : {
    1874            0 :   pass_manager *passes = g->get_passes ();
    1875            0 :   if (index == -1)
    1876              :     return;
    1877            0 :   if (!profile_record)
    1878            0 :     profile_record = XCNEWVEC (struct profile_record,
    1879              :                                passes->passes_by_id_size);
    1880            0 :   gcc_assert (index < passes->passes_by_id_size && index >= 0);
    1881            0 :   profile_record[index].run |= run;
    1882            0 :   profile_record_check_consistency (&profile_record[index]);
    1883              : }
    1884              : 
    1885              : /* Account profile the pass with static number INDEX.
    1886              :    RUN is true if the pass really runs, or FALSE
    1887              :    if we are only book-keeping on passes that may have selectively disabled
    1888              :    themselves on a given function.  */
    1889              : 
    1890              : static void
    1891            0 : account_profile (int index, bool run)
    1892              : {
    1893            0 :   pass_manager *passes = g->get_passes ();
    1894            0 :   if (index == -1)
    1895              :     return;
    1896            0 :   if (!profile_record)
    1897            0 :     profile_record = XCNEWVEC (struct profile_record,
    1898              :                                passes->passes_by_id_size);
    1899            0 :   gcc_assert (index < passes->passes_by_id_size && index >= 0);
    1900            0 :   profile_record[index].run |= run;
    1901            0 :   profile_record_account_profile (&profile_record[index]);
    1902              : }
    1903              : 
    1904              : /* Account profile for IPA pass.  Callback for do_per_function.  */
    1905              : 
    1906              : static void
    1907            0 : account_profile_1 (function *fn, void *data)
    1908              : {
    1909            0 :   opt_pass *pass = (opt_pass *)data;
    1910              : 
    1911            0 :   push_cfun (fn);
    1912            0 :   check_profile_consistency (pass->static_pass_number, true);
    1913            0 :   account_profile (pass->static_pass_number, true);
    1914            0 :   pop_cfun ();
    1915            0 : }
    1916              : 
    1917              : /* Account profile chnages to all passes in list starting in SUB.  */
    1918              : 
    1919              : static void
    1920            0 : account_profile_in_list (opt_pass *sub)
    1921              : {
    1922            0 :   for (; sub; sub = sub->next)
    1923              :     {
    1924            0 :       check_profile_consistency (sub->static_pass_number, false);
    1925            0 :       account_profile (sub->static_pass_number, false);
    1926            0 :       if (sub->sub)
    1927            0 :         account_profile_in_list (sub->sub);
    1928              :     }
    1929            0 : }
    1930              : 
    1931              : /* Output profile consistency.  */
    1932              : 
    1933              : void
    1934            0 : dump_profile_report (void)
    1935              : {
    1936            0 :   g->get_passes ()->dump_profile_report ();
    1937            0 : }
    1938              : 
    1939              : void
    1940            0 : pass_manager::dump_profile_report () const
    1941              : {
    1942            0 :   int last_count_in = 0, last_prob_out = 0;
    1943            0 :   double last_dyn_count_in = 0, last_dyn_prob_out = 0;
    1944            0 :   double last_time = 0;
    1945            0 :   int last_size = 0;
    1946            0 :   double rel_time_change, rel_size_change;
    1947            0 :   gcc::dump_manager *dumps = m_ctxt->get_dumps ();
    1948              : 
    1949            0 :   if (!profile_record)
    1950              :     return;
    1951              : 
    1952            0 :   FILE *dump_file = dump_begin (TDI_profile_report, NULL);
    1953            0 :   if (dump_file == NULL)
    1954            0 :     dump_file = stderr;
    1955              : 
    1956            0 :   fprintf (dump_file, "Profile consistency report:\n\n");
    1957            0 :   fprintf (dump_file,
    1958              :            "Pass dump id and name            |static mismatch            "
    1959              :            "|dynamic mismatch                                     "
    1960              :            "|overall                                       |\n");
    1961            0 :   fprintf (dump_file,
    1962              :            "                                 |in count     |out prob     "
    1963              :            "|in count                  |out prob                  "
    1964              :            "|size               |time                      |\n");
    1965              : 
    1966            0 :   for (int i = 1; i < passes_by_id_size; i++)
    1967            0 :     if (profile_record[i].run)
    1968              :       {
    1969            0 :         if (last_time)
    1970            0 :           rel_time_change = (profile_record[i].time
    1971            0 :                              - last_time) * 100 / last_time;
    1972              :         else
    1973              :           rel_time_change = 0;
    1974            0 :         if (last_size)
    1975            0 :           rel_size_change = (profile_record[i].size
    1976            0 :                              - (double)last_size) * 100 / (double)last_size;
    1977              :         else
    1978              :           rel_size_change = 0;
    1979              : 
    1980            0 :         dump_file_info *dfi = dumps->get_dump_file_info (i);
    1981              : 
    1982            0 :         fprintf (dump_file, "%3i%c %-28s| %6i",
    1983              :                  dfi->num,
    1984            0 :                  passes_by_id[i]->type == GIMPLE_PASS ? 't'
    1985              :                  : passes_by_id[i]->type == RTL_PASS ? 'r'
    1986              :                  : 'i',
    1987            0 :                  passes_by_id[i]->name,
    1988            0 :                  profile_record[i].num_mismatched_count_in);
    1989            0 :         if (profile_record[i].num_mismatched_count_in != last_count_in)
    1990            0 :           fprintf (dump_file, " %+5i",
    1991              :                    profile_record[i].num_mismatched_count_in
    1992              :                    - last_count_in);
    1993              :         else
    1994            0 :           fprintf (dump_file, "      ");
    1995            0 :         fprintf (dump_file, "| %6i",
    1996            0 :                  profile_record[i].num_mismatched_prob_out);
    1997            0 :         if (profile_record[i].num_mismatched_prob_out != last_prob_out)
    1998            0 :           fprintf (dump_file, " %+5i",
    1999              :                    profile_record[i].num_mismatched_prob_out
    2000              :                    - last_prob_out);
    2001              :         else
    2002            0 :           fprintf (dump_file, "      ");
    2003              : 
    2004            0 :         fprintf (dump_file, "| %12.0f",
    2005            0 :                  profile_record[i].dyn_mismatched_count_in);
    2006            0 :         if (profile_record[i].dyn_mismatched_count_in != last_dyn_count_in)
    2007            0 :           fprintf (dump_file, " %+12.0f",
    2008              :                    profile_record[i].dyn_mismatched_count_in
    2009              :                    - last_dyn_count_in);
    2010              :         else
    2011            0 :           fprintf (dump_file, "             ");
    2012            0 :         fprintf (dump_file, "| %12.0f",
    2013            0 :                  profile_record[i].dyn_mismatched_prob_out);
    2014            0 :         if (profile_record[i].dyn_mismatched_prob_out != last_dyn_prob_out)
    2015            0 :           fprintf (dump_file, " %+12.0f",
    2016              :                    profile_record[i].dyn_mismatched_prob_out
    2017              :                    - last_dyn_prob_out);
    2018              :         else
    2019            0 :           fprintf (dump_file, "             ");
    2020              : 
    2021              :         /* Size/time units change across gimple and RTL.  */
    2022            0 :         if (i == m_pass_expand_1->static_pass_number)
    2023            0 :           fprintf (dump_file,
    2024              :                    "|-------------------|--------------------------");
    2025              :         else
    2026              :           {
    2027            0 :             fprintf (dump_file, "| %8i", profile_record[i].size);
    2028            0 :             if (rel_size_change)
    2029            0 :               fprintf (dump_file, " %+8.1f%%", rel_size_change);
    2030              :             else
    2031            0 :               fprintf (dump_file, "          ");
    2032            0 :             fprintf (dump_file, "| %12.0f", profile_record[i].time);
    2033              :             /* Time units changes with profile estimate and feedback.  */
    2034            0 :             if (i == m_pass_profile_1->static_pass_number
    2035            0 :                 || i == m_pass_ipa_auto_profile_1->static_pass_number
    2036            0 :                 || i == m_pass_ipa_tree_profile_1->static_pass_number)
    2037            0 :               fprintf (dump_file, "-------------");
    2038            0 :             else if (rel_time_change)
    2039            0 :               fprintf (dump_file, " %+11.1f%%", rel_time_change);
    2040              :             else
    2041            0 :               fprintf (dump_file, "             ");
    2042              :           }
    2043            0 :         fprintf (dump_file, "|\n");
    2044            0 :         last_prob_out = profile_record[i].num_mismatched_prob_out;
    2045            0 :         last_count_in = profile_record[i].num_mismatched_count_in;
    2046            0 :         last_dyn_prob_out = profile_record[i].dyn_mismatched_prob_out;
    2047            0 :         last_dyn_count_in = profile_record[i].dyn_mismatched_count_in;
    2048            0 :         last_time = profile_record[i].time;
    2049            0 :         last_size = profile_record[i].size;
    2050              :       }
    2051              : 
    2052            0 :   dump_end (TDI_profile_report, dump_file);
    2053              : }
    2054              : 
    2055              : /* Perform all TODO actions that ought to be done on each function.  */
    2056              : 
    2057              : static void
    2058    643533978 : execute_function_todo (function *fn, void *data)
    2059              : {
    2060    643533978 :   bool from_ipa_pass = (cfun == NULL);
    2061    643533978 :   unsigned int flags = (size_t)data;
    2062    643533978 :   if (!flags)
    2063              :     return;
    2064              : 
    2065    643533978 :   push_cfun (fn);
    2066              : 
    2067              :   /* If we need to cleanup the CFG let it perform a needed SSA update.  */
    2068    643533978 :   if (flags & TODO_cleanup_cfg)
    2069     20583207 :     cleanup_tree_cfg (flags & TODO_update_ssa_any);
    2070    622950771 :   else if (flags & TODO_update_ssa_any)
    2071     30973174 :     update_ssa (flags & TODO_update_ssa_any);
    2072    643533978 :   gcc_assert (!need_ssa_update_p (fn));
    2073              : 
    2074    643533978 :   if (flag_tree_pta && (flags & TODO_rebuild_alias))
    2075      4438535 :     compute_may_aliases ();
    2076              : 
    2077    643533978 :   if (optimize && (flags & TODO_update_address_taken))
    2078     10047727 :     execute_update_addresses_taken ();
    2079              : 
    2080    643533978 :   if (flags & TODO_remove_unused_locals)
    2081     12869011 :     remove_unused_locals ();
    2082              : 
    2083    643533978 :   if (flags & TODO_rebuild_cgraph_edges)
    2084         1699 :     cgraph_edge::rebuild_edges ();
    2085              : 
    2086    643533978 :   gcc_assert (dom_info_state (fn, CDI_POST_DOMINATORS) == DOM_NONE);
    2087              :   /* If we've seen errors do not bother running any verifiers.  */
    2088    643533978 :   if (flag_checking && !seen_error ())
    2089              :     {
    2090    642559386 :       dom_state pre_verify_state = dom_info_state (fn, CDI_DOMINATORS);
    2091    642559386 :       dom_state pre_verify_pstate = dom_info_state (fn, CDI_POST_DOMINATORS);
    2092              : 
    2093    642559386 :       if (flags & TODO_verify_il)
    2094              :         {
    2095    353240572 :           if (cfun->curr_properties & PROP_gimple)
    2096              :             {
    2097    257869077 :               if (cfun->curr_properties & PROP_cfg)
    2098              :                 /* IPA passes leave stmts to be fixed up, so make sure to
    2099              :                    not verify stmts really throw.  */
    2100    243399609 :                 verify_gimple_in_cfg (cfun, !from_ipa_pass);
    2101              :               else
    2102     14469468 :                 verify_gimple_in_seq (gimple_body (cfun->decl));
    2103              :             }
    2104    353240572 :           if (cfun->curr_properties & PROP_ssa)
    2105              :             /* IPA passes leave stmts to be fixed up, so make sure to
    2106              :                not verify SSA operands whose verifier will choke on that.  */
    2107    220701785 :             verify_ssa (true, !from_ipa_pass);
    2108              :           /* IPA passes leave basic-blocks unsplit, so make sure to
    2109              :              not trip on that.  */
    2110    353240572 :           if ((cfun->curr_properties & PROP_cfg)
    2111    324290403 :               && !from_ipa_pass)
    2112    283474962 :             verify_flow_info ();
    2113    353240572 :           if (current_loops
    2114    353240572 :               && ! loops_state_satisfies_p (LOOPS_NEED_FIXUP))
    2115              :             {
    2116    263948496 :               verify_loop_structure ();
    2117    263948496 :               if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
    2118      3865293 :                 verify_loop_closed_ssa (false);
    2119              :             }
    2120    353240572 :           if (cfun->curr_properties & PROP_rtl)
    2121     93900116 :             verify_rtl_sharing ();
    2122              :         }
    2123              : 
    2124              :       /* Make sure verifiers don't change dominator state.  */
    2125    642559386 :       gcc_assert (dom_info_state (fn, CDI_DOMINATORS) == pre_verify_state);
    2126    642559386 :       gcc_assert (dom_info_state (fn, CDI_POST_DOMINATORS) == pre_verify_pstate);
    2127              :     }
    2128              : 
    2129    643533978 :   pop_cfun ();
    2130              : 
    2131              :   /* For IPA passes make sure to release dominator info, it can be
    2132              :      computed by non-verifying TODOs.  */
    2133    643533978 :   if (from_ipa_pass)
    2134              :     {
    2135     78300968 :       free_dominance_info (fn, CDI_DOMINATORS);
    2136     78300968 :       free_dominance_info (fn, CDI_POST_DOMINATORS);
    2137              :     }
    2138              : }
    2139              : 
    2140              : /* Perform all TODO actions.  */
    2141              : static void
    2142    640083722 : execute_todo (unsigned int flags)
    2143              : {
    2144    640083722 :   if (flag_checking
    2145    640074294 :       && cfun
    2146   1270770612 :       && need_ssa_update_p (cfun))
    2147      2123615 :     gcc_assert (flags & TODO_update_ssa_any);
    2148              : 
    2149    637960107 :   statistics_fini_pass ();
    2150              : 
    2151    640083722 :   if (flags)
    2152    574158792 :     do_per_function (execute_function_todo, (void *)(size_t) flags);
    2153              : 
    2154              :   /* At this point we should not have any unreachable code in the
    2155              :      CFG, so it is safe to flush the pending freelist for SSA_NAMES.  */
    2156    640083722 :   if (cfun && cfun->gimple_df)
    2157    629221586 :     flush_ssaname_freelist ();
    2158              : 
    2159              :   /* Always remove functions just as before inlining: IPA passes might be
    2160              :      interested to see bodies of extern inline functions that are not inlined
    2161              :      to analyze side effects.  The full removal is done just at the end
    2162              :      of IPA pass queue.  */
    2163    640083722 :   if (flags & TODO_remove_functions)
    2164              :     {
    2165       965223 :       gcc_assert (!cfun);
    2166       965223 :       symtab->remove_unreachable_nodes (dump_file);
    2167              :     }
    2168              : 
    2169    640083722 :   if ((flags & TODO_dump_symtab) && dump_file && !current_function_decl)
    2170              :     {
    2171          773 :       gcc_assert (!cfun);
    2172          773 :       symtab->dump (dump_file);
    2173              :       /* Flush the file.  If verification fails, we won't be able to
    2174              :          close the file before aborting.  */
    2175          773 :       fflush (dump_file);
    2176              :     }
    2177              : 
    2178              :   /* Now that the dumping has been done, we can get rid of the optional
    2179              :      df problems.  */
    2180    640083722 :   if (flags & TODO_df_finish)
    2181     39100323 :     df_finish_pass ((flags & TODO_df_verify) != 0);
    2182    640083722 : }
    2183              : 
    2184              : /* Verify invariants that should hold between passes.  This is a place
    2185              :    to put simple sanity checks.  */
    2186              : 
    2187              : static void
    2188    320041765 : verify_interpass_invariants (void)
    2189              : {
    2190    320041765 :   gcc_checking_assert (!fold_deferring_overflow_warnings_p ());
    2191    320041765 : }
    2192              : 
    2193              : /* Helper function. Verify that the properties has been turn into the
    2194              :    properties expected by the pass.  */
    2195              : 
    2196              : static void
    2197    353743530 : verify_curr_properties (function *fn, void *data)
    2198              : {
    2199    353743530 :   unsigned int props = (size_t)data;
    2200    353743530 :   gcc_assert ((fn->curr_properties & props) == props);
    2201    353743530 : }
    2202              : 
    2203              : /* Release dump file name if set.  */
    2204              : 
    2205              : static void
    2206    613519355 : release_dump_file_name (void)
    2207              : {
    2208    613519355 :   if (dump_file_name)
    2209              :     {
    2210        55388 :       free (const_cast<char *> (dump_file_name));
    2211        55388 :       dump_file_name = NULL;
    2212              :     }
    2213    613519355 : }
    2214              : 
    2215              : /* Initialize pass dump file.  */
    2216              : /* This is non-static so that the plugins can use it.  */
    2217              : 
    2218              : bool
    2219    321454167 : pass_init_dump_file (opt_pass *pass)
    2220              : {
    2221              :   /* If a dump file name is present, open it if enabled.  */
    2222    321454167 :   if (pass->static_pass_number != -1)
    2223              :     {
    2224    292065210 :       timevar_push (TV_DUMP);
    2225    292065210 :       gcc::dump_manager *dumps = g->get_dumps ();
    2226    292065210 :       bool initializing_dump =
    2227    292065210 :         !dumps->dump_initialized_p (pass->static_pass_number);
    2228    292065210 :       release_dump_file_name ();
    2229    292065210 :       dump_file_name = dumps->get_dump_file_name (pass->static_pass_number);
    2230    292065210 :       dumps->dump_start (pass->static_pass_number, &dump_flags);
    2231    292065210 :       if (dump_file && current_function_decl && ! (dump_flags & TDF_GIMPLE))
    2232        52593 :         dump_function_header (dump_file, current_function_decl, dump_flags);
    2233    292065210 :       if (initializing_dump
    2234    292016137 :           && dump_file && (dump_flags & TDF_GRAPH)
    2235    292065393 :           && cfun && (cfun->curr_properties & PROP_cfg))
    2236              :         {
    2237          103 :           clean_graph_dump_file (dump_file_name);
    2238          103 :           struct dump_file_info *dfi
    2239          103 :             = dumps->get_dump_file_info (pass->static_pass_number);
    2240          103 :           dfi->graph_dump_initialized = true;
    2241              :         }
    2242    292065210 :       timevar_pop (TV_DUMP);
    2243    292065210 :       return initializing_dump;
    2244              :     }
    2245              :   else
    2246              :     return false;
    2247              : }
    2248              : 
    2249              : /* Flush PASS dump file.  */
    2250              : /* This is non-static so that plugins can use it.  */
    2251              : 
    2252              : void
    2253    321454145 : pass_fini_dump_file (opt_pass *pass)
    2254              : {
    2255    321454145 :   timevar_push (TV_DUMP);
    2256              : 
    2257              :   /* Flush and close dump file.  */
    2258    321454145 :   release_dump_file_name ();
    2259              : 
    2260    321454145 :   g->get_dumps ()->dump_finish (pass->static_pass_number);
    2261    321454145 :   timevar_pop (TV_DUMP);
    2262    321454145 : }
    2263              : 
    2264              : /* After executing the pass, apply expected changes to the function
    2265              :    properties. */
    2266              : 
    2267              : static void
    2268    353733852 : update_properties_after_pass (function *fn, void *data)
    2269              : {
    2270    353733852 :   opt_pass *pass = (opt_pass *) data;
    2271    353733852 :   fn->curr_properties = (fn->curr_properties | pass->properties_provided)
    2272    353733852 :                          & ~pass->properties_destroyed;
    2273    353733852 : }
    2274              : 
    2275              : /* Execute summary generation for all of the passes in IPA_PASS.  */
    2276              : 
    2277              : void
    2278       229806 : execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
    2279              : {
    2280      4596133 :   while (ipa_pass)
    2281              :     {
    2282      4366327 :       opt_pass *pass = ipa_pass;
    2283              : 
    2284              :       /* Execute all of the IPA_PASSes in the list.  */
    2285      4366327 :       if (ipa_pass->type == IPA_PASS
    2286      4136521 :           && pass->gate (cfun)
    2287      6716500 :           && ipa_pass->generate_summary)
    2288              :         {
    2289      1131095 :           pass_init_dump_file (pass);
    2290              : 
    2291              :           /* If a timevar is present, start it.  */
    2292      1131095 :           if (pass->tv_id)
    2293      1131095 :             timevar_push (pass->tv_id);
    2294              : 
    2295      1131095 :           current_pass = pass;
    2296      1131095 :           ipa_pass->generate_summary ();
    2297              : 
    2298              :           /* Stop timevar.  */
    2299      1131095 :           if (pass->tv_id)
    2300      1131095 :             timevar_pop (pass->tv_id);
    2301              : 
    2302      1131095 :           pass_fini_dump_file (pass);
    2303              :         }
    2304      4366327 :       ipa_pass = (ipa_opt_pass_d *)ipa_pass->next;
    2305              :     }
    2306       229806 : }
    2307              : 
    2308              : /* Execute IPA_PASS function transform on NODE.  */
    2309              : 
    2310              : static void
    2311      2430833 : execute_one_ipa_transform_pass (struct cgraph_node *node,
    2312              :                                 ipa_opt_pass_d *ipa_pass, bool do_not_collect)
    2313              : {
    2314      2430833 :   opt_pass *pass = ipa_pass;
    2315      2430833 :   unsigned int todo_after = 0;
    2316              : 
    2317      2430833 :   current_pass = pass;
    2318      2430833 :   if (!ipa_pass->function_transform)
    2319              :     return;
    2320              : 
    2321              :   /* Note that the folders should only create gimple expressions.
    2322              :      This is a hack until the new folder is ready.  */
    2323      2430833 :   in_gimple_form = (cfun && (cfun->curr_properties & PROP_gimple)) != 0;
    2324              : 
    2325      2430833 :   pass_init_dump_file (pass);
    2326              : 
    2327              :   /* If a timevar is present, start it.  */
    2328      2430833 :   if (pass->tv_id != TV_NONE)
    2329      2430833 :     timevar_push (pass->tv_id);
    2330              : 
    2331      2430833 :   gcc_checking_assert (!(ipa_pass->function_transform_todo_flags_start & TODO_verify_il));
    2332              :   /* Run pre-pass verification.  */
    2333      2430833 :   execute_todo (ipa_pass->function_transform_todo_flags_start);
    2334              : 
    2335              :   /* Do it!  */
    2336      2430833 :   todo_after = ipa_pass->function_transform (node);
    2337              : 
    2338              :   /* Run post-pass cleanup.  */
    2339      2430833 :   gcc_checking_assert (!(todo_after & TODO_verify_il));
    2340      2430833 :   execute_todo (todo_after);
    2341      2430833 :   verify_interpass_invariants ();
    2342              : 
    2343              :   /* Stop timevar.  */
    2344      2430833 :   if (pass->tv_id != TV_NONE)
    2345      2430833 :     timevar_pop (pass->tv_id);
    2346              : 
    2347      2430833 :   if (dump_file)
    2348         1192 :     do_per_function (execute_function_dump, pass);
    2349      2430833 :   pass_fini_dump_file (pass);
    2350              : 
    2351      2430833 :   current_pass = NULL;
    2352      2430833 :   redirect_edge_var_map_empty ();
    2353              : 
    2354              :   /* Signal this is a suitable GC collection point.  */
    2355      2430833 :   if (!do_not_collect && !(todo_after & TODO_do_not_ggc_collect))
    2356      2408656 :     ggc_collect ();
    2357              : }
    2358              : 
    2359              : /* For the current function, execute all ipa transforms. */
    2360              : 
    2361              : void
    2362      1463839 : execute_all_ipa_transforms (bool do_not_collect)
    2363              : {
    2364      1463839 :   struct cgraph_node *node;
    2365      1463839 :   node = cgraph_node::get (current_function_decl);
    2366              : 
    2367              : 
    2368      1463839 :   cgraph_node *next_clone;
    2369      1726560 :   for (cgraph_node *n = node->clones; n; n = next_clone)
    2370              :     {
    2371       262721 :       next_clone = n->next_sibling_clone;
    2372       262721 :       if (n->decl != node->decl)
    2373         3178 :         n->materialize_clone ();
    2374              :     }
    2375              : 
    2376      1463839 :   int j = 0;
    2377      1463839 :   gcc::pass_manager *passes = g->get_passes ();
    2378      1463839 :   bool report = profile_report && (cfun->curr_properties & PROP_gimple) != 0;
    2379              : 
    2380            0 :   if (report)
    2381            0 :     push_cfun (DECL_STRUCT_FUNCTION (node->decl));
    2382              : 
    2383      6822350 :   for (auto p : node->ipa_transforms_to_apply)
    2384              :     {
    2385              :       /* To get consistent statistics, we need to account each function
    2386              :          to each IPA pass.  */
    2387      2430833 :       if (report)
    2388              :         {
    2389            0 :           for (;j < p->static_pass_number; j++)
    2390            0 :             if (passes->get_pass_for_id (j)
    2391            0 :                 && passes->get_pass_for_id (j)->type == IPA_PASS
    2392            0 :                 && ((ipa_opt_pass_d *)passes->get_pass_for_id (j))
    2393            0 :                    ->function_transform)
    2394              :               {
    2395            0 :                 check_profile_consistency (j, true);
    2396            0 :                 account_profile (j, true);
    2397              :               }
    2398            0 :           gcc_checking_assert (passes->get_pass_for_id (j) == p);
    2399              :         }
    2400      2430833 :       execute_one_ipa_transform_pass (node, p, do_not_collect);
    2401              :     }
    2402              :   /* Account remaining IPA passes.  */
    2403      1463839 :   if (report)
    2404              :     {
    2405            0 :       for (;!passes->get_pass_for_id (j)
    2406            0 :             || passes->get_pass_for_id (j)->type != RTL_PASS; j++)
    2407            0 :         if (passes->get_pass_for_id (j)
    2408            0 :             && passes->get_pass_for_id (j)->type == IPA_PASS
    2409            0 :             && ((ipa_opt_pass_d *)passes->get_pass_for_id (j))
    2410            0 :                ->function_transform)
    2411              :           {
    2412            0 :             check_profile_consistency (j, true);
    2413            0 :             account_profile (j, true);
    2414              :           }
    2415            0 :       pop_cfun ();
    2416              :     }
    2417      1463839 :   node->ipa_transforms_to_apply.release ();
    2418      1463839 : }
    2419              : 
    2420              : /* Check if PASS is explicitly disabled or enabled and return
    2421              :    the gate status.  FUNC is the function to be processed, and
    2422              :    GATE_STATUS is the gate status determined by pass manager by
    2423              :    default.  */
    2424              : 
    2425              : static bool
    2426    466984217 : override_gate_status (opt_pass *pass, tree func, bool gate_status)
    2427              : {
    2428    466984217 :   bool explicitly_enabled = false;
    2429    466984217 :   bool explicitly_disabled = false;
    2430              : 
    2431    466984217 :   explicitly_enabled
    2432    466984217 :    = is_pass_explicitly_enabled_or_disabled (pass, func,
    2433              :                                              enabled_pass_uid_range_tab);
    2434    466984217 :   explicitly_disabled
    2435    466984217 :    = is_pass_explicitly_enabled_or_disabled (pass, func,
    2436              :                                              disabled_pass_uid_range_tab);
    2437              : 
    2438    466984217 :   gate_status = !explicitly_disabled && (gate_status || explicitly_enabled);
    2439              : 
    2440    466984217 :   return gate_status;
    2441              : }
    2442              : 
    2443              : /* Determine if PASS_NAME matches CRITERION.
    2444              :    Not a pure predicate, since it can update CRITERION, to support
    2445              :    matching the Nth invocation of a pass.
    2446              :    Subroutine of should_skip_pass_p.  */
    2447              : 
    2448              : static bool
    2449         7738 : determine_pass_name_match (const char *pass_name, char *criterion)
    2450              : {
    2451         7738 :   size_t namelen = strlen (pass_name);
    2452         7738 :   if (! strncmp (pass_name, criterion, namelen))
    2453              :     {
    2454              :       /* The following supports starting with the Nth invocation
    2455              :          of a pass (where N does not necessarily is equal to the
    2456              :          dump file suffix).  */
    2457          173 :       if (criterion[namelen] == '\0'
    2458           60 :           || (criterion[namelen] == '1'
    2459           33 :               && criterion[namelen + 1] == '\0'))
    2460              :         return true;
    2461              :       else
    2462              :         {
    2463           27 :           if (criterion[namelen + 1] == '\0')
    2464           27 :             --criterion[namelen];
    2465           27 :           return false;
    2466              :         }
    2467              :     }
    2468              :   else
    2469              :     return false;
    2470              : }
    2471              : 
    2472              : /* For skipping passes until "startwith" pass.
    2473              :    Return true iff PASS should be skipped.
    2474              :    Clear cfun->pass_startwith when encountering the "startwith" pass,
    2475              :    so that all subsequent passes are run.  */
    2476              : 
    2477              : static bool
    2478    317617834 : should_skip_pass_p (opt_pass *pass)
    2479              : {
    2480    317617834 :   if (!cfun)
    2481              :     return false;
    2482    312923799 :   if (!cfun->pass_startwith)
    2483              :     return false;
    2484              : 
    2485              :   /* For __GIMPLE functions, we have to at least start when we leave
    2486              :      SSA.  Hence, we need to detect the "expand" pass, and stop skipping
    2487              :      when we encounter it.  A cheap way to identify "expand" is it to
    2488              :      detect the destruction of PROP_ssa.
    2489              :      For __RTL functions, we invoke "rest_of_compilation" directly, which
    2490              :      is after "expand", and hence we don't reach this conditional.  */
    2491         7746 :   if (pass->properties_destroyed & PROP_ssa)
    2492              :     {
    2493            8 :       if (!quiet_flag)
    2494            0 :         fprintf (stderr, "starting anyway when leaving SSA: %s\n", pass->name);
    2495            8 :       cfun->pass_startwith = NULL;
    2496            8 :       return false;
    2497              :     }
    2498              : 
    2499         7738 :   if (determine_pass_name_match (pass->name, cfun->pass_startwith))
    2500              :     {
    2501          146 :       if (!quiet_flag)
    2502            0 :         fprintf (stderr, "found starting pass: %s\n", pass->name);
    2503          146 :       cfun->pass_startwith = NULL;
    2504          146 :       return false;
    2505              :     }
    2506              : 
    2507              :   /* For GIMPLE passes, run any property provider (but continue skipping
    2508              :      afterwards).
    2509              :      We don't want to force running RTL passes that are property providers:
    2510              :      "expand" is covered above, and the only pass other than "expand" that
    2511              :      provides a property is "into_cfglayout" (PROP_cfglayout), which does
    2512              :      too much for a dumped __RTL function.  */
    2513         7592 :   if (pass->type == GIMPLE_PASS
    2514         7474 :       && pass->properties_provided != 0)
    2515              :     return false;
    2516              : 
    2517              :   /* We need to (re-)build cgraph edges as needed.  */
    2518         7088 :   if (strstr (pass->name, "build_cgraph_edges") != NULL)
    2519              :     return false;
    2520              : 
    2521              :   /* We need to run ISEL as that lowers VEC_COND_EXPR but doesn't provide
    2522              :      a property.  */
    2523         6726 :   if (strstr (pass->name, "isel") != NULL)
    2524              :     return false;
    2525              : 
    2526              :   /* Don't skip df init; later RTL passes need it.  */
    2527         6716 :   if (strstr (pass->name, "dfinit") != NULL
    2528         6711 :       || strstr (pass->name, "dfinish") != NULL)
    2529              :     return false;
    2530              : 
    2531         6710 :   if (!quiet_flag)
    2532            0 :     fprintf (stderr, "skipping pass: %s\n", pass->name);
    2533              : 
    2534              :   /* If we get here, then we have a "startwith" that we haven't seen yet;
    2535              :      skip the pass.  */
    2536              :   return true;
    2537              : }
    2538              : 
    2539              : /* Skip the given pass, for handling passes before "startwith"
    2540              :    in __GIMPLE and__RTL-marked functions.
    2541              :    In theory, this ought to be a no-op, but some of the RTL passes
    2542              :    need additional processing here.  */
    2543              : 
    2544              : static void
    2545         6710 : skip_pass (opt_pass *pass)
    2546              : {
    2547              :   /* Pass "reload" sets the global "reload_completed", and many
    2548              :      things depend on this (e.g. instructions in .md files).  */
    2549         6710 :   if (strcmp (pass->name, "reload") == 0)
    2550            3 :     reload_completed = 1;
    2551              : 
    2552              :   /* Similar for pass "pro_and_epilogue" and the "epilogue_completed" global
    2553              :      variable.  */
    2554         6710 :   if (strcmp (pass->name, "pro_and_epilogue") == 0)
    2555            2 :     epilogue_completed = 1;
    2556              : 
    2557              :   /* The INSN_ADDRESSES vec is normally set up by
    2558              :      shorten_branches; set it up for the benefit of passes that
    2559              :      run after this.  */
    2560         6710 :   if (strcmp (pass->name, "shorten") == 0)
    2561            4 :     INSN_ADDRESSES_ALLOC (get_max_uid ());
    2562              : 
    2563              :   /* Update the cfg hooks as appropriate.  */
    2564         6710 :   if (strcmp (pass->name, "into_cfglayout") == 0)
    2565              :     {
    2566            6 :       cfg_layout_rtl_register_cfg_hooks ();
    2567            6 :       cfun->curr_properties |= PROP_cfglayout;
    2568              :     }
    2569         6710 :   if (strcmp (pass->name, "outof_cfglayout") == 0)
    2570              :     {
    2571            5 :       rtl_register_cfg_hooks ();
    2572            5 :       cfun->curr_properties &= ~PROP_cfglayout;
    2573              :     }
    2574         6710 : }
    2575              : 
    2576              : /* Execute PASS. */
    2577              : 
    2578              : bool
    2579    466982247 : execute_one_pass (opt_pass *pass)
    2580              : {
    2581    466982247 :   namespace pass_events = gcc::topics::pass_events;
    2582              : 
    2583    466982247 :   unsigned int todo_after = 0;
    2584              : 
    2585    466982247 :   bool gate_status;
    2586              : 
    2587    466982247 :   if (auto channel = g->get_channels ().pass_events_channel.get_if_active ())
    2588          208 :     channel->publish (pass_events::before_pass {pass, cfun});
    2589              : 
    2590              :   /* IPA passes are executed on whole program, so cfun should be NULL.
    2591              :      Other passes need function context set.  */
    2592    466982247 :   if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
    2593      8975308 :     gcc_assert (!cfun && !current_function_decl);
    2594              :   else
    2595    458006939 :     gcc_assert (cfun && current_function_decl);
    2596              : 
    2597    466982247 :   current_pass = pass;
    2598              : 
    2599              :   /* Check whether gate check should be avoided.
    2600              :      User controls the value of the gate through the parameter "gate_status". */
    2601    466982247 :   gate_status = pass->gate (cfun);
    2602    466982247 :   gate_status = override_gate_status (pass, current_function_decl, gate_status);
    2603              : 
    2604              :   /* Override gate with plugin.  */
    2605    466982247 :   invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status);
    2606              : 
    2607    466982247 :   if (!gate_status)
    2608              :     {
    2609              :       /* Run so passes selectively disabling themselves on a given function
    2610              :          are not miscounted.  */
    2611    149364413 :       if (profile_report && cfun && (cfun->curr_properties & PROP_cfg)
    2612            0 :           && pass->type != IPA_PASS && pass->type != SIMPLE_IPA_PASS)
    2613              :         {
    2614            0 :           check_profile_consistency (pass->static_pass_number, false);
    2615            0 :           account_profile (pass->static_pass_number, false);
    2616            0 :           if (pass->sub)
    2617            0 :             account_profile_in_list (pass->sub);
    2618              :         }
    2619    149364413 :       current_pass = NULL;
    2620    149364413 :       return false;
    2621              :     }
    2622              : 
    2623    317617834 :   if (should_skip_pass_p (pass))
    2624              :     {
    2625         6710 :       skip_pass (pass);
    2626         6710 :       return true;
    2627              :     }
    2628              : 
    2629              :   /* Pass execution event trigger: useful to identify passes being
    2630              :      executed.  */
    2631    317611124 :   invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
    2632              : 
    2633    317611124 :   if (!quiet_flag && !cfun)
    2634            0 :     fprintf (stderr, " <%s>", pass->name ? pass->name : "");
    2635              : 
    2636              :   /* Note that the folders should only create gimple expressions.
    2637              :      This is a hack until the new folder is ready.  */
    2638    317611124 :   in_gimple_form = (cfun && (cfun->curr_properties & PROP_gimple)) != 0;
    2639              : 
    2640    317611124 :   pass_init_dump_file (pass);
    2641              : 
    2642              :   /* If a timevar is present, start it.  */
    2643    317611124 :   if (pass->tv_id != TV_NONE)
    2644    230295699 :     timevar_push (pass->tv_id);
    2645              : 
    2646              : 
    2647              :   /* Run pre-pass verification.  */
    2648    317611124 :   gcc_checking_assert (!(pass->todo_flags_start & TODO_verify_il));
    2649    317611124 :   execute_todo (pass->todo_flags_start);
    2650              : 
    2651    317611124 :   if (flag_checking)
    2652    317606444 :     do_per_function (verify_curr_properties,
    2653    317606444 :                      (void *)(size_t)pass->properties_required);
    2654              : 
    2655              :   /* Do it!  */
    2656    317611124 :   todo_after = pass->execute (cfun);
    2657              : 
    2658    317611102 :   if (todo_after & TODO_discard_function)
    2659              :     {
    2660              :       /* Stop timevar.  */
    2661          170 :       if (pass->tv_id != TV_NONE)
    2662          108 :         timevar_pop (pass->tv_id);
    2663              : 
    2664          170 :       pass_fini_dump_file (pass);
    2665              : 
    2666          170 :       gcc_assert (cfun);
    2667              :       /* As cgraph_node::release_body expects release dominators info,
    2668              :          we have to release it.  */
    2669          170 :       if (dom_info_available_p (CDI_DOMINATORS))
    2670          115 :        free_dominance_info (CDI_DOMINATORS);
    2671              : 
    2672          170 :       if (dom_info_available_p (CDI_POST_DOMINATORS))
    2673            0 :        free_dominance_info (CDI_POST_DOMINATORS);
    2674              : 
    2675          170 :       if (cfun->assume_function)
    2676              :         {
    2677              :           /* For assume functions, don't release body, keep it around.  */
    2678          108 :           cfun->curr_properties |= PROP_assumptions_done;
    2679          108 :           pop_cfun ();
    2680          108 :           current_pass = NULL;
    2681          108 :           return true;
    2682              :         }
    2683              : 
    2684           62 :       tree fn = cfun->decl;
    2685           62 :       pop_cfun ();
    2686           62 :       gcc_assert (!cfun);
    2687           62 :       cgraph_node::get (fn)->release_body ();
    2688              : 
    2689           62 :       current_pass = NULL;
    2690           62 :       redirect_edge_var_map_empty ();
    2691              : 
    2692           62 :       ggc_collect ();
    2693              : 
    2694           62 :       return true;
    2695              :     }
    2696              : 
    2697    317610932 :   do_per_function (update_properties_after_pass, pass);
    2698              : 
    2699              :   /* Run post-pass cleanup and verification.  */
    2700    317610932 :   gcc_checking_assert (!(todo_after & TODO_verify_il));
    2701    317610932 :   gcc_checking_assert (!(pass->todo_flags_finish & TODO_verify_il));
    2702    317610932 :   execute_todo (todo_after | pass->todo_flags_finish | TODO_verify_il);
    2703    317610932 :   if (profile_report)
    2704              :     {
    2705              :       /* IPA passes are accounted at transform time.  */
    2706            0 :       if (pass->type == IPA_PASS)
    2707              :         ;
    2708            0 :       else if (pass->type == SIMPLE_IPA_PASS)
    2709            0 :         do_per_function (account_profile_1, pass);
    2710            0 :       else if (cfun && (cfun->curr_properties & PROP_cfg))
    2711              :         {
    2712            0 :           check_profile_consistency (pass->static_pass_number, true);
    2713            0 :           account_profile (pass->static_pass_number, true);
    2714              :         }
    2715              :     }
    2716              : 
    2717    317610932 :   verify_interpass_invariants ();
    2718              : 
    2719              :   /* Stop timevar.  */
    2720    317610932 :   if (pass->tv_id != TV_NONE)
    2721    230295590 :     timevar_pop (pass->tv_id);
    2722              : 
    2723    317610932 :   if (pass->type == IPA_PASS
    2724      2383751 :       && ((ipa_opt_pass_d *)pass)->function_transform)
    2725              :     {
    2726       358049 :       struct cgraph_node *node;
    2727      4422322 :       FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
    2728      4064273 :         if (!node->inlined_to)
    2729      2739622 :           node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass);
    2730              :     }
    2731    317252883 :   else if (dump_file)
    2732        52950 :     do_per_function (execute_function_dump, pass);
    2733              : 
    2734    317610932 :   if (!current_function_decl)
    2735      4694035 :     symtab->process_new_functions ();
    2736              : 
    2737    317610932 :   pass_fini_dump_file (pass);
    2738              : 
    2739    317610932 :   if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS)
    2740    312916897 :     gcc_assert (!(cfun->curr_properties & PROP_gimple)
    2741              :                 || pass->type != RTL_PASS);
    2742              : 
    2743    317610932 :   current_pass = NULL;
    2744    317610932 :   redirect_edge_var_map_empty ();
    2745              : 
    2746              :   /* Signal this is a suitable GC collection point.  */
    2747    317610932 :   if (!((todo_after | pass->todo_flags_finish) & TODO_do_not_ggc_collect))
    2748    316139570 :     ggc_collect ();
    2749              : 
    2750    317610932 :   if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
    2751      4694035 :     report_heap_memory_use ();
    2752              : 
    2753    317610932 :   if (auto channel = g->get_channels ().pass_events_channel.get_if_active ())
    2754           78 :     channel->publish (pass_events::after_pass {pass, cfun});
    2755              : 
    2756              :   return true;
    2757              : }
    2758              : 
    2759              : static void
    2760     21720397 : execute_pass_list_1 (opt_pass *pass)
    2761              : {
    2762    458007109 :   do
    2763              :     {
    2764    458007109 :       gcc_assert (pass->type == GIMPLE_PASS
    2765              :                   || pass->type == RTL_PASS);
    2766              : 
    2767    458007109 :       if (cfun == NULL)
    2768              :         return;
    2769    458006939 :       if (execute_one_pass (pass) && pass->sub)
    2770     11667122 :         execute_pass_list_1 (pass->sub);
    2771    458006917 :       pass = pass->next;
    2772              :     }
    2773    458006917 :   while (pass);
    2774              : }
    2775              : 
    2776              : void
    2777     10053275 : execute_pass_list (function *fn, opt_pass *pass)
    2778              : {
    2779     10053275 :   gcc_assert (fn == cfun);
    2780     10053275 :   execute_pass_list_1 (pass);
    2781     10053253 :   if (cfun && fn->cfg)
    2782              :     {
    2783      8580905 :       free_dominance_info (CDI_DOMINATORS);
    2784      8580905 :       free_dominance_info (CDI_POST_DOMINATORS);
    2785              :     }
    2786     10053253 : }
    2787              : 
    2788              : /* Write out all LTO data.  */
    2789              : static void
    2790        31226 : write_lto (void)
    2791              : {
    2792        31226 :   timevar_push (TV_IPA_LTO_GIMPLE_OUT);
    2793        31226 :   lto_output ();
    2794        31226 :   timevar_pop (TV_IPA_LTO_GIMPLE_OUT);
    2795        31226 :   timevar_push (TV_IPA_LTO_DECL_OUT);
    2796        31226 :   produce_asm_for_decls ();
    2797        31226 :   timevar_pop (TV_IPA_LTO_DECL_OUT);
    2798        31226 : }
    2799              : 
    2800              : /* Same as execute_pass_list but assume that subpasses of IPA passes
    2801              :    are local passes. If SET is not NULL, write out summaries of only
    2802              :    those node in SET. */
    2803              : 
    2804              : static void
    2805        23036 : ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
    2806              : {
    2807       460720 :   while (pass)
    2808              :     {
    2809       437684 :       ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *)pass;
    2810       437684 :       gcc_assert (!current_function_decl);
    2811       437684 :       gcc_assert (!cfun);
    2812       437684 :       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
    2813       437684 :       if (pass->type == IPA_PASS
    2814       414648 :           && ipa_pass->write_summary
    2815       598936 :           && pass->gate (cfun))
    2816              :         {
    2817              :           /* If a timevar is present, start it.  */
    2818       148640 :           if (pass->tv_id)
    2819       148640 :             timevar_push (pass->tv_id);
    2820              : 
    2821       148640 :           pass_init_dump_file (pass);
    2822              : 
    2823       148640 :           current_pass = pass;
    2824       148640 :           ipa_pass->write_summary ();
    2825              : 
    2826       148640 :           pass_fini_dump_file (pass);
    2827              : 
    2828              :           /* If a timevar is present, start it.  */
    2829       148640 :           if (pass->tv_id)
    2830       148640 :             timevar_pop (pass->tv_id);
    2831              :         }
    2832              : 
    2833       437684 :       if (pass->sub && pass->sub->type != GIMPLE_PASS)
    2834            0 :         ipa_write_summaries_2 (pass->sub, state);
    2835              : 
    2836       437684 :       pass = pass->next;
    2837              :     }
    2838        23036 : }
    2839              : 
    2840              : /* Helper function of ipa_write_summaries. Creates and destroys the
    2841              :    decl state and calls ipa_write_summaries_2 for all passes that have
    2842              :    summaries.  SET is the set of nodes to be written.  */
    2843              : 
    2844              : static void
    2845        23036 : ipa_write_summaries_1 (lto_symtab_encoder_t encoder,
    2846              :                        bool output_offload_tables_p)
    2847              : {
    2848        23036 :   pass_manager *passes = g->get_passes ();
    2849        23036 :   struct lto_out_decl_state *state = lto_new_out_decl_state ();
    2850        23036 :   state->symtab_node_encoder = encoder;
    2851        23036 :   state->output_offload_tables_p = output_offload_tables_p;
    2852              : 
    2853        23036 :   lto_output_init_mode_table ();
    2854        23036 :   lto_push_out_decl_state (state);
    2855              : 
    2856        23036 :   gcc_assert (!flag_wpa);
    2857        23036 :   ipa_write_summaries_2 (passes->all_regular_ipa_passes, state);
    2858              : 
    2859        23036 :   write_lto ();
    2860              : 
    2861        23036 :   gcc_assert (lto_get_out_decl_state () == state);
    2862        23036 :   lto_pop_out_decl_state ();
    2863        23036 :   lto_delete_out_decl_state (state);
    2864        23036 : }
    2865              : 
    2866              : /* Write out summaries for all the nodes in the callgraph.  */
    2867              : 
    2868              : void
    2869        23036 : ipa_write_summaries (void)
    2870              : {
    2871        23036 :   lto_symtab_encoder_t encoder;
    2872        23036 :   int i, order_pos;
    2873        23036 :   varpool_node *vnode;
    2874        23036 :   struct cgraph_node *node;
    2875        23036 :   struct cgraph_node **order;
    2876              : 
    2877        23036 :   if ((!flag_generate_lto && !flag_generate_offload) || seen_error ())
    2878            0 :     return;
    2879              : 
    2880        23036 :   gcc_assert (!dump_file);
    2881        23036 :   streamer_dump_file = dump_begin (TDI_lto_stream_out, NULL);
    2882              : 
    2883        23036 :   select_what_to_stream ();
    2884              : 
    2885        23036 :   encoder = lto_symtab_encoder_new (false);
    2886              : 
    2887              :   /* Create the callgraph set in the same order used in
    2888              :      cgraph_expand_all_functions.  This mostly facilitates debugging,
    2889              :      since it causes the gimple file to be processed in the same order
    2890              :      as the source code.  */
    2891        23036 :   order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
    2892        23036 :   order_pos = ipa_reverse_postorder (order);
    2893        23036 :   gcc_assert (order_pos == symtab->cgraph_count);
    2894              : 
    2895       360299 :   for (i = order_pos - 1; i >= 0; i--)
    2896              :     {
    2897       337263 :       struct cgraph_node *node = order[i];
    2898              : 
    2899       337263 :       if (node->definition && node->need_lto_streaming)
    2900              :         {
    2901       104547 :           if (gimple_has_body_p (node->decl))
    2902       101850 :             lto_prepare_function_for_streaming (node);
    2903       104547 :           lto_set_symtab_encoder_in_partition (encoder, node);
    2904              :         }
    2905              :     }
    2906              : 
    2907       127583 :   FOR_EACH_DEFINED_FUNCTION (node)
    2908       104547 :     if (node->alias && node->need_lto_streaming)
    2909         2411 :       lto_set_symtab_encoder_in_partition (encoder, node);
    2910       280530 :   FOR_EACH_DEFINED_VARIABLE (vnode)
    2911       257494 :     if (vnode->need_lto_streaming)
    2912       257494 :       lto_set_symtab_encoder_in_partition (encoder, vnode);
    2913              : 
    2914        23036 :   asm_node *anode;
    2915        23120 :   for (anode = symtab->first_asm_symbol (); anode;
    2916           84 :        anode = safe_as_a<asm_node*> (anode->next))
    2917           84 :     lto_set_symtab_encoder_in_partition (encoder, anode);
    2918              : 
    2919        23036 :   ipa_write_summaries_1 (compute_ltrans_boundary (encoder),
    2920        23036 :                          flag_generate_offload);
    2921              : 
    2922        23036 :   free (order);
    2923        23036 :   if (streamer_dump_file)
    2924              :     {
    2925            4 :       dump_end (TDI_lto_stream_out, streamer_dump_file);
    2926            4 :       streamer_dump_file = NULL;
    2927              :     }
    2928              : }
    2929              : 
    2930              : /* Same as execute_pass_list but assume that subpasses of IPA passes
    2931              :    are local passes. If SET is not NULL, write out optimization summaries of
    2932              :    only those node in SET. */
    2933              : 
    2934              : static void
    2935         8190 : ipa_write_optimization_summaries_1 (opt_pass *pass,
    2936              :                                     struct lto_out_decl_state *state)
    2937              : {
    2938       163800 :   while (pass)
    2939              :     {
    2940       155610 :       ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *)pass;
    2941       155610 :       gcc_assert (!current_function_decl);
    2942       155610 :       gcc_assert (!cfun);
    2943       155610 :       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
    2944       155610 :       if (pass->type == IPA_PASS
    2945       147420 :           && ipa_pass->write_optimization_summary
    2946       180180 :           && pass->gate (cfun))
    2947              :         {
    2948              :           /* If a timevar is present, start it.  */
    2949        24570 :           if (pass->tv_id)
    2950        24570 :             timevar_push (pass->tv_id);
    2951              : 
    2952        24570 :           pass_init_dump_file (pass);
    2953              : 
    2954        24570 :           current_pass = pass;
    2955        24570 :           ipa_pass->write_optimization_summary ();
    2956              : 
    2957        24570 :           pass_fini_dump_file (pass);
    2958              : 
    2959              :           /* If a timevar is present, start it.  */
    2960        24570 :           if (pass->tv_id)
    2961        24570 :             timevar_pop (pass->tv_id);
    2962              :         }
    2963              : 
    2964       155610 :       if (pass->sub && pass->sub->type != GIMPLE_PASS)
    2965            0 :         ipa_write_optimization_summaries_1 (pass->sub, state);
    2966              : 
    2967       155610 :       pass = pass->next;
    2968              :     }
    2969         8190 : }
    2970              : 
    2971              : /* Write all the optimization summaries for the cgraph nodes in SET.  If SET is
    2972              :    NULL, write out all summaries of all nodes. */
    2973              : 
    2974              : void
    2975         8190 : ipa_write_optimization_summaries (lto_symtab_encoder_t encoder,
    2976              :                                   bool output_offload_tables_p)
    2977              : {
    2978         8190 :   struct lto_out_decl_state *state = lto_new_out_decl_state ();
    2979         8190 :   state->symtab_node_encoder = encoder;
    2980         8190 :   state->output_offload_tables_p = output_offload_tables_p;
    2981              : 
    2982         8190 :   lto_output_init_mode_table ();
    2983         8190 :   lto_push_out_decl_state (state);
    2984              : 
    2985              :   /* Be sure that we did not forget to renumber stmt uids.  */
    2986         8190 :   gcc_checking_assert (flag_wpa);
    2987              : 
    2988         8190 :   gcc_assert (flag_wpa);
    2989         8190 :   pass_manager *passes = g->get_passes ();
    2990         8190 :   ipa_write_optimization_summaries_1 (passes->all_regular_ipa_passes, state);
    2991              : 
    2992         8190 :   write_lto ();
    2993              : 
    2994         8190 :   gcc_assert (lto_get_out_decl_state () == state);
    2995         8190 :   lto_pop_out_decl_state ();
    2996         8190 :   lto_delete_out_decl_state (state);
    2997         8190 : }
    2998              : 
    2999              : /* Same as execute_pass_list but assume that subpasses of IPA passes
    3000              :    are local passes.  */
    3001              : 
    3002              : static void
    3003        12202 : ipa_read_summaries_1 (opt_pass *pass)
    3004              : {
    3005       244040 :   while (pass)
    3006              :     {
    3007       231838 :       ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
    3008              : 
    3009       231838 :       gcc_assert (!current_function_decl);
    3010       231838 :       gcc_assert (!cfun);
    3011       231838 :       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
    3012              : 
    3013       231838 :       if (pass->gate (cfun))
    3014              :         {
    3015       193171 :           if (pass->type == IPA_PASS && ipa_pass->read_summary)
    3016              :             {
    3017              :               /* If a timevar is present, start it.  */
    3018        83335 :               if (pass->tv_id)
    3019        83335 :                 timevar_push (pass->tv_id);
    3020        83335 :               if (!quiet_flag)
    3021            0 :                 fprintf (stderr, " <%s>", pass->name ? pass->name : "");
    3022              : 
    3023        83335 :               pass_init_dump_file (pass);
    3024              : 
    3025        83335 :               current_pass = pass;
    3026        83335 :               ipa_pass->read_summary ();
    3027              : 
    3028        83335 :               pass_fini_dump_file (pass);
    3029              : 
    3030              :               /* Stop timevar.  */
    3031        83335 :               if (pass->tv_id)
    3032        83335 :                 timevar_pop (pass->tv_id);
    3033        83335 :               ggc_grow ();
    3034        83335 :               report_heap_memory_use ();
    3035              :             }
    3036              : 
    3037       193171 :           if (pass->sub && pass->sub->type != GIMPLE_PASS)
    3038            0 :             ipa_read_summaries_1 (pass->sub);
    3039              :         }
    3040       231838 :       pass = pass->next;
    3041              :     }
    3042        12202 : }
    3043              : 
    3044              : 
    3045              : /* Read all the summaries for all_regular_ipa_passes.  */
    3046              : 
    3047              : void
    3048        12202 : ipa_read_summaries (void)
    3049              : {
    3050        12202 :   pass_manager *passes = g->get_passes ();
    3051        12202 :   ipa_read_summaries_1 (passes->all_regular_ipa_passes);
    3052        12202 : }
    3053              : 
    3054              : /* Same as execute_pass_list but assume that subpasses of IPA passes
    3055              :    are local passes.  */
    3056              : 
    3057              : static void
    3058         8190 : ipa_read_optimization_summaries_1 (opt_pass *pass)
    3059              : {
    3060       163800 :   while (pass)
    3061              :     {
    3062       155610 :       ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
    3063              : 
    3064       155610 :       gcc_assert (!current_function_decl);
    3065       155610 :       gcc_assert (!cfun);
    3066       155610 :       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
    3067              : 
    3068       155610 :       if (pass->gate (cfun))
    3069              :         {
    3070       120820 :           if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
    3071              :             {
    3072              :               /* If a timevar is present, start it.  */
    3073        24570 :               if (pass->tv_id)
    3074        24570 :                 timevar_push (pass->tv_id);
    3075        24570 :               if (!quiet_flag)
    3076            0 :                 fprintf (stderr, " <%s>", pass->name ? pass->name : "");
    3077              : 
    3078        24570 :               pass_init_dump_file (pass);
    3079              : 
    3080        24570 :               current_pass = pass;
    3081        24570 :               ipa_pass->read_optimization_summary ();
    3082              : 
    3083        24570 :               pass_fini_dump_file (pass);
    3084              : 
    3085              :               /* Stop timevar.  */
    3086        24570 :               if (pass->tv_id)
    3087        24570 :                 timevar_pop (pass->tv_id);
    3088              :             }
    3089              : 
    3090       120820 :           if (pass->sub && pass->sub->type != GIMPLE_PASS)
    3091            0 :             ipa_read_optimization_summaries_1 (pass->sub);
    3092       120820 :           ggc_grow ();
    3093       120820 :           report_heap_memory_use ();
    3094              :         }
    3095       155610 :       pass = pass->next;
    3096              :     }
    3097         8190 : }
    3098              : 
    3099              : /* Read all the summaries for all_regular_ipa_passes.  */
    3100              : 
    3101              : void
    3102         8190 : ipa_read_optimization_summaries (void)
    3103              : {
    3104         8190 :   pass_manager *passes = g->get_passes ();
    3105         8190 :   ipa_read_optimization_summaries_1 (passes->all_regular_ipa_passes);
    3106         8190 : }
    3107              : 
    3108              : /* Same as execute_pass_list but assume that subpasses of IPA passes
    3109              :    are local passes.  */
    3110              : void
    3111       692472 : execute_ipa_pass_list (opt_pass *pass)
    3112              : {
    3113      8975308 :   do
    3114              :     {
    3115      8975308 :       gcc_assert (!current_function_decl);
    3116      8975308 :       gcc_assert (!cfun);
    3117      8975308 :       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
    3118      8975308 :       if (execute_one_pass (pass) && pass->sub)
    3119              :         {
    3120       464408 :           if (pass->sub->type == GIMPLE_PASS)
    3121              :             {
    3122       462382 :               invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
    3123       462382 :               do_per_function_toporder ((void (*)(function *, void *))
    3124              :                                           execute_pass_list,
    3125       462382 :                                         pass->sub);
    3126       462382 :               invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
    3127              :             }
    3128         2026 :           else if (pass->sub->type == SIMPLE_IPA_PASS
    3129         2026 :                    || pass->sub->type == IPA_PASS)
    3130         2026 :             execute_ipa_pass_list (pass->sub);
    3131              :           else
    3132            0 :             gcc_unreachable ();
    3133              :         }
    3134      8975308 :       gcc_assert (!current_function_decl);
    3135      8975308 :       symtab->process_new_functions ();
    3136      8975308 :       pass = pass->next;
    3137              :     }
    3138      8975308 :   while (pass);
    3139       692472 : }
    3140              : 
    3141              : /* Execute stmt fixup hooks of all passes in PASS for NODE and STMTS.  */
    3142              : 
    3143              : static void
    3144        83453 : execute_ipa_stmt_fixups (opt_pass *pass,
    3145              :                          struct cgraph_node *node, gimple **stmts)
    3146              : {
    3147      1669060 :   while (pass)
    3148              :     {
    3149              :       /* Execute all of the IPA_PASSes in the list.  */
    3150      1585607 :       if (pass->type == IPA_PASS
    3151      1585607 :           && pass->gate (cfun))
    3152              :         {
    3153      1208408 :           ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
    3154              : 
    3155      1208408 :           if (ipa_pass->stmt_fixup)
    3156              :             {
    3157            0 :               pass_init_dump_file (pass);
    3158              :               /* If a timevar is present, start it.  */
    3159            0 :               if (pass->tv_id)
    3160            0 :                 timevar_push (pass->tv_id);
    3161              : 
    3162            0 :               current_pass = pass;
    3163            0 :               ipa_pass->stmt_fixup (node, stmts);
    3164              : 
    3165              :               /* Stop timevar.  */
    3166            0 :               if (pass->tv_id)
    3167            0 :                 timevar_pop (pass->tv_id);
    3168            0 :               pass_fini_dump_file (pass);
    3169              :             }
    3170      1208408 :           if (pass->sub)
    3171            0 :             execute_ipa_stmt_fixups (pass->sub, node, stmts);
    3172              :         }
    3173      1585607 :       pass = pass->next;
    3174              :     }
    3175        83453 : }
    3176              : 
    3177              : /* Execute stmt fixup hooks of all IPA passes for NODE and STMTS.  */
    3178              : 
    3179              : void
    3180        83453 : execute_all_ipa_stmt_fixups (struct cgraph_node *node, gimple **stmts)
    3181              : {
    3182        83453 :   pass_manager *passes = g->get_passes ();
    3183        83453 :   execute_ipa_stmt_fixups (passes->all_regular_ipa_passes, node, stmts);
    3184        83453 : }
    3185              : 
    3186              : 
    3187              : extern void debug_properties (unsigned int);
    3188              : extern void dump_properties (FILE *, unsigned int);
    3189              : 
    3190              : DEBUG_FUNCTION void
    3191            0 : dump_properties (FILE *dump, unsigned int props)
    3192              : {
    3193            0 :   fprintf (dump, "Properties:\n");
    3194            0 :   if (props & PROP_gimple_any)
    3195            0 :     fprintf (dump, "PROP_gimple_any\n");
    3196            0 :   if (props & PROP_gimple_lcf)
    3197            0 :     fprintf (dump, "PROP_gimple_lcf\n");
    3198            0 :   if (props & PROP_gimple_leh)
    3199            0 :     fprintf (dump, "PROP_gimple_leh\n");
    3200            0 :   if (props & PROP_cfg)
    3201            0 :     fprintf (dump, "PROP_cfg\n");
    3202            0 :   if (props & PROP_ssa)
    3203            0 :     fprintf (dump, "PROP_ssa\n");
    3204            0 :   if (props & PROP_no_crit_edges)
    3205            0 :     fprintf (dump, "PROP_no_crit_edges\n");
    3206            0 :   if (props & PROP_rtl)
    3207            0 :     fprintf (dump, "PROP_rtl\n");
    3208            0 :   if (props & PROP_gimple_lomp)
    3209            0 :     fprintf (dump, "PROP_gimple_lomp\n");
    3210            0 :   if (props & PROP_gimple_lomp_dev)
    3211            0 :     fprintf (dump, "PROP_gimple_lomp_dev\n");
    3212            0 :   if (props & PROP_gimple_lcx)
    3213            0 :     fprintf (dump, "PROP_gimple_lcx\n");
    3214            0 :   if (props & PROP_gimple_lvec)
    3215            0 :     fprintf (dump, "PROP_gimple_lvec\n");
    3216            0 :   if (props & PROP_cfglayout)
    3217            0 :     fprintf (dump, "PROP_cfglayout\n");
    3218            0 : }
    3219              : 
    3220              : DEBUG_FUNCTION void
    3221            0 : debug_properties (unsigned int props)
    3222              : {
    3223            0 :   dump_properties (stderr, props);
    3224            0 : }
    3225              : 
    3226              : /* Called by local passes to see if function is called by already processed nodes.
    3227              :    Because we process nodes in topological order, this means that function is
    3228              :    in recursive cycle or we introduced new direct calls.  */
    3229              : bool
    3230      4668106 : function_called_by_processed_nodes_p (void)
    3231              : {
    3232      4668106 :   struct cgraph_edge *e;
    3233      4668106 :   for (e = cgraph_node::get (current_function_decl)->callers;
    3234     12019969 :        e;
    3235      7351863 :        e = e->next_caller)
    3236              :     {
    3237      7355247 :       if (e->caller->decl == current_function_decl)
    3238            0 :         continue;
    3239      7355247 :       if (!e->caller->has_gimple_body_p ())
    3240            0 :         continue;
    3241      7355247 :       if (TREE_ASM_WRITTEN (e->caller->decl))
    3242            0 :         continue;
    3243      7355247 :       if (!e->caller->process && !e->caller->inlined_to)
    3244              :         break;
    3245              :     }
    3246      4668106 :   if (dump_file && e)
    3247              :     {
    3248            1 :       fprintf (dump_file, "Already processed call to:\n");
    3249            1 :       e->caller->dump (dump_file);
    3250              :     }
    3251      4668106 :   return e != NULL;
    3252              : }
        

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.