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

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.