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