LCOV - code coverage report
Current view: top level - gcc - passes.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 1004 1232 81.5 %
Date: 2020-04-04 11:58:09 Functions: 90 104 86.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.