1*e4b17023SJohn Marino /* Top level of GCC compilers (cc1, cc1plus, etc.) 2*e4b17023SJohn Marino Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3*e4b17023SJohn Marino 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 4*e4b17023SJohn Marino 2011, 2012 Free Software Foundation, Inc. 5*e4b17023SJohn Marino 6*e4b17023SJohn Marino This file is part of GCC. 7*e4b17023SJohn Marino 8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under 9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free 10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later 11*e4b17023SJohn Marino version. 12*e4b17023SJohn Marino 13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or 15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16*e4b17023SJohn Marino for more details. 17*e4b17023SJohn Marino 18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino /* This is the top level of cc1/c++. 23*e4b17023SJohn Marino It parses command args, opens files, invokes the various passes 24*e4b17023SJohn Marino in the proper order, and counts the time used by each. 25*e4b17023SJohn Marino Error messages and low-level interface to malloc also handled here. */ 26*e4b17023SJohn Marino 27*e4b17023SJohn Marino #include "config.h" 28*e4b17023SJohn Marino #include "system.h" 29*e4b17023SJohn Marino #include "coretypes.h" 30*e4b17023SJohn Marino #include "tm.h" 31*e4b17023SJohn Marino #include "line-map.h" 32*e4b17023SJohn Marino #include "input.h" 33*e4b17023SJohn Marino #include "tree.h" 34*e4b17023SJohn Marino #include "rtl.h" 35*e4b17023SJohn Marino #include "tm_p.h" 36*e4b17023SJohn Marino #include "flags.h" 37*e4b17023SJohn Marino #include "insn-attr.h" 38*e4b17023SJohn Marino #include "insn-config.h" 39*e4b17023SJohn Marino #include "insn-flags.h" 40*e4b17023SJohn Marino #include "hard-reg-set.h" 41*e4b17023SJohn Marino #include "recog.h" 42*e4b17023SJohn Marino #include "output.h" 43*e4b17023SJohn Marino #include "except.h" 44*e4b17023SJohn Marino #include "function.h" 45*e4b17023SJohn Marino #include "toplev.h" 46*e4b17023SJohn Marino #include "expr.h" 47*e4b17023SJohn Marino #include "basic-block.h" 48*e4b17023SJohn Marino #include "intl.h" 49*e4b17023SJohn Marino #include "ggc.h" 50*e4b17023SJohn Marino #include "graph.h" 51*e4b17023SJohn Marino #include "regs.h" 52*e4b17023SJohn Marino #include "timevar.h" 53*e4b17023SJohn Marino #include "diagnostic-core.h" 54*e4b17023SJohn Marino #include "params.h" 55*e4b17023SJohn Marino #include "reload.h" 56*e4b17023SJohn Marino #include "dwarf2asm.h" 57*e4b17023SJohn Marino #include "integrate.h" 58*e4b17023SJohn Marino #include "debug.h" 59*e4b17023SJohn Marino #include "target.h" 60*e4b17023SJohn Marino #include "langhooks.h" 61*e4b17023SJohn Marino #include "cfglayout.h" 62*e4b17023SJohn Marino #include "cfgloop.h" 63*e4b17023SJohn Marino #include "hosthooks.h" 64*e4b17023SJohn Marino #include "cgraph.h" 65*e4b17023SJohn Marino #include "opts.h" 66*e4b17023SJohn Marino #include "coverage.h" 67*e4b17023SJohn Marino #include "value-prof.h" 68*e4b17023SJohn Marino #include "tree-inline.h" 69*e4b17023SJohn Marino #include "tree-flow.h" 70*e4b17023SJohn Marino #include "tree-pass.h" 71*e4b17023SJohn Marino #include "tree-dump.h" 72*e4b17023SJohn Marino #include "df.h" 73*e4b17023SJohn Marino #include "predict.h" 74*e4b17023SJohn Marino #include "lto-streamer.h" 75*e4b17023SJohn Marino #include "plugin.h" 76*e4b17023SJohn Marino #include "ipa-utils.h" 77*e4b17023SJohn Marino #include "tree-pretty-print.h" 78*e4b17023SJohn Marino 79*e4b17023SJohn Marino #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) 80*e4b17023SJohn Marino #include "dwarf2out.h" 81*e4b17023SJohn Marino #endif 82*e4b17023SJohn Marino 83*e4b17023SJohn Marino #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 84*e4b17023SJohn Marino #include "dbxout.h" 85*e4b17023SJohn Marino #endif 86*e4b17023SJohn Marino 87*e4b17023SJohn Marino #ifdef SDB_DEBUGGING_INFO 88*e4b17023SJohn Marino #include "sdbout.h" 89*e4b17023SJohn Marino #endif 90*e4b17023SJohn Marino 91*e4b17023SJohn Marino #ifdef XCOFF_DEBUGGING_INFO 92*e4b17023SJohn Marino #include "xcoffout.h" /* Needed for external data 93*e4b17023SJohn Marino declarations for e.g. AIX 4.x. */ 94*e4b17023SJohn Marino #endif 95*e4b17023SJohn Marino 96*e4b17023SJohn Marino /* This is used for debugging. It allows the current pass to printed 97*e4b17023SJohn Marino from anywhere in compilation. 98*e4b17023SJohn Marino The variable current_pass is also used for statistics and plugins. */ 99*e4b17023SJohn Marino struct opt_pass *current_pass; 100*e4b17023SJohn Marino 101*e4b17023SJohn Marino static void register_pass_name (struct opt_pass *, const char *); 102*e4b17023SJohn Marino 103*e4b17023SJohn Marino /* Call from anywhere to find out what pass this is. Useful for 104*e4b17023SJohn Marino printing out debugging information deep inside an service 105*e4b17023SJohn Marino routine. */ 106*e4b17023SJohn Marino void 107*e4b17023SJohn Marino print_current_pass (FILE *file) 108*e4b17023SJohn Marino { 109*e4b17023SJohn Marino if (current_pass) 110*e4b17023SJohn Marino fprintf (file, "current pass = %s (%d)\n", 111*e4b17023SJohn Marino current_pass->name, current_pass->static_pass_number); 112*e4b17023SJohn Marino else 113*e4b17023SJohn Marino fprintf (file, "no current pass.\n"); 114*e4b17023SJohn Marino } 115*e4b17023SJohn Marino 116*e4b17023SJohn Marino 117*e4b17023SJohn Marino /* Call from the debugger to get the current pass name. */ 118*e4b17023SJohn Marino DEBUG_FUNCTION void 119*e4b17023SJohn Marino debug_pass (void) 120*e4b17023SJohn Marino { 121*e4b17023SJohn Marino print_current_pass (stderr); 122*e4b17023SJohn Marino } 123*e4b17023SJohn Marino 124*e4b17023SJohn Marino 125*e4b17023SJohn Marino 126*e4b17023SJohn Marino /* Global variables used to communicate with passes. */ 127*e4b17023SJohn Marino int dump_flags; 128*e4b17023SJohn Marino bool in_gimple_form; 129*e4b17023SJohn Marino bool first_pass_instance; 130*e4b17023SJohn Marino 131*e4b17023SJohn Marino 132*e4b17023SJohn Marino /* This is called from various places for FUNCTION_DECL, VAR_DECL, 133*e4b17023SJohn Marino and TYPE_DECL nodes. 134*e4b17023SJohn Marino 135*e4b17023SJohn Marino This does nothing for local (non-static) variables, unless the 136*e4b17023SJohn Marino variable is a register variable with DECL_ASSEMBLER_NAME set. In 137*e4b17023SJohn Marino that case, or if the variable is not an automatic, it sets up the 138*e4b17023SJohn Marino RTL and outputs any assembler code (label definition, storage 139*e4b17023SJohn Marino allocation and initialization). 140*e4b17023SJohn Marino 141*e4b17023SJohn Marino DECL is the declaration. TOP_LEVEL is nonzero 142*e4b17023SJohn Marino if this declaration is not within a function. */ 143*e4b17023SJohn Marino 144*e4b17023SJohn Marino void 145*e4b17023SJohn Marino rest_of_decl_compilation (tree decl, 146*e4b17023SJohn Marino int top_level, 147*e4b17023SJohn Marino int at_end) 148*e4b17023SJohn Marino { 149*e4b17023SJohn Marino /* We deferred calling assemble_alias so that we could collect 150*e4b17023SJohn Marino other attributes such as visibility. Emit the alias now. */ 151*e4b17023SJohn Marino if (!in_lto_p) 152*e4b17023SJohn Marino { 153*e4b17023SJohn Marino tree alias; 154*e4b17023SJohn Marino alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)); 155*e4b17023SJohn Marino if (alias) 156*e4b17023SJohn Marino { 157*e4b17023SJohn Marino alias = TREE_VALUE (TREE_VALUE (alias)); 158*e4b17023SJohn Marino alias = get_identifier (TREE_STRING_POINTER (alias)); 159*e4b17023SJohn Marino /* A quirk of the initial implementation of aliases required that the 160*e4b17023SJohn Marino user add "extern" to all of them. Which is silly, but now 161*e4b17023SJohn Marino historical. Do note that the symbol is in fact locally defined. */ 162*e4b17023SJohn Marino if (!lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) 163*e4b17023SJohn Marino DECL_EXTERNAL (decl) = 0; 164*e4b17023SJohn Marino assemble_alias (decl, alias); 165*e4b17023SJohn Marino } 166*e4b17023SJohn Marino } 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino /* Can't defer this, because it needs to happen before any 169*e4b17023SJohn Marino later function definitions are processed. */ 170*e4b17023SJohn Marino if (DECL_ASSEMBLER_NAME_SET_P (decl) && DECL_REGISTER (decl)) 171*e4b17023SJohn Marino make_decl_rtl (decl); 172*e4b17023SJohn Marino 173*e4b17023SJohn Marino /* Forward declarations for nested functions are not "external", 174*e4b17023SJohn Marino but we need to treat them as if they were. */ 175*e4b17023SJohn Marino if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) 176*e4b17023SJohn Marino || TREE_CODE (decl) == FUNCTION_DECL) 177*e4b17023SJohn Marino { 178*e4b17023SJohn Marino timevar_push (TV_VARCONST); 179*e4b17023SJohn Marino 180*e4b17023SJohn Marino /* Don't output anything when a tentative file-scope definition 181*e4b17023SJohn Marino is seen. But at end of compilation, do output code for them. 182*e4b17023SJohn Marino 183*e4b17023SJohn Marino We do output all variables and rely on 184*e4b17023SJohn Marino callgraph code to defer them except for forward declarations 185*e4b17023SJohn Marino (see gcc.c-torture/compile/920624-1.c) */ 186*e4b17023SJohn Marino if ((at_end 187*e4b17023SJohn Marino || !DECL_DEFER_OUTPUT (decl) 188*e4b17023SJohn Marino || DECL_INITIAL (decl)) 189*e4b17023SJohn Marino && !DECL_EXTERNAL (decl)) 190*e4b17023SJohn Marino { 191*e4b17023SJohn Marino /* When reading LTO unit, we also read varpool, so do not 192*e4b17023SJohn Marino rebuild it. */ 193*e4b17023SJohn Marino if (in_lto_p && !at_end) 194*e4b17023SJohn Marino ; 195*e4b17023SJohn Marino else if (TREE_CODE (decl) != FUNCTION_DECL) 196*e4b17023SJohn Marino varpool_finalize_decl (decl); 197*e4b17023SJohn Marino } 198*e4b17023SJohn Marino 199*e4b17023SJohn Marino #ifdef ASM_FINISH_DECLARE_OBJECT 200*e4b17023SJohn Marino if (decl == last_assemble_variable_decl) 201*e4b17023SJohn Marino { 202*e4b17023SJohn Marino ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, 203*e4b17023SJohn Marino top_level, at_end); 204*e4b17023SJohn Marino } 205*e4b17023SJohn Marino #endif 206*e4b17023SJohn Marino 207*e4b17023SJohn Marino timevar_pop (TV_VARCONST); 208*e4b17023SJohn Marino } 209*e4b17023SJohn Marino else if (TREE_CODE (decl) == TYPE_DECL 210*e4b17023SJohn Marino /* Like in rest_of_type_compilation, avoid confusing the debug 211*e4b17023SJohn Marino information machinery when there are errors. */ 212*e4b17023SJohn Marino && !seen_error ()) 213*e4b17023SJohn Marino { 214*e4b17023SJohn Marino timevar_push (TV_SYMOUT); 215*e4b17023SJohn Marino debug_hooks->type_decl (decl, !top_level); 216*e4b17023SJohn Marino timevar_pop (TV_SYMOUT); 217*e4b17023SJohn Marino } 218*e4b17023SJohn Marino 219*e4b17023SJohn Marino /* Let cgraph know about the existence of variables. */ 220*e4b17023SJohn Marino if (in_lto_p && !at_end) 221*e4b17023SJohn Marino ; 222*e4b17023SJohn Marino else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl) 223*e4b17023SJohn Marino && TREE_STATIC (decl)) 224*e4b17023SJohn Marino varpool_node (decl); 225*e4b17023SJohn Marino } 226*e4b17023SJohn Marino 227*e4b17023SJohn Marino /* Called after finishing a record, union or enumeral type. */ 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino void 230*e4b17023SJohn Marino rest_of_type_compilation (tree type, int toplev) 231*e4b17023SJohn Marino { 232*e4b17023SJohn Marino /* Avoid confusing the debug information machinery when there are 233*e4b17023SJohn Marino errors. */ 234*e4b17023SJohn Marino if (seen_error ()) 235*e4b17023SJohn Marino return; 236*e4b17023SJohn Marino 237*e4b17023SJohn Marino timevar_push (TV_SYMOUT); 238*e4b17023SJohn Marino debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev); 239*e4b17023SJohn Marino timevar_pop (TV_SYMOUT); 240*e4b17023SJohn Marino } 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino 243*e4b17023SJohn Marino 244*e4b17023SJohn Marino void 245*e4b17023SJohn Marino finish_optimization_passes (void) 246*e4b17023SJohn Marino { 247*e4b17023SJohn Marino int i; 248*e4b17023SJohn Marino struct dump_file_info *dfi; 249*e4b17023SJohn Marino char *name; 250*e4b17023SJohn Marino 251*e4b17023SJohn Marino timevar_push (TV_DUMP); 252*e4b17023SJohn Marino if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) 253*e4b17023SJohn Marino { 254*e4b17023SJohn Marino dump_file = dump_begin (pass_profile.pass.static_pass_number, NULL); 255*e4b17023SJohn Marino end_branch_prob (); 256*e4b17023SJohn Marino if (dump_file) 257*e4b17023SJohn Marino dump_end (pass_profile.pass.static_pass_number, dump_file); 258*e4b17023SJohn Marino } 259*e4b17023SJohn Marino 260*e4b17023SJohn Marino if (optimize > 0) 261*e4b17023SJohn Marino { 262*e4b17023SJohn Marino dump_file = dump_begin (pass_combine.pass.static_pass_number, NULL); 263*e4b17023SJohn Marino if (dump_file) 264*e4b17023SJohn Marino { 265*e4b17023SJohn Marino dump_combine_total_stats (dump_file); 266*e4b17023SJohn Marino dump_end (pass_combine.pass.static_pass_number, dump_file); 267*e4b17023SJohn Marino } 268*e4b17023SJohn Marino } 269*e4b17023SJohn Marino 270*e4b17023SJohn Marino /* Do whatever is necessary to finish printing the graphs. */ 271*e4b17023SJohn Marino if (graph_dump_format != no_graph) 272*e4b17023SJohn Marino for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i) 273*e4b17023SJohn Marino if (dump_initialized_p (i) 274*e4b17023SJohn Marino && (dfi->flags & TDF_GRAPH) != 0 275*e4b17023SJohn Marino && (name = get_dump_file_name (i)) != NULL) 276*e4b17023SJohn Marino { 277*e4b17023SJohn Marino finish_graph_dump_file (name); 278*e4b17023SJohn Marino free (name); 279*e4b17023SJohn Marino } 280*e4b17023SJohn Marino 281*e4b17023SJohn Marino timevar_pop (TV_DUMP); 282*e4b17023SJohn Marino } 283*e4b17023SJohn Marino 284*e4b17023SJohn Marino static bool 285*e4b17023SJohn Marino gate_rest_of_compilation (void) 286*e4b17023SJohn Marino { 287*e4b17023SJohn Marino /* Early return if there were errors. We can run afoul of our 288*e4b17023SJohn Marino consistency checks, and there's not really much point in fixing them. */ 289*e4b17023SJohn Marino return !(rtl_dump_and_exit || flag_syntax_only || seen_error ()); 290*e4b17023SJohn Marino } 291*e4b17023SJohn Marino 292*e4b17023SJohn Marino struct gimple_opt_pass pass_rest_of_compilation = 293*e4b17023SJohn Marino { 294*e4b17023SJohn Marino { 295*e4b17023SJohn Marino GIMPLE_PASS, 296*e4b17023SJohn Marino "*rest_of_compilation", /* name */ 297*e4b17023SJohn Marino gate_rest_of_compilation, /* gate */ 298*e4b17023SJohn Marino NULL, /* execute */ 299*e4b17023SJohn Marino NULL, /* sub */ 300*e4b17023SJohn Marino NULL, /* next */ 301*e4b17023SJohn Marino 0, /* static_pass_number */ 302*e4b17023SJohn Marino TV_REST_OF_COMPILATION, /* tv_id */ 303*e4b17023SJohn Marino PROP_rtl, /* properties_required */ 304*e4b17023SJohn Marino 0, /* properties_provided */ 305*e4b17023SJohn Marino 0, /* properties_destroyed */ 306*e4b17023SJohn Marino 0, /* todo_flags_start */ 307*e4b17023SJohn Marino TODO_ggc_collect /* todo_flags_finish */ 308*e4b17023SJohn Marino } 309*e4b17023SJohn Marino }; 310*e4b17023SJohn Marino 311*e4b17023SJohn Marino static bool 312*e4b17023SJohn Marino gate_postreload (void) 313*e4b17023SJohn Marino { 314*e4b17023SJohn Marino return reload_completed; 315*e4b17023SJohn Marino } 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino struct rtl_opt_pass pass_postreload = 318*e4b17023SJohn Marino { 319*e4b17023SJohn Marino { 320*e4b17023SJohn Marino RTL_PASS, 321*e4b17023SJohn Marino "*all-postreload", /* name */ 322*e4b17023SJohn Marino gate_postreload, /* gate */ 323*e4b17023SJohn Marino NULL, /* execute */ 324*e4b17023SJohn Marino NULL, /* sub */ 325*e4b17023SJohn Marino NULL, /* next */ 326*e4b17023SJohn Marino 0, /* static_pass_number */ 327*e4b17023SJohn Marino TV_POSTRELOAD, /* tv_id */ 328*e4b17023SJohn Marino PROP_rtl, /* properties_required */ 329*e4b17023SJohn Marino 0, /* properties_provided */ 330*e4b17023SJohn Marino 0, /* properties_destroyed */ 331*e4b17023SJohn Marino 0, /* todo_flags_start */ 332*e4b17023SJohn Marino TODO_ggc_collect | TODO_verify_rtl_sharing /* todo_flags_finish */ 333*e4b17023SJohn Marino } 334*e4b17023SJohn Marino }; 335*e4b17023SJohn Marino 336*e4b17023SJohn Marino 337*e4b17023SJohn Marino 338*e4b17023SJohn Marino /* The root of the compilation pass tree, once constructed. */ 339*e4b17023SJohn Marino struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes, 340*e4b17023SJohn Marino *all_regular_ipa_passes, *all_late_ipa_passes, *all_lto_gen_passes; 341*e4b17023SJohn Marino 342*e4b17023SJohn Marino /* This is used by plugins, and should also be used in register_pass. */ 343*e4b17023SJohn Marino #define DEF_PASS_LIST(LIST) &LIST, 344*e4b17023SJohn Marino struct opt_pass **gcc_pass_lists[] = { GCC_PASS_LISTS NULL }; 345*e4b17023SJohn Marino #undef DEF_PASS_LIST 346*e4b17023SJohn Marino 347*e4b17023SJohn Marino /* A map from static pass id to optimization pass. */ 348*e4b17023SJohn Marino struct opt_pass **passes_by_id; 349*e4b17023SJohn Marino int passes_by_id_size; 350*e4b17023SJohn Marino 351*e4b17023SJohn Marino /* Set the static pass number of pass PASS to ID and record that 352*e4b17023SJohn Marino in the mapping from static pass number to pass. */ 353*e4b17023SJohn Marino 354*e4b17023SJohn Marino static void 355*e4b17023SJohn Marino set_pass_for_id (int id, struct opt_pass *pass) 356*e4b17023SJohn Marino { 357*e4b17023SJohn Marino pass->static_pass_number = id; 358*e4b17023SJohn Marino if (passes_by_id_size <= id) 359*e4b17023SJohn Marino { 360*e4b17023SJohn Marino passes_by_id = XRESIZEVEC (struct opt_pass *, passes_by_id, id + 1); 361*e4b17023SJohn Marino memset (passes_by_id + passes_by_id_size, 0, 362*e4b17023SJohn Marino (id + 1 - passes_by_id_size) * sizeof (void *)); 363*e4b17023SJohn Marino passes_by_id_size = id + 1; 364*e4b17023SJohn Marino } 365*e4b17023SJohn Marino passes_by_id[id] = pass; 366*e4b17023SJohn Marino } 367*e4b17023SJohn Marino 368*e4b17023SJohn Marino /* Return the pass with the static pass number ID. */ 369*e4b17023SJohn Marino 370*e4b17023SJohn Marino struct opt_pass * 371*e4b17023SJohn Marino get_pass_for_id (int id) 372*e4b17023SJohn Marino { 373*e4b17023SJohn Marino if (id >= passes_by_id_size) 374*e4b17023SJohn Marino return NULL; 375*e4b17023SJohn Marino return passes_by_id[id]; 376*e4b17023SJohn Marino } 377*e4b17023SJohn Marino 378*e4b17023SJohn Marino /* Iterate over the pass tree allocating dump file numbers. We want 379*e4b17023SJohn Marino to do this depth first, and independent of whether the pass is 380*e4b17023SJohn Marino enabled or not. */ 381*e4b17023SJohn Marino 382*e4b17023SJohn Marino void 383*e4b17023SJohn Marino register_one_dump_file (struct opt_pass *pass) 384*e4b17023SJohn Marino { 385*e4b17023SJohn Marino char *dot_name, *flag_name, *glob_name; 386*e4b17023SJohn Marino const char *name, *full_name, *prefix; 387*e4b17023SJohn Marino char num[10]; 388*e4b17023SJohn Marino int flags, id; 389*e4b17023SJohn Marino 390*e4b17023SJohn Marino /* See below in next_pass_1. */ 391*e4b17023SJohn Marino num[0] = '\0'; 392*e4b17023SJohn Marino if (pass->static_pass_number != -1) 393*e4b17023SJohn Marino sprintf (num, "%d", ((int) pass->static_pass_number < 0 394*e4b17023SJohn Marino ? 1 : pass->static_pass_number)); 395*e4b17023SJohn Marino 396*e4b17023SJohn Marino /* The name is both used to identify the pass for the purposes of plugins, 397*e4b17023SJohn Marino and to specify dump file name and option. 398*e4b17023SJohn Marino The latter two might want something short which is not quite unique; for 399*e4b17023SJohn Marino that reason, we may have a disambiguating prefix, followed by a space 400*e4b17023SJohn Marino to mark the start of the following dump file name / option string. */ 401*e4b17023SJohn Marino name = strchr (pass->name, ' '); 402*e4b17023SJohn Marino name = name ? name + 1 : pass->name; 403*e4b17023SJohn Marino dot_name = concat (".", name, num, NULL); 404*e4b17023SJohn Marino if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS) 405*e4b17023SJohn Marino prefix = "ipa-", flags = TDF_IPA; 406*e4b17023SJohn Marino else if (pass->type == GIMPLE_PASS) 407*e4b17023SJohn Marino prefix = "tree-", flags = TDF_TREE; 408*e4b17023SJohn Marino else 409*e4b17023SJohn Marino prefix = "rtl-", flags = TDF_RTL; 410*e4b17023SJohn Marino 411*e4b17023SJohn Marino flag_name = concat (prefix, name, num, NULL); 412*e4b17023SJohn Marino glob_name = concat (prefix, name, NULL); 413*e4b17023SJohn Marino id = dump_register (dot_name, flag_name, glob_name, flags); 414*e4b17023SJohn Marino set_pass_for_id (id, pass); 415*e4b17023SJohn Marino full_name = concat (prefix, pass->name, num, NULL); 416*e4b17023SJohn Marino register_pass_name (pass, full_name); 417*e4b17023SJohn Marino free (CONST_CAST (char *, full_name)); 418*e4b17023SJohn Marino } 419*e4b17023SJohn Marino 420*e4b17023SJohn Marino /* Recursive worker function for register_dump_files. */ 421*e4b17023SJohn Marino 422*e4b17023SJohn Marino static int 423*e4b17023SJohn Marino register_dump_files_1 (struct opt_pass *pass, int properties) 424*e4b17023SJohn Marino { 425*e4b17023SJohn Marino do 426*e4b17023SJohn Marino { 427*e4b17023SJohn Marino int new_properties = (properties | pass->properties_provided) 428*e4b17023SJohn Marino & ~pass->properties_destroyed; 429*e4b17023SJohn Marino 430*e4b17023SJohn Marino if (pass->name && pass->name[0] != '*') 431*e4b17023SJohn Marino register_one_dump_file (pass); 432*e4b17023SJohn Marino 433*e4b17023SJohn Marino if (pass->sub) 434*e4b17023SJohn Marino new_properties = register_dump_files_1 (pass->sub, new_properties); 435*e4b17023SJohn Marino 436*e4b17023SJohn Marino /* If we have a gate, combine the properties that we could have with 437*e4b17023SJohn Marino and without the pass being examined. */ 438*e4b17023SJohn Marino if (pass->gate) 439*e4b17023SJohn Marino properties &= new_properties; 440*e4b17023SJohn Marino else 441*e4b17023SJohn Marino properties = new_properties; 442*e4b17023SJohn Marino 443*e4b17023SJohn Marino pass = pass->next; 444*e4b17023SJohn Marino } 445*e4b17023SJohn Marino while (pass); 446*e4b17023SJohn Marino 447*e4b17023SJohn Marino return properties; 448*e4b17023SJohn Marino } 449*e4b17023SJohn Marino 450*e4b17023SJohn Marino /* Register the dump files for the pipeline starting at PASS. 451*e4b17023SJohn Marino PROPERTIES reflects the properties that are guaranteed to be available at 452*e4b17023SJohn Marino the beginning of the pipeline. */ 453*e4b17023SJohn Marino 454*e4b17023SJohn Marino static void 455*e4b17023SJohn Marino register_dump_files (struct opt_pass *pass,int properties) 456*e4b17023SJohn Marino { 457*e4b17023SJohn Marino pass->properties_required |= properties; 458*e4b17023SJohn Marino register_dump_files_1 (pass, properties); 459*e4b17023SJohn Marino } 460*e4b17023SJohn Marino 461*e4b17023SJohn Marino struct pass_registry 462*e4b17023SJohn Marino { 463*e4b17023SJohn Marino const char* unique_name; 464*e4b17023SJohn Marino struct opt_pass *pass; 465*e4b17023SJohn Marino }; 466*e4b17023SJohn Marino 467*e4b17023SJohn Marino /* Pass registry hash function. */ 468*e4b17023SJohn Marino 469*e4b17023SJohn Marino static hashval_t 470*e4b17023SJohn Marino passr_hash (const void *p) 471*e4b17023SJohn Marino { 472*e4b17023SJohn Marino const struct pass_registry *const s = (const struct pass_registry *const) p; 473*e4b17023SJohn Marino return htab_hash_string (s->unique_name); 474*e4b17023SJohn Marino } 475*e4b17023SJohn Marino 476*e4b17023SJohn Marino /* Hash equal function */ 477*e4b17023SJohn Marino 478*e4b17023SJohn Marino static int 479*e4b17023SJohn Marino passr_eq (const void *p1, const void *p2) 480*e4b17023SJohn Marino { 481*e4b17023SJohn Marino const struct pass_registry *const s1 = (const struct pass_registry *const) p1; 482*e4b17023SJohn Marino const struct pass_registry *const s2 = (const struct pass_registry *const) p2; 483*e4b17023SJohn Marino 484*e4b17023SJohn Marino return !strcmp (s1->unique_name, s2->unique_name); 485*e4b17023SJohn Marino } 486*e4b17023SJohn Marino 487*e4b17023SJohn Marino static htab_t name_to_pass_map = NULL; 488*e4b17023SJohn Marino 489*e4b17023SJohn Marino /* Register PASS with NAME. */ 490*e4b17023SJohn Marino 491*e4b17023SJohn Marino static void 492*e4b17023SJohn Marino register_pass_name (struct opt_pass *pass, const char *name) 493*e4b17023SJohn Marino { 494*e4b17023SJohn Marino struct pass_registry **slot; 495*e4b17023SJohn Marino struct pass_registry pr; 496*e4b17023SJohn Marino 497*e4b17023SJohn Marino if (!name_to_pass_map) 498*e4b17023SJohn Marino name_to_pass_map = htab_create (256, passr_hash, passr_eq, NULL); 499*e4b17023SJohn Marino 500*e4b17023SJohn Marino pr.unique_name = name; 501*e4b17023SJohn Marino slot = (struct pass_registry **) htab_find_slot (name_to_pass_map, &pr, INSERT); 502*e4b17023SJohn Marino if (!*slot) 503*e4b17023SJohn Marino { 504*e4b17023SJohn Marino struct pass_registry *new_pr; 505*e4b17023SJohn Marino 506*e4b17023SJohn Marino new_pr = XCNEW (struct pass_registry); 507*e4b17023SJohn Marino new_pr->unique_name = xstrdup (name); 508*e4b17023SJohn Marino new_pr->pass = pass; 509*e4b17023SJohn Marino *slot = new_pr; 510*e4b17023SJohn Marino } 511*e4b17023SJohn Marino else 512*e4b17023SJohn Marino return; /* Ignore plugin passes. */ 513*e4b17023SJohn Marino } 514*e4b17023SJohn Marino 515*e4b17023SJohn Marino /* Map from pass id to canonicalized pass name. */ 516*e4b17023SJohn Marino 517*e4b17023SJohn Marino typedef const char *char_ptr; 518*e4b17023SJohn Marino DEF_VEC_P(char_ptr); 519*e4b17023SJohn Marino DEF_VEC_ALLOC_P(char_ptr, heap); 520*e4b17023SJohn Marino static VEC(char_ptr, heap) *pass_tab = NULL; 521*e4b17023SJohn Marino 522*e4b17023SJohn Marino /* Callback function for traversing NAME_TO_PASS_MAP. */ 523*e4b17023SJohn Marino 524*e4b17023SJohn Marino static int 525*e4b17023SJohn Marino pass_traverse (void **slot, void *data ATTRIBUTE_UNUSED) 526*e4b17023SJohn Marino { 527*e4b17023SJohn Marino struct pass_registry **p = (struct pass_registry **)slot; 528*e4b17023SJohn Marino struct opt_pass *pass = (*p)->pass; 529*e4b17023SJohn Marino 530*e4b17023SJohn Marino gcc_assert (pass->static_pass_number > 0); 531*e4b17023SJohn Marino gcc_assert (pass_tab); 532*e4b17023SJohn Marino 533*e4b17023SJohn Marino VEC_replace (char_ptr, pass_tab, pass->static_pass_number, 534*e4b17023SJohn Marino (*p)->unique_name); 535*e4b17023SJohn Marino 536*e4b17023SJohn Marino return 1; 537*e4b17023SJohn Marino } 538*e4b17023SJohn Marino 539*e4b17023SJohn Marino /* The function traverses NAME_TO_PASS_MAP and creates a pass info 540*e4b17023SJohn Marino table for dumping purpose. */ 541*e4b17023SJohn Marino 542*e4b17023SJohn Marino static void 543*e4b17023SJohn Marino create_pass_tab (void) 544*e4b17023SJohn Marino { 545*e4b17023SJohn Marino if (!flag_dump_passes) 546*e4b17023SJohn Marino return; 547*e4b17023SJohn Marino 548*e4b17023SJohn Marino VEC_safe_grow_cleared (char_ptr, heap, 549*e4b17023SJohn Marino pass_tab, passes_by_id_size + 1); 550*e4b17023SJohn Marino htab_traverse (name_to_pass_map, pass_traverse, NULL); 551*e4b17023SJohn Marino } 552*e4b17023SJohn Marino 553*e4b17023SJohn Marino static bool override_gate_status (struct opt_pass *, tree, bool); 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino /* Dump the instantiated name for PASS. IS_ON indicates if PASS 556*e4b17023SJohn Marino is turned on or not. */ 557*e4b17023SJohn Marino 558*e4b17023SJohn Marino static void 559*e4b17023SJohn Marino dump_one_pass (struct opt_pass *pass, int pass_indent) 560*e4b17023SJohn Marino { 561*e4b17023SJohn Marino int indent = 3 * pass_indent; 562*e4b17023SJohn Marino const char *pn; 563*e4b17023SJohn Marino bool is_on, is_really_on; 564*e4b17023SJohn Marino 565*e4b17023SJohn Marino is_on = (pass->gate == NULL) ? true : pass->gate(); 566*e4b17023SJohn Marino is_really_on = override_gate_status (pass, current_function_decl, is_on); 567*e4b17023SJohn Marino 568*e4b17023SJohn Marino if (pass->static_pass_number <= 0) 569*e4b17023SJohn Marino pn = pass->name; 570*e4b17023SJohn Marino else 571*e4b17023SJohn Marino pn = VEC_index (char_ptr, pass_tab, pass->static_pass_number); 572*e4b17023SJohn Marino 573*e4b17023SJohn Marino fprintf (stderr, "%*s%-40s%*s:%s%s\n", indent, " ", pn, 574*e4b17023SJohn Marino (15 - indent < 0 ? 0 : 15 - indent), " ", 575*e4b17023SJohn Marino is_on ? " ON" : " OFF", 576*e4b17023SJohn Marino ((!is_on) == (!is_really_on) ? "" 577*e4b17023SJohn Marino : (is_really_on ? " (FORCED_ON)" : " (FORCED_OFF)"))); 578*e4b17023SJohn Marino } 579*e4b17023SJohn Marino 580*e4b17023SJohn Marino /* Dump pass list PASS with indentation INDENT. */ 581*e4b17023SJohn Marino 582*e4b17023SJohn Marino static void 583*e4b17023SJohn Marino dump_pass_list (struct opt_pass *pass, int indent) 584*e4b17023SJohn Marino { 585*e4b17023SJohn Marino do 586*e4b17023SJohn Marino { 587*e4b17023SJohn Marino dump_one_pass (pass, indent); 588*e4b17023SJohn Marino if (pass->sub) 589*e4b17023SJohn Marino dump_pass_list (pass->sub, indent + 1); 590*e4b17023SJohn Marino pass = pass->next; 591*e4b17023SJohn Marino } 592*e4b17023SJohn Marino while (pass); 593*e4b17023SJohn Marino } 594*e4b17023SJohn Marino 595*e4b17023SJohn Marino /* Dump all optimization passes. */ 596*e4b17023SJohn Marino 597*e4b17023SJohn Marino void 598*e4b17023SJohn Marino dump_passes (void) 599*e4b17023SJohn Marino { 600*e4b17023SJohn Marino struct cgraph_node *n, *node = NULL; 601*e4b17023SJohn Marino tree save_fndecl = current_function_decl; 602*e4b17023SJohn Marino 603*e4b17023SJohn Marino create_pass_tab(); 604*e4b17023SJohn Marino 605*e4b17023SJohn Marino n = cgraph_nodes; 606*e4b17023SJohn Marino while (n) 607*e4b17023SJohn Marino { 608*e4b17023SJohn Marino if (DECL_STRUCT_FUNCTION (n->decl)) 609*e4b17023SJohn Marino { 610*e4b17023SJohn Marino node = n; 611*e4b17023SJohn Marino break; 612*e4b17023SJohn Marino } 613*e4b17023SJohn Marino n = n->next; 614*e4b17023SJohn Marino } 615*e4b17023SJohn Marino 616*e4b17023SJohn Marino if (!node) 617*e4b17023SJohn Marino return; 618*e4b17023SJohn Marino 619*e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 620*e4b17023SJohn Marino current_function_decl = node->decl; 621*e4b17023SJohn Marino 622*e4b17023SJohn Marino dump_pass_list (all_lowering_passes, 1); 623*e4b17023SJohn Marino dump_pass_list (all_small_ipa_passes, 1); 624*e4b17023SJohn Marino dump_pass_list (all_regular_ipa_passes, 1); 625*e4b17023SJohn Marino dump_pass_list (all_lto_gen_passes, 1); 626*e4b17023SJohn Marino dump_pass_list (all_late_ipa_passes, 1); 627*e4b17023SJohn Marino dump_pass_list (all_passes, 1); 628*e4b17023SJohn Marino 629*e4b17023SJohn Marino pop_cfun (); 630*e4b17023SJohn Marino current_function_decl = save_fndecl; 631*e4b17023SJohn Marino } 632*e4b17023SJohn Marino 633*e4b17023SJohn Marino 634*e4b17023SJohn Marino /* Returns the pass with NAME. */ 635*e4b17023SJohn Marino 636*e4b17023SJohn Marino static struct opt_pass * 637*e4b17023SJohn Marino get_pass_by_name (const char *name) 638*e4b17023SJohn Marino { 639*e4b17023SJohn Marino struct pass_registry **slot, pr; 640*e4b17023SJohn Marino 641*e4b17023SJohn Marino pr.unique_name = name; 642*e4b17023SJohn Marino slot = (struct pass_registry **) htab_find_slot (name_to_pass_map, 643*e4b17023SJohn Marino &pr, NO_INSERT); 644*e4b17023SJohn Marino 645*e4b17023SJohn Marino if (!slot || !*slot) 646*e4b17023SJohn Marino return NULL; 647*e4b17023SJohn Marino 648*e4b17023SJohn Marino return (*slot)->pass; 649*e4b17023SJohn Marino } 650*e4b17023SJohn Marino 651*e4b17023SJohn Marino 652*e4b17023SJohn Marino /* Range [start, last]. */ 653*e4b17023SJohn Marino 654*e4b17023SJohn Marino struct uid_range 655*e4b17023SJohn Marino { 656*e4b17023SJohn Marino unsigned int start; 657*e4b17023SJohn Marino unsigned int last; 658*e4b17023SJohn Marino const char *assem_name; 659*e4b17023SJohn Marino struct uid_range *next; 660*e4b17023SJohn Marino }; 661*e4b17023SJohn Marino 662*e4b17023SJohn Marino typedef struct uid_range *uid_range_p; 663*e4b17023SJohn Marino 664*e4b17023SJohn Marino DEF_VEC_P(uid_range_p); 665*e4b17023SJohn Marino DEF_VEC_ALLOC_P(uid_range_p, heap); 666*e4b17023SJohn Marino 667*e4b17023SJohn Marino static VEC(uid_range_p, heap) *enabled_pass_uid_range_tab = NULL; 668*e4b17023SJohn Marino static VEC(uid_range_p, heap) *disabled_pass_uid_range_tab = NULL; 669*e4b17023SJohn Marino 670*e4b17023SJohn Marino 671*e4b17023SJohn Marino /* Parse option string for -fdisable- and -fenable- 672*e4b17023SJohn Marino The syntax of the options: 673*e4b17023SJohn Marino 674*e4b17023SJohn Marino -fenable-<pass_name> 675*e4b17023SJohn Marino -fdisable-<pass_name> 676*e4b17023SJohn Marino 677*e4b17023SJohn Marino -fenable-<pass_name>=s1:e1,s2:e2,... 678*e4b17023SJohn Marino -fdisable-<pass_name>=s1:e1,s2:e2,... 679*e4b17023SJohn Marino */ 680*e4b17023SJohn Marino 681*e4b17023SJohn Marino static void 682*e4b17023SJohn Marino enable_disable_pass (const char *arg, bool is_enable) 683*e4b17023SJohn Marino { 684*e4b17023SJohn Marino struct opt_pass *pass; 685*e4b17023SJohn Marino char *range_str, *phase_name; 686*e4b17023SJohn Marino char *argstr = xstrdup (arg); 687*e4b17023SJohn Marino VEC(uid_range_p, heap) **tab = 0; 688*e4b17023SJohn Marino 689*e4b17023SJohn Marino range_str = strchr (argstr,'='); 690*e4b17023SJohn Marino if (range_str) 691*e4b17023SJohn Marino { 692*e4b17023SJohn Marino *range_str = '\0'; 693*e4b17023SJohn Marino range_str++; 694*e4b17023SJohn Marino } 695*e4b17023SJohn Marino 696*e4b17023SJohn Marino phase_name = argstr; 697*e4b17023SJohn Marino if (!*phase_name) 698*e4b17023SJohn Marino { 699*e4b17023SJohn Marino if (is_enable) 700*e4b17023SJohn Marino error ("unrecognized option -fenable"); 701*e4b17023SJohn Marino else 702*e4b17023SJohn Marino error ("unrecognized option -fdisable"); 703*e4b17023SJohn Marino free (argstr); 704*e4b17023SJohn Marino return; 705*e4b17023SJohn Marino } 706*e4b17023SJohn Marino pass = get_pass_by_name (phase_name); 707*e4b17023SJohn Marino if (!pass || pass->static_pass_number == -1) 708*e4b17023SJohn Marino { 709*e4b17023SJohn Marino if (is_enable) 710*e4b17023SJohn Marino error ("unknown pass %s specified in -fenable", phase_name); 711*e4b17023SJohn Marino else 712*e4b17023SJohn Marino error ("unknown pass %s specified in -fdisable", phase_name); 713*e4b17023SJohn Marino free (argstr); 714*e4b17023SJohn Marino return; 715*e4b17023SJohn Marino } 716*e4b17023SJohn Marino 717*e4b17023SJohn Marino if (is_enable) 718*e4b17023SJohn Marino tab = &enabled_pass_uid_range_tab; 719*e4b17023SJohn Marino else 720*e4b17023SJohn Marino tab = &disabled_pass_uid_range_tab; 721*e4b17023SJohn Marino 722*e4b17023SJohn Marino if ((unsigned) pass->static_pass_number >= VEC_length (uid_range_p, *tab)) 723*e4b17023SJohn Marino VEC_safe_grow_cleared (uid_range_p, heap, 724*e4b17023SJohn Marino *tab, pass->static_pass_number + 1); 725*e4b17023SJohn Marino 726*e4b17023SJohn Marino if (!range_str) 727*e4b17023SJohn Marino { 728*e4b17023SJohn Marino uid_range_p slot; 729*e4b17023SJohn Marino uid_range_p new_range = XCNEW (struct uid_range); 730*e4b17023SJohn Marino 731*e4b17023SJohn Marino new_range->start = 0; 732*e4b17023SJohn Marino new_range->last = (unsigned)-1; 733*e4b17023SJohn Marino 734*e4b17023SJohn Marino slot = VEC_index (uid_range_p, *tab, pass->static_pass_number); 735*e4b17023SJohn Marino new_range->next = slot; 736*e4b17023SJohn Marino VEC_replace (uid_range_p, *tab, pass->static_pass_number, 737*e4b17023SJohn Marino new_range); 738*e4b17023SJohn Marino if (is_enable) 739*e4b17023SJohn Marino inform (UNKNOWN_LOCATION, "enable pass %s for functions in the range " 740*e4b17023SJohn Marino "of [%u, %u]", phase_name, new_range->start, new_range->last); 741*e4b17023SJohn Marino else 742*e4b17023SJohn Marino inform (UNKNOWN_LOCATION, "disable pass %s for functions in the range " 743*e4b17023SJohn Marino "of [%u, %u]", phase_name, new_range->start, new_range->last); 744*e4b17023SJohn Marino } 745*e4b17023SJohn Marino else 746*e4b17023SJohn Marino { 747*e4b17023SJohn Marino char *next_range = NULL; 748*e4b17023SJohn Marino char *one_range = range_str; 749*e4b17023SJohn Marino char *end_val = NULL; 750*e4b17023SJohn Marino 751*e4b17023SJohn Marino do 752*e4b17023SJohn Marino { 753*e4b17023SJohn Marino uid_range_p slot; 754*e4b17023SJohn Marino uid_range_p new_range; 755*e4b17023SJohn Marino char *invalid = NULL; 756*e4b17023SJohn Marino long start; 757*e4b17023SJohn Marino char *func_name = NULL; 758*e4b17023SJohn Marino 759*e4b17023SJohn Marino next_range = strchr (one_range, ','); 760*e4b17023SJohn Marino if (next_range) 761*e4b17023SJohn Marino { 762*e4b17023SJohn Marino *next_range = '\0'; 763*e4b17023SJohn Marino next_range++; 764*e4b17023SJohn Marino } 765*e4b17023SJohn Marino 766*e4b17023SJohn Marino end_val = strchr (one_range, ':'); 767*e4b17023SJohn Marino if (end_val) 768*e4b17023SJohn Marino { 769*e4b17023SJohn Marino *end_val = '\0'; 770*e4b17023SJohn Marino end_val++; 771*e4b17023SJohn Marino } 772*e4b17023SJohn Marino start = strtol (one_range, &invalid, 10); 773*e4b17023SJohn Marino if (*invalid || start < 0) 774*e4b17023SJohn Marino { 775*e4b17023SJohn Marino if (end_val || (one_range[0] >= '0' 776*e4b17023SJohn Marino && one_range[0] <= '9')) 777*e4b17023SJohn Marino { 778*e4b17023SJohn Marino error ("Invalid range %s in option %s", 779*e4b17023SJohn Marino one_range, 780*e4b17023SJohn Marino is_enable ? "-fenable" : "-fdisable"); 781*e4b17023SJohn Marino free (argstr); 782*e4b17023SJohn Marino return; 783*e4b17023SJohn Marino } 784*e4b17023SJohn Marino func_name = one_range; 785*e4b17023SJohn Marino } 786*e4b17023SJohn Marino if (!end_val) 787*e4b17023SJohn Marino { 788*e4b17023SJohn Marino new_range = XCNEW (struct uid_range); 789*e4b17023SJohn Marino if (!func_name) 790*e4b17023SJohn Marino { 791*e4b17023SJohn Marino new_range->start = (unsigned) start; 792*e4b17023SJohn Marino new_range->last = (unsigned) start; 793*e4b17023SJohn Marino } 794*e4b17023SJohn Marino else 795*e4b17023SJohn Marino { 796*e4b17023SJohn Marino new_range->start = (unsigned) -1; 797*e4b17023SJohn Marino new_range->last = (unsigned) -1; 798*e4b17023SJohn Marino new_range->assem_name = xstrdup (func_name); 799*e4b17023SJohn Marino } 800*e4b17023SJohn Marino } 801*e4b17023SJohn Marino else 802*e4b17023SJohn Marino { 803*e4b17023SJohn Marino long last = strtol (end_val, &invalid, 10); 804*e4b17023SJohn Marino if (*invalid || last < start) 805*e4b17023SJohn Marino { 806*e4b17023SJohn Marino error ("Invalid range %s in option %s", 807*e4b17023SJohn Marino end_val, 808*e4b17023SJohn Marino is_enable ? "-fenable" : "-fdisable"); 809*e4b17023SJohn Marino free (argstr); 810*e4b17023SJohn Marino return; 811*e4b17023SJohn Marino } 812*e4b17023SJohn Marino new_range = XCNEW (struct uid_range); 813*e4b17023SJohn Marino new_range->start = (unsigned) start; 814*e4b17023SJohn Marino new_range->last = (unsigned) last; 815*e4b17023SJohn Marino } 816*e4b17023SJohn Marino 817*e4b17023SJohn Marino slot = VEC_index (uid_range_p, *tab, pass->static_pass_number); 818*e4b17023SJohn Marino new_range->next = slot; 819*e4b17023SJohn Marino VEC_replace (uid_range_p, *tab, pass->static_pass_number, 820*e4b17023SJohn Marino new_range); 821*e4b17023SJohn Marino if (is_enable) 822*e4b17023SJohn Marino { 823*e4b17023SJohn Marino if (new_range->assem_name) 824*e4b17023SJohn Marino inform (UNKNOWN_LOCATION, 825*e4b17023SJohn Marino "enable pass %s for function %s", 826*e4b17023SJohn Marino phase_name, new_range->assem_name); 827*e4b17023SJohn Marino else 828*e4b17023SJohn Marino inform (UNKNOWN_LOCATION, 829*e4b17023SJohn Marino "enable pass %s for functions in the range of [%u, %u]", 830*e4b17023SJohn Marino phase_name, new_range->start, new_range->last); 831*e4b17023SJohn Marino } 832*e4b17023SJohn Marino else 833*e4b17023SJohn Marino { 834*e4b17023SJohn Marino if (new_range->assem_name) 835*e4b17023SJohn Marino inform (UNKNOWN_LOCATION, 836*e4b17023SJohn Marino "disable pass %s for function %s", 837*e4b17023SJohn Marino phase_name, new_range->assem_name); 838*e4b17023SJohn Marino else 839*e4b17023SJohn Marino inform (UNKNOWN_LOCATION, 840*e4b17023SJohn Marino "disable pass %s for functions in the range of [%u, %u]", 841*e4b17023SJohn Marino phase_name, new_range->start, new_range->last); 842*e4b17023SJohn Marino } 843*e4b17023SJohn Marino 844*e4b17023SJohn Marino one_range = next_range; 845*e4b17023SJohn Marino } while (next_range); 846*e4b17023SJohn Marino } 847*e4b17023SJohn Marino 848*e4b17023SJohn Marino free (argstr); 849*e4b17023SJohn Marino } 850*e4b17023SJohn Marino 851*e4b17023SJohn Marino /* Enable pass specified by ARG. */ 852*e4b17023SJohn Marino 853*e4b17023SJohn Marino void 854*e4b17023SJohn Marino enable_pass (const char *arg) 855*e4b17023SJohn Marino { 856*e4b17023SJohn Marino enable_disable_pass (arg, true); 857*e4b17023SJohn Marino } 858*e4b17023SJohn Marino 859*e4b17023SJohn Marino /* Disable pass specified by ARG. */ 860*e4b17023SJohn Marino 861*e4b17023SJohn Marino void 862*e4b17023SJohn Marino disable_pass (const char *arg) 863*e4b17023SJohn Marino { 864*e4b17023SJohn Marino enable_disable_pass (arg, false); 865*e4b17023SJohn Marino } 866*e4b17023SJohn Marino 867*e4b17023SJohn Marino /* Returns true if PASS is explicitly enabled/disabled for FUNC. */ 868*e4b17023SJohn Marino 869*e4b17023SJohn Marino static bool 870*e4b17023SJohn Marino is_pass_explicitly_enabled_or_disabled (struct opt_pass *pass, 871*e4b17023SJohn Marino tree func, 872*e4b17023SJohn Marino VEC(uid_range_p, heap) *tab) 873*e4b17023SJohn Marino { 874*e4b17023SJohn Marino uid_range_p slot, range; 875*e4b17023SJohn Marino int cgraph_uid; 876*e4b17023SJohn Marino const char *aname = NULL; 877*e4b17023SJohn Marino 878*e4b17023SJohn Marino if (!tab 879*e4b17023SJohn Marino || (unsigned) pass->static_pass_number >= VEC_length (uid_range_p, tab) 880*e4b17023SJohn Marino || pass->static_pass_number == -1) 881*e4b17023SJohn Marino return false; 882*e4b17023SJohn Marino 883*e4b17023SJohn Marino slot = VEC_index (uid_range_p, tab, pass->static_pass_number); 884*e4b17023SJohn Marino if (!slot) 885*e4b17023SJohn Marino return false; 886*e4b17023SJohn Marino 887*e4b17023SJohn Marino cgraph_uid = func ? cgraph_get_node (func)->uid : 0; 888*e4b17023SJohn Marino if (func && DECL_ASSEMBLER_NAME_SET_P (func)) 889*e4b17023SJohn Marino aname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func)); 890*e4b17023SJohn Marino 891*e4b17023SJohn Marino range = slot; 892*e4b17023SJohn Marino while (range) 893*e4b17023SJohn Marino { 894*e4b17023SJohn Marino if ((unsigned) cgraph_uid >= range->start 895*e4b17023SJohn Marino && (unsigned) cgraph_uid <= range->last) 896*e4b17023SJohn Marino return true; 897*e4b17023SJohn Marino if (range->assem_name && aname 898*e4b17023SJohn Marino && !strcmp (range->assem_name, aname)) 899*e4b17023SJohn Marino return true; 900*e4b17023SJohn Marino range = range->next; 901*e4b17023SJohn Marino } 902*e4b17023SJohn Marino 903*e4b17023SJohn Marino return false; 904*e4b17023SJohn Marino } 905*e4b17023SJohn Marino 906*e4b17023SJohn Marino /* Look at the static_pass_number and duplicate the pass 907*e4b17023SJohn Marino if it is already added to a list. */ 908*e4b17023SJohn Marino 909*e4b17023SJohn Marino static struct opt_pass * 910*e4b17023SJohn Marino make_pass_instance (struct opt_pass *pass, bool track_duplicates) 911*e4b17023SJohn Marino { 912*e4b17023SJohn Marino /* A nonzero static_pass_number indicates that the 913*e4b17023SJohn Marino pass is already in the list. */ 914*e4b17023SJohn Marino if (pass->static_pass_number) 915*e4b17023SJohn Marino { 916*e4b17023SJohn Marino struct opt_pass *new_pass; 917*e4b17023SJohn Marino 918*e4b17023SJohn Marino if (pass->type == GIMPLE_PASS 919*e4b17023SJohn Marino || pass->type == RTL_PASS 920*e4b17023SJohn Marino || pass->type == SIMPLE_IPA_PASS) 921*e4b17023SJohn Marino { 922*e4b17023SJohn Marino new_pass = XNEW (struct opt_pass); 923*e4b17023SJohn Marino memcpy (new_pass, pass, sizeof (struct opt_pass)); 924*e4b17023SJohn Marino } 925*e4b17023SJohn Marino else if (pass->type == IPA_PASS) 926*e4b17023SJohn Marino { 927*e4b17023SJohn Marino new_pass = (struct opt_pass *)XNEW (struct ipa_opt_pass_d); 928*e4b17023SJohn Marino memcpy (new_pass, pass, sizeof (struct ipa_opt_pass_d)); 929*e4b17023SJohn Marino } 930*e4b17023SJohn Marino else 931*e4b17023SJohn Marino gcc_unreachable (); 932*e4b17023SJohn Marino 933*e4b17023SJohn Marino new_pass->next = NULL; 934*e4b17023SJohn Marino 935*e4b17023SJohn Marino new_pass->todo_flags_start &= ~TODO_mark_first_instance; 936*e4b17023SJohn Marino 937*e4b17023SJohn Marino /* Indicate to register_dump_files that this pass has duplicates, 938*e4b17023SJohn Marino and so it should rename the dump file. The first instance will 939*e4b17023SJohn Marino be -1, and be number of duplicates = -static_pass_number - 1. 940*e4b17023SJohn Marino Subsequent instances will be > 0 and just the duplicate number. */ 941*e4b17023SJohn Marino if ((pass->name && pass->name[0] != '*') || track_duplicates) 942*e4b17023SJohn Marino { 943*e4b17023SJohn Marino pass->static_pass_number -= 1; 944*e4b17023SJohn Marino new_pass->static_pass_number = -pass->static_pass_number; 945*e4b17023SJohn Marino } 946*e4b17023SJohn Marino return new_pass; 947*e4b17023SJohn Marino } 948*e4b17023SJohn Marino else 949*e4b17023SJohn Marino { 950*e4b17023SJohn Marino pass->todo_flags_start |= TODO_mark_first_instance; 951*e4b17023SJohn Marino pass->static_pass_number = -1; 952*e4b17023SJohn Marino 953*e4b17023SJohn Marino invoke_plugin_callbacks (PLUGIN_NEW_PASS, pass); 954*e4b17023SJohn Marino } 955*e4b17023SJohn Marino return pass; 956*e4b17023SJohn Marino } 957*e4b17023SJohn Marino 958*e4b17023SJohn Marino /* Add a pass to the pass list. Duplicate the pass if it's already 959*e4b17023SJohn Marino in the list. */ 960*e4b17023SJohn Marino 961*e4b17023SJohn Marino static struct opt_pass ** 962*e4b17023SJohn Marino next_pass_1 (struct opt_pass **list, struct opt_pass *pass) 963*e4b17023SJohn Marino { 964*e4b17023SJohn Marino /* Every pass should have a name so that plugins can refer to them. */ 965*e4b17023SJohn Marino gcc_assert (pass->name != NULL); 966*e4b17023SJohn Marino 967*e4b17023SJohn Marino *list = make_pass_instance (pass, false); 968*e4b17023SJohn Marino 969*e4b17023SJohn Marino return &(*list)->next; 970*e4b17023SJohn Marino } 971*e4b17023SJohn Marino 972*e4b17023SJohn Marino /* List node for an inserted pass instance. We need to keep track of all 973*e4b17023SJohn Marino the newly-added pass instances (with 'added_pass_nodes' defined below) 974*e4b17023SJohn Marino so that we can register their dump files after pass-positioning is finished. 975*e4b17023SJohn Marino Registering dumping files needs to be post-processed or the 976*e4b17023SJohn Marino static_pass_number of the opt_pass object would be modified and mess up 977*e4b17023SJohn Marino the dump file names of future pass instances to be added. */ 978*e4b17023SJohn Marino 979*e4b17023SJohn Marino struct pass_list_node 980*e4b17023SJohn Marino { 981*e4b17023SJohn Marino struct opt_pass *pass; 982*e4b17023SJohn Marino struct pass_list_node *next; 983*e4b17023SJohn Marino }; 984*e4b17023SJohn Marino 985*e4b17023SJohn Marino static struct pass_list_node *added_pass_nodes = NULL; 986*e4b17023SJohn Marino static struct pass_list_node *prev_added_pass_node; 987*e4b17023SJohn Marino 988*e4b17023SJohn Marino /* Insert the pass at the proper position. Return true if the pass 989*e4b17023SJohn Marino is successfully added. 990*e4b17023SJohn Marino 991*e4b17023SJohn Marino NEW_PASS_INFO - new pass to be inserted 992*e4b17023SJohn Marino PASS_LIST - root of the pass list to insert the new pass to */ 993*e4b17023SJohn Marino 994*e4b17023SJohn Marino static bool 995*e4b17023SJohn Marino position_pass (struct register_pass_info *new_pass_info, 996*e4b17023SJohn Marino struct opt_pass **pass_list) 997*e4b17023SJohn Marino { 998*e4b17023SJohn Marino struct opt_pass *pass = *pass_list, *prev_pass = NULL; 999*e4b17023SJohn Marino bool success = false; 1000*e4b17023SJohn Marino 1001*e4b17023SJohn Marino for ( ; pass; prev_pass = pass, pass = pass->next) 1002*e4b17023SJohn Marino { 1003*e4b17023SJohn Marino /* Check if the current pass is of the same type as the new pass and 1004*e4b17023SJohn Marino matches the name and the instance number of the reference pass. */ 1005*e4b17023SJohn Marino if (pass->type == new_pass_info->pass->type 1006*e4b17023SJohn Marino && pass->name 1007*e4b17023SJohn Marino && !strcmp (pass->name, new_pass_info->reference_pass_name) 1008*e4b17023SJohn Marino && ((new_pass_info->ref_pass_instance_number == 0) 1009*e4b17023SJohn Marino || (new_pass_info->ref_pass_instance_number == 1010*e4b17023SJohn Marino pass->static_pass_number) 1011*e4b17023SJohn Marino || (new_pass_info->ref_pass_instance_number == 1 1012*e4b17023SJohn Marino && pass->todo_flags_start & TODO_mark_first_instance))) 1013*e4b17023SJohn Marino { 1014*e4b17023SJohn Marino struct opt_pass *new_pass; 1015*e4b17023SJohn Marino struct pass_list_node *new_pass_node; 1016*e4b17023SJohn Marino 1017*e4b17023SJohn Marino new_pass = make_pass_instance (new_pass_info->pass, true); 1018*e4b17023SJohn Marino 1019*e4b17023SJohn Marino /* Insert the new pass instance based on the positioning op. */ 1020*e4b17023SJohn Marino switch (new_pass_info->pos_op) 1021*e4b17023SJohn Marino { 1022*e4b17023SJohn Marino case PASS_POS_INSERT_AFTER: 1023*e4b17023SJohn Marino new_pass->next = pass->next; 1024*e4b17023SJohn Marino pass->next = new_pass; 1025*e4b17023SJohn Marino 1026*e4b17023SJohn Marino /* Skip newly inserted pass to avoid repeated 1027*e4b17023SJohn Marino insertions in the case where the new pass and the 1028*e4b17023SJohn Marino existing one have the same name. */ 1029*e4b17023SJohn Marino pass = new_pass; 1030*e4b17023SJohn Marino break; 1031*e4b17023SJohn Marino case PASS_POS_INSERT_BEFORE: 1032*e4b17023SJohn Marino new_pass->next = pass; 1033*e4b17023SJohn Marino if (prev_pass) 1034*e4b17023SJohn Marino prev_pass->next = new_pass; 1035*e4b17023SJohn Marino else 1036*e4b17023SJohn Marino *pass_list = new_pass; 1037*e4b17023SJohn Marino break; 1038*e4b17023SJohn Marino case PASS_POS_REPLACE: 1039*e4b17023SJohn Marino new_pass->next = pass->next; 1040*e4b17023SJohn Marino if (prev_pass) 1041*e4b17023SJohn Marino prev_pass->next = new_pass; 1042*e4b17023SJohn Marino else 1043*e4b17023SJohn Marino *pass_list = new_pass; 1044*e4b17023SJohn Marino new_pass->sub = pass->sub; 1045*e4b17023SJohn Marino new_pass->tv_id = pass->tv_id; 1046*e4b17023SJohn Marino pass = new_pass; 1047*e4b17023SJohn Marino break; 1048*e4b17023SJohn Marino default: 1049*e4b17023SJohn Marino error ("invalid pass positioning operation"); 1050*e4b17023SJohn Marino return false; 1051*e4b17023SJohn Marino } 1052*e4b17023SJohn Marino 1053*e4b17023SJohn Marino /* Save the newly added pass (instance) in the added_pass_nodes 1054*e4b17023SJohn Marino list so that we can register its dump file later. Note that 1055*e4b17023SJohn Marino we cannot register the dump file now because doing so will modify 1056*e4b17023SJohn Marino the static_pass_number of the opt_pass object and therefore 1057*e4b17023SJohn Marino mess up the dump file name of future instances. */ 1058*e4b17023SJohn Marino new_pass_node = XCNEW (struct pass_list_node); 1059*e4b17023SJohn Marino new_pass_node->pass = new_pass; 1060*e4b17023SJohn Marino if (!added_pass_nodes) 1061*e4b17023SJohn Marino added_pass_nodes = new_pass_node; 1062*e4b17023SJohn Marino else 1063*e4b17023SJohn Marino prev_added_pass_node->next = new_pass_node; 1064*e4b17023SJohn Marino prev_added_pass_node = new_pass_node; 1065*e4b17023SJohn Marino 1066*e4b17023SJohn Marino success = true; 1067*e4b17023SJohn Marino } 1068*e4b17023SJohn Marino 1069*e4b17023SJohn Marino if (pass->sub && position_pass (new_pass_info, &pass->sub)) 1070*e4b17023SJohn Marino success = true; 1071*e4b17023SJohn Marino } 1072*e4b17023SJohn Marino 1073*e4b17023SJohn Marino return success; 1074*e4b17023SJohn Marino } 1075*e4b17023SJohn Marino 1076*e4b17023SJohn Marino /* Hooks a new pass into the pass lists. 1077*e4b17023SJohn Marino 1078*e4b17023SJohn Marino PASS_INFO - pass information that specifies the opt_pass object, 1079*e4b17023SJohn Marino reference pass, instance number, and how to position 1080*e4b17023SJohn Marino the pass */ 1081*e4b17023SJohn Marino 1082*e4b17023SJohn Marino void 1083*e4b17023SJohn Marino register_pass (struct register_pass_info *pass_info) 1084*e4b17023SJohn Marino { 1085*e4b17023SJohn Marino bool all_instances, success; 1086*e4b17023SJohn Marino 1087*e4b17023SJohn Marino /* The checks below could fail in buggy plugins. Existing GCC 1088*e4b17023SJohn Marino passes should never fail these checks, so we mention plugin in 1089*e4b17023SJohn Marino the messages. */ 1090*e4b17023SJohn Marino if (!pass_info->pass) 1091*e4b17023SJohn Marino fatal_error ("plugin cannot register a missing pass"); 1092*e4b17023SJohn Marino 1093*e4b17023SJohn Marino if (!pass_info->pass->name) 1094*e4b17023SJohn Marino fatal_error ("plugin cannot register an unnamed pass"); 1095*e4b17023SJohn Marino 1096*e4b17023SJohn Marino if (!pass_info->reference_pass_name) 1097*e4b17023SJohn Marino fatal_error 1098*e4b17023SJohn Marino ("plugin cannot register pass %qs without reference pass name", 1099*e4b17023SJohn Marino pass_info->pass->name); 1100*e4b17023SJohn Marino 1101*e4b17023SJohn Marino /* Try to insert the new pass to the pass lists. We need to check 1102*e4b17023SJohn Marino all five lists as the reference pass could be in one (or all) of 1103*e4b17023SJohn Marino them. */ 1104*e4b17023SJohn Marino all_instances = pass_info->ref_pass_instance_number == 0; 1105*e4b17023SJohn Marino success = position_pass (pass_info, &all_lowering_passes); 1106*e4b17023SJohn Marino if (!success || all_instances) 1107*e4b17023SJohn Marino success |= position_pass (pass_info, &all_small_ipa_passes); 1108*e4b17023SJohn Marino if (!success || all_instances) 1109*e4b17023SJohn Marino success |= position_pass (pass_info, &all_regular_ipa_passes); 1110*e4b17023SJohn Marino if (!success || all_instances) 1111*e4b17023SJohn Marino success |= position_pass (pass_info, &all_lto_gen_passes); 1112*e4b17023SJohn Marino if (!success || all_instances) 1113*e4b17023SJohn Marino success |= position_pass (pass_info, &all_late_ipa_passes); 1114*e4b17023SJohn Marino if (!success || all_instances) 1115*e4b17023SJohn Marino success |= position_pass (pass_info, &all_passes); 1116*e4b17023SJohn Marino if (!success) 1117*e4b17023SJohn Marino fatal_error 1118*e4b17023SJohn Marino ("pass %qs not found but is referenced by new pass %qs", 1119*e4b17023SJohn Marino pass_info->reference_pass_name, pass_info->pass->name); 1120*e4b17023SJohn Marino 1121*e4b17023SJohn Marino /* OK, we have successfully inserted the new pass. We need to register 1122*e4b17023SJohn Marino the dump files for the newly added pass and its duplicates (if any). 1123*e4b17023SJohn Marino Because the registration of plugin/backend passes happens after the 1124*e4b17023SJohn Marino command-line options are parsed, the options that specify single 1125*e4b17023SJohn Marino pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new 1126*e4b17023SJohn Marino passes. Therefore we currently can only enable dumping of 1127*e4b17023SJohn Marino new passes when the 'dump-all' flags (e.g. -fdump-tree-all) 1128*e4b17023SJohn Marino are specified. While doing so, we also delete the pass_list_node 1129*e4b17023SJohn Marino objects created during pass positioning. */ 1130*e4b17023SJohn Marino while (added_pass_nodes) 1131*e4b17023SJohn Marino { 1132*e4b17023SJohn Marino struct pass_list_node *next_node = added_pass_nodes->next; 1133*e4b17023SJohn Marino enum tree_dump_index tdi; 1134*e4b17023SJohn Marino register_one_dump_file (added_pass_nodes->pass); 1135*e4b17023SJohn Marino if (added_pass_nodes->pass->type == SIMPLE_IPA_PASS 1136*e4b17023SJohn Marino || added_pass_nodes->pass->type == IPA_PASS) 1137*e4b17023SJohn Marino tdi = TDI_ipa_all; 1138*e4b17023SJohn Marino else if (added_pass_nodes->pass->type == GIMPLE_PASS) 1139*e4b17023SJohn Marino tdi = TDI_tree_all; 1140*e4b17023SJohn Marino else 1141*e4b17023SJohn Marino tdi = TDI_rtl_all; 1142*e4b17023SJohn Marino /* Check if dump-all flag is specified. */ 1143*e4b17023SJohn Marino if (get_dump_file_info (tdi)->state) 1144*e4b17023SJohn Marino get_dump_file_info (added_pass_nodes->pass->static_pass_number) 1145*e4b17023SJohn Marino ->state = get_dump_file_info (tdi)->state; 1146*e4b17023SJohn Marino XDELETE (added_pass_nodes); 1147*e4b17023SJohn Marino added_pass_nodes = next_node; 1148*e4b17023SJohn Marino } 1149*e4b17023SJohn Marino } 1150*e4b17023SJohn Marino 1151*e4b17023SJohn Marino /* Construct the pass tree. The sequencing of passes is driven by 1152*e4b17023SJohn Marino the cgraph routines: 1153*e4b17023SJohn Marino 1154*e4b17023SJohn Marino cgraph_finalize_compilation_unit () 1155*e4b17023SJohn Marino for each node N in the cgraph 1156*e4b17023SJohn Marino cgraph_analyze_function (N) 1157*e4b17023SJohn Marino cgraph_lower_function (N) -> all_lowering_passes 1158*e4b17023SJohn Marino 1159*e4b17023SJohn Marino If we are optimizing, cgraph_optimize is then invoked: 1160*e4b17023SJohn Marino 1161*e4b17023SJohn Marino cgraph_optimize () 1162*e4b17023SJohn Marino ipa_passes () -> all_small_ipa_passes 1163*e4b17023SJohn Marino cgraph_expand_all_functions () 1164*e4b17023SJohn Marino for each node N in the cgraph 1165*e4b17023SJohn Marino cgraph_expand_function (N) 1166*e4b17023SJohn Marino tree_rest_of_compilation (DECL (N)) -> all_passes 1167*e4b17023SJohn Marino */ 1168*e4b17023SJohn Marino 1169*e4b17023SJohn Marino void 1170*e4b17023SJohn Marino init_optimization_passes (void) 1171*e4b17023SJohn Marino { 1172*e4b17023SJohn Marino struct opt_pass **p; 1173*e4b17023SJohn Marino 1174*e4b17023SJohn Marino #define NEXT_PASS(PASS) (p = next_pass_1 (p, &((PASS).pass))) 1175*e4b17023SJohn Marino 1176*e4b17023SJohn Marino /* All passes needed to lower the function into shape optimizers can 1177*e4b17023SJohn Marino operate on. These passes are always run first on the function, but 1178*e4b17023SJohn Marino backend might produce already lowered functions that are not processed 1179*e4b17023SJohn Marino by these passes. */ 1180*e4b17023SJohn Marino p = &all_lowering_passes; 1181*e4b17023SJohn Marino NEXT_PASS (pass_warn_unused_result); 1182*e4b17023SJohn Marino NEXT_PASS (pass_diagnose_omp_blocks); 1183*e4b17023SJohn Marino NEXT_PASS (pass_diagnose_tm_blocks); 1184*e4b17023SJohn Marino NEXT_PASS (pass_mudflap_1); 1185*e4b17023SJohn Marino NEXT_PASS (pass_lower_omp); 1186*e4b17023SJohn Marino NEXT_PASS (pass_lower_cf); 1187*e4b17023SJohn Marino NEXT_PASS (pass_lower_tm); 1188*e4b17023SJohn Marino NEXT_PASS (pass_refactor_eh); 1189*e4b17023SJohn Marino NEXT_PASS (pass_lower_eh); 1190*e4b17023SJohn Marino NEXT_PASS (pass_build_cfg); 1191*e4b17023SJohn Marino NEXT_PASS (pass_warn_function_return); 1192*e4b17023SJohn Marino NEXT_PASS (pass_build_cgraph_edges); 1193*e4b17023SJohn Marino *p = NULL; 1194*e4b17023SJohn Marino 1195*e4b17023SJohn Marino /* Interprocedural optimization passes. */ 1196*e4b17023SJohn Marino p = &all_small_ipa_passes; 1197*e4b17023SJohn Marino NEXT_PASS (pass_ipa_free_lang_data); 1198*e4b17023SJohn Marino NEXT_PASS (pass_ipa_function_and_variable_visibility); 1199*e4b17023SJohn Marino NEXT_PASS (pass_early_local_passes); 1200*e4b17023SJohn Marino { 1201*e4b17023SJohn Marino struct opt_pass **p = &pass_early_local_passes.pass.sub; 1202*e4b17023SJohn Marino NEXT_PASS (pass_fixup_cfg); 1203*e4b17023SJohn Marino NEXT_PASS (pass_init_datastructures); 1204*e4b17023SJohn Marino NEXT_PASS (pass_expand_omp); 1205*e4b17023SJohn Marino 1206*e4b17023SJohn Marino NEXT_PASS (pass_referenced_vars); 1207*e4b17023SJohn Marino NEXT_PASS (pass_build_ssa); 1208*e4b17023SJohn Marino NEXT_PASS (pass_lower_vector); 1209*e4b17023SJohn Marino NEXT_PASS (pass_early_warn_uninitialized); 1210*e4b17023SJohn Marino NEXT_PASS (pass_rebuild_cgraph_edges); 1211*e4b17023SJohn Marino NEXT_PASS (pass_inline_parameters); 1212*e4b17023SJohn Marino NEXT_PASS (pass_early_inline); 1213*e4b17023SJohn Marino NEXT_PASS (pass_all_early_optimizations); 1214*e4b17023SJohn Marino { 1215*e4b17023SJohn Marino struct opt_pass **p = &pass_all_early_optimizations.pass.sub; 1216*e4b17023SJohn Marino NEXT_PASS (pass_remove_cgraph_callee_edges); 1217*e4b17023SJohn Marino NEXT_PASS (pass_rename_ssa_copies); 1218*e4b17023SJohn Marino NEXT_PASS (pass_ccp); 1219*e4b17023SJohn Marino NEXT_PASS (pass_forwprop); 1220*e4b17023SJohn Marino /* pass_build_ealias is a dummy pass that ensures that we 1221*e4b17023SJohn Marino execute TODO_rebuild_alias at this point. Re-building 1222*e4b17023SJohn Marino alias information also rewrites no longer addressed 1223*e4b17023SJohn Marino locals into SSA form if possible. */ 1224*e4b17023SJohn Marino NEXT_PASS (pass_build_ealias); 1225*e4b17023SJohn Marino NEXT_PASS (pass_sra_early); 1226*e4b17023SJohn Marino NEXT_PASS (pass_fre); 1227*e4b17023SJohn Marino NEXT_PASS (pass_copy_prop); 1228*e4b17023SJohn Marino NEXT_PASS (pass_merge_phi); 1229*e4b17023SJohn Marino NEXT_PASS (pass_cd_dce); 1230*e4b17023SJohn Marino NEXT_PASS (pass_early_ipa_sra); 1231*e4b17023SJohn Marino NEXT_PASS (pass_tail_recursion); 1232*e4b17023SJohn Marino NEXT_PASS (pass_convert_switch); 1233*e4b17023SJohn Marino NEXT_PASS (pass_cleanup_eh); 1234*e4b17023SJohn Marino NEXT_PASS (pass_profile); 1235*e4b17023SJohn Marino NEXT_PASS (pass_local_pure_const); 1236*e4b17023SJohn Marino /* Split functions creates parts that are not run through 1237*e4b17023SJohn Marino early optimizations again. It is thus good idea to do this 1238*e4b17023SJohn Marino late. */ 1239*e4b17023SJohn Marino NEXT_PASS (pass_split_functions); 1240*e4b17023SJohn Marino } 1241*e4b17023SJohn Marino NEXT_PASS (pass_release_ssa_names); 1242*e4b17023SJohn Marino NEXT_PASS (pass_rebuild_cgraph_edges); 1243*e4b17023SJohn Marino NEXT_PASS (pass_inline_parameters); 1244*e4b17023SJohn Marino } 1245*e4b17023SJohn Marino NEXT_PASS (pass_ipa_tree_profile); 1246*e4b17023SJohn Marino { 1247*e4b17023SJohn Marino struct opt_pass **p = &pass_ipa_tree_profile.pass.sub; 1248*e4b17023SJohn Marino NEXT_PASS (pass_feedback_split_functions); 1249*e4b17023SJohn Marino } 1250*e4b17023SJohn Marino NEXT_PASS (pass_ipa_increase_alignment); 1251*e4b17023SJohn Marino NEXT_PASS (pass_ipa_matrix_reorg); 1252*e4b17023SJohn Marino NEXT_PASS (pass_ipa_tm); 1253*e4b17023SJohn Marino NEXT_PASS (pass_ipa_lower_emutls); 1254*e4b17023SJohn Marino *p = NULL; 1255*e4b17023SJohn Marino 1256*e4b17023SJohn Marino p = &all_regular_ipa_passes; 1257*e4b17023SJohn Marino NEXT_PASS (pass_ipa_whole_program_visibility); 1258*e4b17023SJohn Marino NEXT_PASS (pass_ipa_profile); 1259*e4b17023SJohn Marino NEXT_PASS (pass_ipa_cp); 1260*e4b17023SJohn Marino NEXT_PASS (pass_ipa_cdtor_merge); 1261*e4b17023SJohn Marino NEXT_PASS (pass_ipa_inline); 1262*e4b17023SJohn Marino NEXT_PASS (pass_ipa_pure_const); 1263*e4b17023SJohn Marino NEXT_PASS (pass_ipa_reference); 1264*e4b17023SJohn Marino *p = NULL; 1265*e4b17023SJohn Marino 1266*e4b17023SJohn Marino p = &all_lto_gen_passes; 1267*e4b17023SJohn Marino NEXT_PASS (pass_ipa_lto_gimple_out); 1268*e4b17023SJohn Marino NEXT_PASS (pass_ipa_lto_finish_out); /* This must be the last LTO pass. */ 1269*e4b17023SJohn Marino *p = NULL; 1270*e4b17023SJohn Marino 1271*e4b17023SJohn Marino /* Simple IPA passes executed after the regular passes. In WHOPR mode the 1272*e4b17023SJohn Marino passes are executed after partitioning and thus see just parts of the 1273*e4b17023SJohn Marino compiled unit. */ 1274*e4b17023SJohn Marino p = &all_late_ipa_passes; 1275*e4b17023SJohn Marino NEXT_PASS (pass_ipa_pta); 1276*e4b17023SJohn Marino *p = NULL; 1277*e4b17023SJohn Marino /* These passes are run after IPA passes on every function that is being 1278*e4b17023SJohn Marino output to the assembler file. */ 1279*e4b17023SJohn Marino p = &all_passes; 1280*e4b17023SJohn Marino NEXT_PASS (pass_fixup_cfg); 1281*e4b17023SJohn Marino NEXT_PASS (pass_lower_eh_dispatch); 1282*e4b17023SJohn Marino NEXT_PASS (pass_all_optimizations); 1283*e4b17023SJohn Marino { 1284*e4b17023SJohn Marino struct opt_pass **p = &pass_all_optimizations.pass.sub; 1285*e4b17023SJohn Marino NEXT_PASS (pass_remove_cgraph_callee_edges); 1286*e4b17023SJohn Marino /* Initial scalar cleanups before alias computation. 1287*e4b17023SJohn Marino They ensure memory accesses are not indirect wherever possible. */ 1288*e4b17023SJohn Marino NEXT_PASS (pass_strip_predict_hints); 1289*e4b17023SJohn Marino NEXT_PASS (pass_rename_ssa_copies); 1290*e4b17023SJohn Marino NEXT_PASS (pass_complete_unrolli); 1291*e4b17023SJohn Marino NEXT_PASS (pass_ccp); 1292*e4b17023SJohn Marino NEXT_PASS (pass_forwprop); 1293*e4b17023SJohn Marino NEXT_PASS (pass_call_cdce); 1294*e4b17023SJohn Marino /* pass_build_alias is a dummy pass that ensures that we 1295*e4b17023SJohn Marino execute TODO_rebuild_alias at this point. Re-building 1296*e4b17023SJohn Marino alias information also rewrites no longer addressed 1297*e4b17023SJohn Marino locals into SSA form if possible. */ 1298*e4b17023SJohn Marino NEXT_PASS (pass_build_alias); 1299*e4b17023SJohn Marino NEXT_PASS (pass_return_slot); 1300*e4b17023SJohn Marino NEXT_PASS (pass_phiprop); 1301*e4b17023SJohn Marino NEXT_PASS (pass_fre); 1302*e4b17023SJohn Marino NEXT_PASS (pass_copy_prop); 1303*e4b17023SJohn Marino NEXT_PASS (pass_merge_phi); 1304*e4b17023SJohn Marino NEXT_PASS (pass_vrp); 1305*e4b17023SJohn Marino NEXT_PASS (pass_dce); 1306*e4b17023SJohn Marino NEXT_PASS (pass_cselim); 1307*e4b17023SJohn Marino NEXT_PASS (pass_tree_ifcombine); 1308*e4b17023SJohn Marino NEXT_PASS (pass_phiopt); 1309*e4b17023SJohn Marino NEXT_PASS (pass_tail_recursion); 1310*e4b17023SJohn Marino NEXT_PASS (pass_ch); 1311*e4b17023SJohn Marino NEXT_PASS (pass_stdarg); 1312*e4b17023SJohn Marino NEXT_PASS (pass_lower_complex); 1313*e4b17023SJohn Marino NEXT_PASS (pass_sra); 1314*e4b17023SJohn Marino NEXT_PASS (pass_rename_ssa_copies); 1315*e4b17023SJohn Marino /* The dom pass will also resolve all __builtin_constant_p calls 1316*e4b17023SJohn Marino that are still there to 0. This has to be done after some 1317*e4b17023SJohn Marino propagations have already run, but before some more dead code 1318*e4b17023SJohn Marino is removed, and this place fits nicely. Remember this when 1319*e4b17023SJohn Marino trying to move or duplicate pass_dominator somewhere earlier. */ 1320*e4b17023SJohn Marino NEXT_PASS (pass_dominator); 1321*e4b17023SJohn Marino /* The only const/copy propagation opportunities left after 1322*e4b17023SJohn Marino DOM should be due to degenerate PHI nodes. So rather than 1323*e4b17023SJohn Marino run the full propagators, run a specialized pass which 1324*e4b17023SJohn Marino only examines PHIs to discover const/copy propagation 1325*e4b17023SJohn Marino opportunities. */ 1326*e4b17023SJohn Marino NEXT_PASS (pass_phi_only_cprop); 1327*e4b17023SJohn Marino NEXT_PASS (pass_dse); 1328*e4b17023SJohn Marino NEXT_PASS (pass_reassoc); 1329*e4b17023SJohn Marino NEXT_PASS (pass_dce); 1330*e4b17023SJohn Marino NEXT_PASS (pass_forwprop); 1331*e4b17023SJohn Marino NEXT_PASS (pass_phiopt); 1332*e4b17023SJohn Marino NEXT_PASS (pass_object_sizes); 1333*e4b17023SJohn Marino NEXT_PASS (pass_strlen); 1334*e4b17023SJohn Marino NEXT_PASS (pass_ccp); 1335*e4b17023SJohn Marino NEXT_PASS (pass_copy_prop); 1336*e4b17023SJohn Marino NEXT_PASS (pass_cse_sincos); 1337*e4b17023SJohn Marino NEXT_PASS (pass_optimize_bswap); 1338*e4b17023SJohn Marino NEXT_PASS (pass_split_crit_edges); 1339*e4b17023SJohn Marino NEXT_PASS (pass_pre); 1340*e4b17023SJohn Marino NEXT_PASS (pass_sink_code); 1341*e4b17023SJohn Marino NEXT_PASS (pass_tree_loop); 1342*e4b17023SJohn Marino { 1343*e4b17023SJohn Marino struct opt_pass **p = &pass_tree_loop.pass.sub; 1344*e4b17023SJohn Marino NEXT_PASS (pass_tree_loop_init); 1345*e4b17023SJohn Marino NEXT_PASS (pass_lim); 1346*e4b17023SJohn Marino NEXT_PASS (pass_copy_prop); 1347*e4b17023SJohn Marino NEXT_PASS (pass_dce_loop); 1348*e4b17023SJohn Marino NEXT_PASS (pass_tree_unswitch); 1349*e4b17023SJohn Marino NEXT_PASS (pass_scev_cprop); 1350*e4b17023SJohn Marino NEXT_PASS (pass_record_bounds); 1351*e4b17023SJohn Marino NEXT_PASS (pass_check_data_deps); 1352*e4b17023SJohn Marino NEXT_PASS (pass_loop_distribution); 1353*e4b17023SJohn Marino NEXT_PASS (pass_copy_prop); 1354*e4b17023SJohn Marino NEXT_PASS (pass_graphite); 1355*e4b17023SJohn Marino { 1356*e4b17023SJohn Marino struct opt_pass **p = &pass_graphite.pass.sub; 1357*e4b17023SJohn Marino NEXT_PASS (pass_graphite_transforms); 1358*e4b17023SJohn Marino NEXT_PASS (pass_lim); 1359*e4b17023SJohn Marino NEXT_PASS (pass_copy_prop); 1360*e4b17023SJohn Marino NEXT_PASS (pass_dce_loop); 1361*e4b17023SJohn Marino } 1362*e4b17023SJohn Marino NEXT_PASS (pass_iv_canon); 1363*e4b17023SJohn Marino NEXT_PASS (pass_if_conversion); 1364*e4b17023SJohn Marino NEXT_PASS (pass_vectorize); 1365*e4b17023SJohn Marino { 1366*e4b17023SJohn Marino struct opt_pass **p = &pass_vectorize.pass.sub; 1367*e4b17023SJohn Marino NEXT_PASS (pass_dce_loop); 1368*e4b17023SJohn Marino } 1369*e4b17023SJohn Marino NEXT_PASS (pass_predcom); 1370*e4b17023SJohn Marino NEXT_PASS (pass_complete_unroll); 1371*e4b17023SJohn Marino NEXT_PASS (pass_slp_vectorize); 1372*e4b17023SJohn Marino NEXT_PASS (pass_parallelize_loops); 1373*e4b17023SJohn Marino NEXT_PASS (pass_loop_prefetch); 1374*e4b17023SJohn Marino NEXT_PASS (pass_iv_optimize); 1375*e4b17023SJohn Marino NEXT_PASS (pass_lim); 1376*e4b17023SJohn Marino NEXT_PASS (pass_tree_loop_done); 1377*e4b17023SJohn Marino } 1378*e4b17023SJohn Marino NEXT_PASS (pass_lower_vector_ssa); 1379*e4b17023SJohn Marino NEXT_PASS (pass_cse_reciprocals); 1380*e4b17023SJohn Marino NEXT_PASS (pass_reassoc); 1381*e4b17023SJohn Marino NEXT_PASS (pass_vrp); 1382*e4b17023SJohn Marino NEXT_PASS (pass_dominator); 1383*e4b17023SJohn Marino /* The only const/copy propagation opportunities left after 1384*e4b17023SJohn Marino DOM should be due to degenerate PHI nodes. So rather than 1385*e4b17023SJohn Marino run the full propagators, run a specialized pass which 1386*e4b17023SJohn Marino only examines PHIs to discover const/copy propagation 1387*e4b17023SJohn Marino opportunities. */ 1388*e4b17023SJohn Marino NEXT_PASS (pass_phi_only_cprop); 1389*e4b17023SJohn Marino NEXT_PASS (pass_cd_dce); 1390*e4b17023SJohn Marino NEXT_PASS (pass_tracer); 1391*e4b17023SJohn Marino 1392*e4b17023SJohn Marino /* FIXME: If DCE is not run before checking for uninitialized uses, 1393*e4b17023SJohn Marino we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c). 1394*e4b17023SJohn Marino However, this also causes us to misdiagnose cases that should be 1395*e4b17023SJohn Marino real warnings (e.g., testsuite/gcc.dg/pr18501.c). 1396*e4b17023SJohn Marino 1397*e4b17023SJohn Marino To fix the false positives in uninit-5.c, we would have to 1398*e4b17023SJohn Marino account for the predicates protecting the set and the use of each 1399*e4b17023SJohn Marino variable. Using a representation like Gated Single Assignment 1400*e4b17023SJohn Marino may help. */ 1401*e4b17023SJohn Marino NEXT_PASS (pass_late_warn_uninitialized); 1402*e4b17023SJohn Marino NEXT_PASS (pass_dse); 1403*e4b17023SJohn Marino NEXT_PASS (pass_forwprop); 1404*e4b17023SJohn Marino NEXT_PASS (pass_phiopt); 1405*e4b17023SJohn Marino NEXT_PASS (pass_fold_builtins); 1406*e4b17023SJohn Marino NEXT_PASS (pass_optimize_widening_mul); 1407*e4b17023SJohn Marino NEXT_PASS (pass_tail_calls); 1408*e4b17023SJohn Marino NEXT_PASS (pass_rename_ssa_copies); 1409*e4b17023SJohn Marino NEXT_PASS (pass_uncprop); 1410*e4b17023SJohn Marino NEXT_PASS (pass_local_pure_const); 1411*e4b17023SJohn Marino } 1412*e4b17023SJohn Marino NEXT_PASS (pass_tm_init); 1413*e4b17023SJohn Marino { 1414*e4b17023SJohn Marino struct opt_pass **p = &pass_tm_init.pass.sub; 1415*e4b17023SJohn Marino NEXT_PASS (pass_tm_mark); 1416*e4b17023SJohn Marino NEXT_PASS (pass_tm_memopt); 1417*e4b17023SJohn Marino NEXT_PASS (pass_tm_edges); 1418*e4b17023SJohn Marino } 1419*e4b17023SJohn Marino NEXT_PASS (pass_lower_complex_O0); 1420*e4b17023SJohn Marino NEXT_PASS (pass_cleanup_eh); 1421*e4b17023SJohn Marino NEXT_PASS (pass_lower_resx); 1422*e4b17023SJohn Marino NEXT_PASS (pass_nrv); 1423*e4b17023SJohn Marino NEXT_PASS (pass_mudflap_2); 1424*e4b17023SJohn Marino NEXT_PASS (pass_cleanup_cfg_post_optimizing); 1425*e4b17023SJohn Marino NEXT_PASS (pass_warn_function_noreturn); 1426*e4b17023SJohn Marino 1427*e4b17023SJohn Marino NEXT_PASS (pass_expand); 1428*e4b17023SJohn Marino 1429*e4b17023SJohn Marino NEXT_PASS (pass_rest_of_compilation); 1430*e4b17023SJohn Marino { 1431*e4b17023SJohn Marino struct opt_pass **p = &pass_rest_of_compilation.pass.sub; 1432*e4b17023SJohn Marino NEXT_PASS (pass_init_function); 1433*e4b17023SJohn Marino NEXT_PASS (pass_jump); 1434*e4b17023SJohn Marino NEXT_PASS (pass_rtl_eh); 1435*e4b17023SJohn Marino NEXT_PASS (pass_initial_value_sets); 1436*e4b17023SJohn Marino NEXT_PASS (pass_unshare_all_rtl); 1437*e4b17023SJohn Marino NEXT_PASS (pass_instantiate_virtual_regs); 1438*e4b17023SJohn Marino NEXT_PASS (pass_into_cfg_layout_mode); 1439*e4b17023SJohn Marino NEXT_PASS (pass_jump2); 1440*e4b17023SJohn Marino NEXT_PASS (pass_lower_subreg); 1441*e4b17023SJohn Marino NEXT_PASS (pass_df_initialize_opt); 1442*e4b17023SJohn Marino NEXT_PASS (pass_cse); 1443*e4b17023SJohn Marino NEXT_PASS (pass_rtl_fwprop); 1444*e4b17023SJohn Marino NEXT_PASS (pass_rtl_cprop); 1445*e4b17023SJohn Marino NEXT_PASS (pass_rtl_pre); 1446*e4b17023SJohn Marino NEXT_PASS (pass_rtl_hoist); 1447*e4b17023SJohn Marino NEXT_PASS (pass_rtl_cprop); 1448*e4b17023SJohn Marino NEXT_PASS (pass_rtl_store_motion); 1449*e4b17023SJohn Marino NEXT_PASS (pass_cse_after_global_opts); 1450*e4b17023SJohn Marino NEXT_PASS (pass_rtl_ifcvt); 1451*e4b17023SJohn Marino NEXT_PASS (pass_reginfo_init); 1452*e4b17023SJohn Marino /* Perform loop optimizations. It might be better to do them a bit 1453*e4b17023SJohn Marino sooner, but we want the profile feedback to work more 1454*e4b17023SJohn Marino efficiently. */ 1455*e4b17023SJohn Marino NEXT_PASS (pass_loop2); 1456*e4b17023SJohn Marino { 1457*e4b17023SJohn Marino struct opt_pass **p = &pass_loop2.pass.sub; 1458*e4b17023SJohn Marino NEXT_PASS (pass_rtl_loop_init); 1459*e4b17023SJohn Marino NEXT_PASS (pass_rtl_move_loop_invariants); 1460*e4b17023SJohn Marino NEXT_PASS (pass_rtl_unswitch); 1461*e4b17023SJohn Marino NEXT_PASS (pass_rtl_unroll_and_peel_loops); 1462*e4b17023SJohn Marino NEXT_PASS (pass_rtl_doloop); 1463*e4b17023SJohn Marino NEXT_PASS (pass_rtl_loop_done); 1464*e4b17023SJohn Marino *p = NULL; 1465*e4b17023SJohn Marino } 1466*e4b17023SJohn Marino NEXT_PASS (pass_web); 1467*e4b17023SJohn Marino NEXT_PASS (pass_rtl_cprop); 1468*e4b17023SJohn Marino NEXT_PASS (pass_cse2); 1469*e4b17023SJohn Marino NEXT_PASS (pass_rtl_dse1); 1470*e4b17023SJohn Marino NEXT_PASS (pass_rtl_fwprop_addr); 1471*e4b17023SJohn Marino NEXT_PASS (pass_inc_dec); 1472*e4b17023SJohn Marino NEXT_PASS (pass_initialize_regs); 1473*e4b17023SJohn Marino NEXT_PASS (pass_ud_rtl_dce); 1474*e4b17023SJohn Marino NEXT_PASS (pass_combine); 1475*e4b17023SJohn Marino NEXT_PASS (pass_if_after_combine); 1476*e4b17023SJohn Marino NEXT_PASS (pass_partition_blocks); 1477*e4b17023SJohn Marino NEXT_PASS (pass_regmove); 1478*e4b17023SJohn Marino NEXT_PASS (pass_outof_cfg_layout_mode); 1479*e4b17023SJohn Marino NEXT_PASS (pass_split_all_insns); 1480*e4b17023SJohn Marino NEXT_PASS (pass_lower_subreg2); 1481*e4b17023SJohn Marino NEXT_PASS (pass_df_initialize_no_opt); 1482*e4b17023SJohn Marino NEXT_PASS (pass_stack_ptr_mod); 1483*e4b17023SJohn Marino NEXT_PASS (pass_mode_switching); 1484*e4b17023SJohn Marino NEXT_PASS (pass_match_asm_constraints); 1485*e4b17023SJohn Marino NEXT_PASS (pass_sms); 1486*e4b17023SJohn Marino NEXT_PASS (pass_sched); 1487*e4b17023SJohn Marino NEXT_PASS (pass_ira); 1488*e4b17023SJohn Marino NEXT_PASS (pass_reload); 1489*e4b17023SJohn Marino NEXT_PASS (pass_postreload); 1490*e4b17023SJohn Marino { 1491*e4b17023SJohn Marino struct opt_pass **p = &pass_postreload.pass.sub; 1492*e4b17023SJohn Marino NEXT_PASS (pass_postreload_cse); 1493*e4b17023SJohn Marino NEXT_PASS (pass_gcse2); 1494*e4b17023SJohn Marino NEXT_PASS (pass_split_after_reload); 1495*e4b17023SJohn Marino NEXT_PASS (pass_ree); 1496*e4b17023SJohn Marino NEXT_PASS (pass_compare_elim_after_reload); 1497*e4b17023SJohn Marino NEXT_PASS (pass_branch_target_load_optimize1); 1498*e4b17023SJohn Marino NEXT_PASS (pass_thread_prologue_and_epilogue); 1499*e4b17023SJohn Marino NEXT_PASS (pass_rtl_dse2); 1500*e4b17023SJohn Marino NEXT_PASS (pass_stack_adjustments); 1501*e4b17023SJohn Marino NEXT_PASS (pass_peephole2); 1502*e4b17023SJohn Marino NEXT_PASS (pass_if_after_reload); 1503*e4b17023SJohn Marino NEXT_PASS (pass_regrename); 1504*e4b17023SJohn Marino NEXT_PASS (pass_cprop_hardreg); 1505*e4b17023SJohn Marino NEXT_PASS (pass_fast_rtl_dce); 1506*e4b17023SJohn Marino NEXT_PASS (pass_reorder_blocks); 1507*e4b17023SJohn Marino NEXT_PASS (pass_branch_target_load_optimize2); 1508*e4b17023SJohn Marino NEXT_PASS (pass_leaf_regs); 1509*e4b17023SJohn Marino NEXT_PASS (pass_split_before_sched2); 1510*e4b17023SJohn Marino NEXT_PASS (pass_sched2); 1511*e4b17023SJohn Marino NEXT_PASS (pass_stack_regs); 1512*e4b17023SJohn Marino { 1513*e4b17023SJohn Marino struct opt_pass **p = &pass_stack_regs.pass.sub; 1514*e4b17023SJohn Marino NEXT_PASS (pass_split_before_regstack); 1515*e4b17023SJohn Marino NEXT_PASS (pass_stack_regs_run); 1516*e4b17023SJohn Marino } 1517*e4b17023SJohn Marino NEXT_PASS (pass_compute_alignments); 1518*e4b17023SJohn Marino NEXT_PASS (pass_duplicate_computed_gotos); 1519*e4b17023SJohn Marino NEXT_PASS (pass_variable_tracking); 1520*e4b17023SJohn Marino NEXT_PASS (pass_free_cfg); 1521*e4b17023SJohn Marino NEXT_PASS (pass_machine_reorg); 1522*e4b17023SJohn Marino NEXT_PASS (pass_cleanup_barriers); 1523*e4b17023SJohn Marino NEXT_PASS (pass_delay_slots); 1524*e4b17023SJohn Marino NEXT_PASS (pass_split_for_shorten_branches); 1525*e4b17023SJohn Marino NEXT_PASS (pass_convert_to_eh_region_ranges); 1526*e4b17023SJohn Marino NEXT_PASS (pass_shorten_branches); 1527*e4b17023SJohn Marino NEXT_PASS (pass_set_nothrow_function_flags); 1528*e4b17023SJohn Marino NEXT_PASS (pass_dwarf2_frame); 1529*e4b17023SJohn Marino NEXT_PASS (pass_final); 1530*e4b17023SJohn Marino } 1531*e4b17023SJohn Marino NEXT_PASS (pass_df_finish); 1532*e4b17023SJohn Marino } 1533*e4b17023SJohn Marino NEXT_PASS (pass_clean_state); 1534*e4b17023SJohn Marino *p = NULL; 1535*e4b17023SJohn Marino 1536*e4b17023SJohn Marino #undef NEXT_PASS 1537*e4b17023SJohn Marino 1538*e4b17023SJohn Marino /* Register the passes with the tree dump code. */ 1539*e4b17023SJohn Marino register_dump_files (all_lowering_passes, PROP_gimple_any); 1540*e4b17023SJohn Marino register_dump_files (all_small_ipa_passes, 1541*e4b17023SJohn Marino PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh 1542*e4b17023SJohn Marino | PROP_cfg); 1543*e4b17023SJohn Marino register_dump_files (all_regular_ipa_passes, 1544*e4b17023SJohn Marino PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh 1545*e4b17023SJohn Marino | PROP_cfg); 1546*e4b17023SJohn Marino register_dump_files (all_lto_gen_passes, 1547*e4b17023SJohn Marino PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh 1548*e4b17023SJohn Marino | PROP_cfg); 1549*e4b17023SJohn Marino register_dump_files (all_late_ipa_passes, 1550*e4b17023SJohn Marino PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh 1551*e4b17023SJohn Marino | PROP_cfg); 1552*e4b17023SJohn Marino register_dump_files (all_passes, 1553*e4b17023SJohn Marino PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh 1554*e4b17023SJohn Marino | PROP_cfg); 1555*e4b17023SJohn Marino } 1556*e4b17023SJohn Marino 1557*e4b17023SJohn Marino /* If we are in IPA mode (i.e., current_function_decl is NULL), call 1558*e4b17023SJohn Marino function CALLBACK for every function in the call graph. Otherwise, 1559*e4b17023SJohn Marino call CALLBACK on the current function. */ 1560*e4b17023SJohn Marino 1561*e4b17023SJohn Marino static void 1562*e4b17023SJohn Marino do_per_function (void (*callback) (void *data), void *data) 1563*e4b17023SJohn Marino { 1564*e4b17023SJohn Marino if (current_function_decl) 1565*e4b17023SJohn Marino callback (data); 1566*e4b17023SJohn Marino else 1567*e4b17023SJohn Marino { 1568*e4b17023SJohn Marino struct cgraph_node *node; 1569*e4b17023SJohn Marino for (node = cgraph_nodes; node; node = node->next) 1570*e4b17023SJohn Marino if (node->analyzed && gimple_has_body_p (node->decl) 1571*e4b17023SJohn Marino && (!node->clone_of || node->decl != node->clone_of->decl)) 1572*e4b17023SJohn Marino { 1573*e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 1574*e4b17023SJohn Marino current_function_decl = node->decl; 1575*e4b17023SJohn Marino callback (data); 1576*e4b17023SJohn Marino if (!flag_wpa) 1577*e4b17023SJohn Marino { 1578*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS); 1579*e4b17023SJohn Marino free_dominance_info (CDI_POST_DOMINATORS); 1580*e4b17023SJohn Marino } 1581*e4b17023SJohn Marino current_function_decl = NULL; 1582*e4b17023SJohn Marino pop_cfun (); 1583*e4b17023SJohn Marino ggc_collect (); 1584*e4b17023SJohn Marino } 1585*e4b17023SJohn Marino } 1586*e4b17023SJohn Marino } 1587*e4b17023SJohn Marino 1588*e4b17023SJohn Marino /* Because inlining might remove no-longer reachable nodes, we need to 1589*e4b17023SJohn Marino keep the array visible to garbage collector to avoid reading collected 1590*e4b17023SJohn Marino out nodes. */ 1591*e4b17023SJohn Marino static int nnodes; 1592*e4b17023SJohn Marino static GTY ((length ("nnodes"))) cgraph_node_ptr *order; 1593*e4b17023SJohn Marino 1594*e4b17023SJohn Marino /* If we are in IPA mode (i.e., current_function_decl is NULL), call 1595*e4b17023SJohn Marino function CALLBACK for every function in the call graph. Otherwise, 1596*e4b17023SJohn Marino call CALLBACK on the current function. 1597*e4b17023SJohn Marino This function is global so that plugins can use it. */ 1598*e4b17023SJohn Marino void 1599*e4b17023SJohn Marino do_per_function_toporder (void (*callback) (void *data), void *data) 1600*e4b17023SJohn Marino { 1601*e4b17023SJohn Marino int i; 1602*e4b17023SJohn Marino 1603*e4b17023SJohn Marino if (current_function_decl) 1604*e4b17023SJohn Marino callback (data); 1605*e4b17023SJohn Marino else 1606*e4b17023SJohn Marino { 1607*e4b17023SJohn Marino gcc_assert (!order); 1608*e4b17023SJohn Marino order = ggc_alloc_vec_cgraph_node_ptr (cgraph_n_nodes); 1609*e4b17023SJohn Marino nnodes = ipa_reverse_postorder (order); 1610*e4b17023SJohn Marino for (i = nnodes - 1; i >= 0; i--) 1611*e4b17023SJohn Marino order[i]->process = 1; 1612*e4b17023SJohn Marino for (i = nnodes - 1; i >= 0; i--) 1613*e4b17023SJohn Marino { 1614*e4b17023SJohn Marino struct cgraph_node *node = order[i]; 1615*e4b17023SJohn Marino 1616*e4b17023SJohn Marino /* Allow possibly removed nodes to be garbage collected. */ 1617*e4b17023SJohn Marino order[i] = NULL; 1618*e4b17023SJohn Marino node->process = 0; 1619*e4b17023SJohn Marino if (cgraph_function_with_gimple_body_p (node)) 1620*e4b17023SJohn Marino { 1621*e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 1622*e4b17023SJohn Marino current_function_decl = node->decl; 1623*e4b17023SJohn Marino callback (data); 1624*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS); 1625*e4b17023SJohn Marino free_dominance_info (CDI_POST_DOMINATORS); 1626*e4b17023SJohn Marino current_function_decl = NULL; 1627*e4b17023SJohn Marino pop_cfun (); 1628*e4b17023SJohn Marino ggc_collect (); 1629*e4b17023SJohn Marino } 1630*e4b17023SJohn Marino } 1631*e4b17023SJohn Marino } 1632*e4b17023SJohn Marino ggc_free (order); 1633*e4b17023SJohn Marino order = NULL; 1634*e4b17023SJohn Marino nnodes = 0; 1635*e4b17023SJohn Marino } 1636*e4b17023SJohn Marino 1637*e4b17023SJohn Marino /* Helper function to perform function body dump. */ 1638*e4b17023SJohn Marino 1639*e4b17023SJohn Marino static void 1640*e4b17023SJohn Marino execute_function_dump (void *data ATTRIBUTE_UNUSED) 1641*e4b17023SJohn Marino { 1642*e4b17023SJohn Marino if (dump_file && current_function_decl) 1643*e4b17023SJohn Marino { 1644*e4b17023SJohn Marino if (cfun->curr_properties & PROP_trees) 1645*e4b17023SJohn Marino dump_function_to_file (current_function_decl, dump_file, dump_flags); 1646*e4b17023SJohn Marino else 1647*e4b17023SJohn Marino { 1648*e4b17023SJohn Marino if (dump_flags & TDF_SLIM) 1649*e4b17023SJohn Marino print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); 1650*e4b17023SJohn Marino else if ((cfun->curr_properties & PROP_cfg) 1651*e4b17023SJohn Marino && (dump_flags & TDF_BLOCKS)) 1652*e4b17023SJohn Marino print_rtl_with_bb (dump_file, get_insns ()); 1653*e4b17023SJohn Marino else 1654*e4b17023SJohn Marino print_rtl (dump_file, get_insns ()); 1655*e4b17023SJohn Marino 1656*e4b17023SJohn Marino if ((cfun->curr_properties & PROP_cfg) 1657*e4b17023SJohn Marino && graph_dump_format != no_graph 1658*e4b17023SJohn Marino && (dump_flags & TDF_GRAPH)) 1659*e4b17023SJohn Marino print_rtl_graph_with_bb (dump_file_name, get_insns ()); 1660*e4b17023SJohn Marino } 1661*e4b17023SJohn Marino 1662*e4b17023SJohn Marino /* Flush the file. If verification fails, we won't be able to 1663*e4b17023SJohn Marino close the file before aborting. */ 1664*e4b17023SJohn Marino fflush (dump_file); 1665*e4b17023SJohn Marino } 1666*e4b17023SJohn Marino } 1667*e4b17023SJohn Marino 1668*e4b17023SJohn Marino /* Perform all TODO actions that ought to be done on each function. */ 1669*e4b17023SJohn Marino 1670*e4b17023SJohn Marino static void 1671*e4b17023SJohn Marino execute_function_todo (void *data) 1672*e4b17023SJohn Marino { 1673*e4b17023SJohn Marino unsigned int flags = (size_t)data; 1674*e4b17023SJohn Marino flags &= ~cfun->last_verified; 1675*e4b17023SJohn Marino if (!flags) 1676*e4b17023SJohn Marino return; 1677*e4b17023SJohn Marino 1678*e4b17023SJohn Marino /* Always cleanup the CFG before trying to update SSA. */ 1679*e4b17023SJohn Marino if (flags & TODO_cleanup_cfg) 1680*e4b17023SJohn Marino { 1681*e4b17023SJohn Marino bool cleanup = cleanup_tree_cfg (); 1682*e4b17023SJohn Marino 1683*e4b17023SJohn Marino if (cleanup && (cfun->curr_properties & PROP_ssa)) 1684*e4b17023SJohn Marino flags |= TODO_remove_unused_locals; 1685*e4b17023SJohn Marino 1686*e4b17023SJohn Marino /* When cleanup_tree_cfg merges consecutive blocks, it may 1687*e4b17023SJohn Marino perform some simplistic propagation when removing single 1688*e4b17023SJohn Marino valued PHI nodes. This propagation may, in turn, cause the 1689*e4b17023SJohn Marino SSA form to become out-of-date (see PR 22037). So, even 1690*e4b17023SJohn Marino if the parent pass had not scheduled an SSA update, we may 1691*e4b17023SJohn Marino still need to do one. */ 1692*e4b17023SJohn Marino if (!(flags & TODO_update_ssa_any) && need_ssa_update_p (cfun)) 1693*e4b17023SJohn Marino flags |= TODO_update_ssa; 1694*e4b17023SJohn Marino } 1695*e4b17023SJohn Marino 1696*e4b17023SJohn Marino if (flags & TODO_update_ssa_any) 1697*e4b17023SJohn Marino { 1698*e4b17023SJohn Marino unsigned update_flags = flags & TODO_update_ssa_any; 1699*e4b17023SJohn Marino update_ssa (update_flags); 1700*e4b17023SJohn Marino cfun->last_verified &= ~TODO_verify_ssa; 1701*e4b17023SJohn Marino } 1702*e4b17023SJohn Marino 1703*e4b17023SJohn Marino if (flags & TODO_rebuild_alias) 1704*e4b17023SJohn Marino { 1705*e4b17023SJohn Marino execute_update_addresses_taken (); 1706*e4b17023SJohn Marino compute_may_aliases (); 1707*e4b17023SJohn Marino } 1708*e4b17023SJohn Marino else if (optimize && (flags & TODO_update_address_taken)) 1709*e4b17023SJohn Marino execute_update_addresses_taken (); 1710*e4b17023SJohn Marino 1711*e4b17023SJohn Marino if (flags & TODO_remove_unused_locals) 1712*e4b17023SJohn Marino remove_unused_locals (); 1713*e4b17023SJohn Marino 1714*e4b17023SJohn Marino if (flags & TODO_rebuild_frequencies) 1715*e4b17023SJohn Marino rebuild_frequencies (); 1716*e4b17023SJohn Marino 1717*e4b17023SJohn Marino if (flags & TODO_rebuild_cgraph_edges) 1718*e4b17023SJohn Marino rebuild_cgraph_edges (); 1719*e4b17023SJohn Marino 1720*e4b17023SJohn Marino /* If we've seen errors do not bother running any verifiers. */ 1721*e4b17023SJohn Marino if (seen_error ()) 1722*e4b17023SJohn Marino return; 1723*e4b17023SJohn Marino 1724*e4b17023SJohn Marino #if defined ENABLE_CHECKING 1725*e4b17023SJohn Marino if (flags & TODO_verify_ssa 1726*e4b17023SJohn Marino || (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA))) 1727*e4b17023SJohn Marino { 1728*e4b17023SJohn Marino verify_gimple_in_cfg (cfun); 1729*e4b17023SJohn Marino verify_ssa (true); 1730*e4b17023SJohn Marino } 1731*e4b17023SJohn Marino else if (flags & TODO_verify_stmts) 1732*e4b17023SJohn Marino verify_gimple_in_cfg (cfun); 1733*e4b17023SJohn Marino if (flags & TODO_verify_flow) 1734*e4b17023SJohn Marino verify_flow_info (); 1735*e4b17023SJohn Marino if (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA)) 1736*e4b17023SJohn Marino verify_loop_closed_ssa (false); 1737*e4b17023SJohn Marino if (flags & TODO_verify_rtl_sharing) 1738*e4b17023SJohn Marino verify_rtl_sharing (); 1739*e4b17023SJohn Marino #endif 1740*e4b17023SJohn Marino 1741*e4b17023SJohn Marino cfun->last_verified = flags & TODO_verify_all; 1742*e4b17023SJohn Marino } 1743*e4b17023SJohn Marino 1744*e4b17023SJohn Marino /* Perform all TODO actions. */ 1745*e4b17023SJohn Marino static void 1746*e4b17023SJohn Marino execute_todo (unsigned int flags) 1747*e4b17023SJohn Marino { 1748*e4b17023SJohn Marino #if defined ENABLE_CHECKING 1749*e4b17023SJohn Marino if (cfun 1750*e4b17023SJohn Marino && need_ssa_update_p (cfun)) 1751*e4b17023SJohn Marino gcc_assert (flags & TODO_update_ssa_any); 1752*e4b17023SJohn Marino #endif 1753*e4b17023SJohn Marino 1754*e4b17023SJohn Marino timevar_push (TV_TODO); 1755*e4b17023SJohn Marino 1756*e4b17023SJohn Marino /* Inform the pass whether it is the first time it is run. */ 1757*e4b17023SJohn Marino first_pass_instance = (flags & TODO_mark_first_instance) != 0; 1758*e4b17023SJohn Marino 1759*e4b17023SJohn Marino statistics_fini_pass (); 1760*e4b17023SJohn Marino 1761*e4b17023SJohn Marino do_per_function (execute_function_todo, (void *)(size_t) flags); 1762*e4b17023SJohn Marino 1763*e4b17023SJohn Marino /* Always remove functions just as before inlining: IPA passes might be 1764*e4b17023SJohn Marino interested to see bodies of extern inline functions that are not inlined 1765*e4b17023SJohn Marino to analyze side effects. The full removal is done just at the end 1766*e4b17023SJohn Marino of IPA pass queue. */ 1767*e4b17023SJohn Marino if (flags & TODO_remove_functions) 1768*e4b17023SJohn Marino { 1769*e4b17023SJohn Marino gcc_assert (!cfun); 1770*e4b17023SJohn Marino cgraph_remove_unreachable_nodes (true, dump_file); 1771*e4b17023SJohn Marino } 1772*e4b17023SJohn Marino 1773*e4b17023SJohn Marino if ((flags & TODO_dump_cgraph) && dump_file && !current_function_decl) 1774*e4b17023SJohn Marino { 1775*e4b17023SJohn Marino gcc_assert (!cfun); 1776*e4b17023SJohn Marino dump_cgraph (dump_file); 1777*e4b17023SJohn Marino /* Flush the file. If verification fails, we won't be able to 1778*e4b17023SJohn Marino close the file before aborting. */ 1779*e4b17023SJohn Marino fflush (dump_file); 1780*e4b17023SJohn Marino } 1781*e4b17023SJohn Marino 1782*e4b17023SJohn Marino if (flags & TODO_ggc_collect) 1783*e4b17023SJohn Marino ggc_collect (); 1784*e4b17023SJohn Marino 1785*e4b17023SJohn Marino /* Now that the dumping has been done, we can get rid of the optional 1786*e4b17023SJohn Marino df problems. */ 1787*e4b17023SJohn Marino if (flags & TODO_df_finish) 1788*e4b17023SJohn Marino df_finish_pass ((flags & TODO_df_verify) != 0); 1789*e4b17023SJohn Marino 1790*e4b17023SJohn Marino timevar_pop (TV_TODO); 1791*e4b17023SJohn Marino } 1792*e4b17023SJohn Marino 1793*e4b17023SJohn Marino /* Verify invariants that should hold between passes. This is a place 1794*e4b17023SJohn Marino to put simple sanity checks. */ 1795*e4b17023SJohn Marino 1796*e4b17023SJohn Marino static void 1797*e4b17023SJohn Marino verify_interpass_invariants (void) 1798*e4b17023SJohn Marino { 1799*e4b17023SJohn Marino gcc_checking_assert (!fold_deferring_overflow_warnings_p ()); 1800*e4b17023SJohn Marino } 1801*e4b17023SJohn Marino 1802*e4b17023SJohn Marino /* Clear the last verified flag. */ 1803*e4b17023SJohn Marino 1804*e4b17023SJohn Marino static void 1805*e4b17023SJohn Marino clear_last_verified (void *data ATTRIBUTE_UNUSED) 1806*e4b17023SJohn Marino { 1807*e4b17023SJohn Marino cfun->last_verified = 0; 1808*e4b17023SJohn Marino } 1809*e4b17023SJohn Marino 1810*e4b17023SJohn Marino /* Helper function. Verify that the properties has been turn into the 1811*e4b17023SJohn Marino properties expected by the pass. */ 1812*e4b17023SJohn Marino 1813*e4b17023SJohn Marino #ifdef ENABLE_CHECKING 1814*e4b17023SJohn Marino static void 1815*e4b17023SJohn Marino verify_curr_properties (void *data) 1816*e4b17023SJohn Marino { 1817*e4b17023SJohn Marino unsigned int props = (size_t)data; 1818*e4b17023SJohn Marino gcc_assert ((cfun->curr_properties & props) == props); 1819*e4b17023SJohn Marino } 1820*e4b17023SJohn Marino #endif 1821*e4b17023SJohn Marino 1822*e4b17023SJohn Marino /* Initialize pass dump file. */ 1823*e4b17023SJohn Marino /* This is non-static so that the plugins can use it. */ 1824*e4b17023SJohn Marino 1825*e4b17023SJohn Marino bool 1826*e4b17023SJohn Marino pass_init_dump_file (struct opt_pass *pass) 1827*e4b17023SJohn Marino { 1828*e4b17023SJohn Marino /* If a dump file name is present, open it if enabled. */ 1829*e4b17023SJohn Marino if (pass->static_pass_number != -1) 1830*e4b17023SJohn Marino { 1831*e4b17023SJohn Marino bool initializing_dump = !dump_initialized_p (pass->static_pass_number); 1832*e4b17023SJohn Marino dump_file_name = get_dump_file_name (pass->static_pass_number); 1833*e4b17023SJohn Marino dump_file = dump_begin (pass->static_pass_number, &dump_flags); 1834*e4b17023SJohn Marino if (dump_file && current_function_decl) 1835*e4b17023SJohn Marino dump_function_header (dump_file, current_function_decl, dump_flags); 1836*e4b17023SJohn Marino return initializing_dump; 1837*e4b17023SJohn Marino } 1838*e4b17023SJohn Marino else 1839*e4b17023SJohn Marino return false; 1840*e4b17023SJohn Marino } 1841*e4b17023SJohn Marino 1842*e4b17023SJohn Marino /* Flush PASS dump file. */ 1843*e4b17023SJohn Marino /* This is non-static so that plugins can use it. */ 1844*e4b17023SJohn Marino 1845*e4b17023SJohn Marino void 1846*e4b17023SJohn Marino pass_fini_dump_file (struct opt_pass *pass) 1847*e4b17023SJohn Marino { 1848*e4b17023SJohn Marino /* Flush and close dump file. */ 1849*e4b17023SJohn Marino if (dump_file_name) 1850*e4b17023SJohn Marino { 1851*e4b17023SJohn Marino free (CONST_CAST (char *, dump_file_name)); 1852*e4b17023SJohn Marino dump_file_name = NULL; 1853*e4b17023SJohn Marino } 1854*e4b17023SJohn Marino 1855*e4b17023SJohn Marino if (dump_file) 1856*e4b17023SJohn Marino { 1857*e4b17023SJohn Marino dump_end (pass->static_pass_number, dump_file); 1858*e4b17023SJohn Marino dump_file = NULL; 1859*e4b17023SJohn Marino } 1860*e4b17023SJohn Marino } 1861*e4b17023SJohn Marino 1862*e4b17023SJohn Marino /* After executing the pass, apply expected changes to the function 1863*e4b17023SJohn Marino properties. */ 1864*e4b17023SJohn Marino 1865*e4b17023SJohn Marino static void 1866*e4b17023SJohn Marino update_properties_after_pass (void *data) 1867*e4b17023SJohn Marino { 1868*e4b17023SJohn Marino struct opt_pass *pass = (struct opt_pass *) data; 1869*e4b17023SJohn Marino cfun->curr_properties = (cfun->curr_properties | pass->properties_provided) 1870*e4b17023SJohn Marino & ~pass->properties_destroyed; 1871*e4b17023SJohn Marino } 1872*e4b17023SJohn Marino 1873*e4b17023SJohn Marino /* Execute summary generation for all of the passes in IPA_PASS. */ 1874*e4b17023SJohn Marino 1875*e4b17023SJohn Marino void 1876*e4b17023SJohn Marino execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass) 1877*e4b17023SJohn Marino { 1878*e4b17023SJohn Marino while (ipa_pass) 1879*e4b17023SJohn Marino { 1880*e4b17023SJohn Marino struct opt_pass *pass = &ipa_pass->pass; 1881*e4b17023SJohn Marino 1882*e4b17023SJohn Marino /* Execute all of the IPA_PASSes in the list. */ 1883*e4b17023SJohn Marino if (ipa_pass->pass.type == IPA_PASS 1884*e4b17023SJohn Marino && (!pass->gate || pass->gate ()) 1885*e4b17023SJohn Marino && ipa_pass->generate_summary) 1886*e4b17023SJohn Marino { 1887*e4b17023SJohn Marino pass_init_dump_file (pass); 1888*e4b17023SJohn Marino 1889*e4b17023SJohn Marino /* If a timevar is present, start it. */ 1890*e4b17023SJohn Marino if (pass->tv_id) 1891*e4b17023SJohn Marino timevar_push (pass->tv_id); 1892*e4b17023SJohn Marino 1893*e4b17023SJohn Marino ipa_pass->generate_summary (); 1894*e4b17023SJohn Marino 1895*e4b17023SJohn Marino /* Stop timevar. */ 1896*e4b17023SJohn Marino if (pass->tv_id) 1897*e4b17023SJohn Marino timevar_pop (pass->tv_id); 1898*e4b17023SJohn Marino 1899*e4b17023SJohn Marino pass_fini_dump_file (pass); 1900*e4b17023SJohn Marino } 1901*e4b17023SJohn Marino ipa_pass = (struct ipa_opt_pass_d *)ipa_pass->pass.next; 1902*e4b17023SJohn Marino } 1903*e4b17023SJohn Marino } 1904*e4b17023SJohn Marino 1905*e4b17023SJohn Marino /* Execute IPA_PASS function transform on NODE. */ 1906*e4b17023SJohn Marino 1907*e4b17023SJohn Marino static void 1908*e4b17023SJohn Marino execute_one_ipa_transform_pass (struct cgraph_node *node, 1909*e4b17023SJohn Marino struct ipa_opt_pass_d *ipa_pass) 1910*e4b17023SJohn Marino { 1911*e4b17023SJohn Marino struct opt_pass *pass = &ipa_pass->pass; 1912*e4b17023SJohn Marino unsigned int todo_after = 0; 1913*e4b17023SJohn Marino 1914*e4b17023SJohn Marino current_pass = pass; 1915*e4b17023SJohn Marino if (!ipa_pass->function_transform) 1916*e4b17023SJohn Marino return; 1917*e4b17023SJohn Marino 1918*e4b17023SJohn Marino /* Note that the folders should only create gimple expressions. 1919*e4b17023SJohn Marino This is a hack until the new folder is ready. */ 1920*e4b17023SJohn Marino in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0; 1921*e4b17023SJohn Marino 1922*e4b17023SJohn Marino pass_init_dump_file (pass); 1923*e4b17023SJohn Marino 1924*e4b17023SJohn Marino /* Run pre-pass verification. */ 1925*e4b17023SJohn Marino execute_todo (ipa_pass->function_transform_todo_flags_start); 1926*e4b17023SJohn Marino 1927*e4b17023SJohn Marino /* If a timevar is present, start it. */ 1928*e4b17023SJohn Marino if (pass->tv_id != TV_NONE) 1929*e4b17023SJohn Marino timevar_push (pass->tv_id); 1930*e4b17023SJohn Marino 1931*e4b17023SJohn Marino /* Do it! */ 1932*e4b17023SJohn Marino todo_after = ipa_pass->function_transform (node); 1933*e4b17023SJohn Marino 1934*e4b17023SJohn Marino /* Stop timevar. */ 1935*e4b17023SJohn Marino if (pass->tv_id != TV_NONE) 1936*e4b17023SJohn Marino timevar_pop (pass->tv_id); 1937*e4b17023SJohn Marino 1938*e4b17023SJohn Marino /* Run post-pass cleanup and verification. */ 1939*e4b17023SJohn Marino execute_todo (todo_after); 1940*e4b17023SJohn Marino verify_interpass_invariants (); 1941*e4b17023SJohn Marino 1942*e4b17023SJohn Marino do_per_function (execute_function_dump, NULL); 1943*e4b17023SJohn Marino pass_fini_dump_file (pass); 1944*e4b17023SJohn Marino 1945*e4b17023SJohn Marino current_pass = NULL; 1946*e4b17023SJohn Marino } 1947*e4b17023SJohn Marino 1948*e4b17023SJohn Marino /* For the current function, execute all ipa transforms. */ 1949*e4b17023SJohn Marino 1950*e4b17023SJohn Marino void 1951*e4b17023SJohn Marino execute_all_ipa_transforms (void) 1952*e4b17023SJohn Marino { 1953*e4b17023SJohn Marino struct cgraph_node *node; 1954*e4b17023SJohn Marino if (!cfun) 1955*e4b17023SJohn Marino return; 1956*e4b17023SJohn Marino node = cgraph_get_node (current_function_decl); 1957*e4b17023SJohn Marino 1958*e4b17023SJohn Marino if (node->ipa_transforms_to_apply) 1959*e4b17023SJohn Marino { 1960*e4b17023SJohn Marino unsigned int i; 1961*e4b17023SJohn Marino 1962*e4b17023SJohn Marino for (i = 0; i < VEC_length (ipa_opt_pass, node->ipa_transforms_to_apply); 1963*e4b17023SJohn Marino i++) 1964*e4b17023SJohn Marino execute_one_ipa_transform_pass (node, 1965*e4b17023SJohn Marino VEC_index (ipa_opt_pass, 1966*e4b17023SJohn Marino node->ipa_transforms_to_apply, 1967*e4b17023SJohn Marino i)); 1968*e4b17023SJohn Marino VEC_free (ipa_opt_pass, heap, node->ipa_transforms_to_apply); 1969*e4b17023SJohn Marino node->ipa_transforms_to_apply = NULL; 1970*e4b17023SJohn Marino } 1971*e4b17023SJohn Marino } 1972*e4b17023SJohn Marino 1973*e4b17023SJohn Marino /* Callback for do_per_function to apply all IPA transforms. */ 1974*e4b17023SJohn Marino 1975*e4b17023SJohn Marino static void 1976*e4b17023SJohn Marino apply_ipa_transforms (void *data) 1977*e4b17023SJohn Marino { 1978*e4b17023SJohn Marino struct cgraph_node *node = cgraph_get_node (current_function_decl); 1979*e4b17023SJohn Marino if (!node->global.inlined_to && node->ipa_transforms_to_apply) 1980*e4b17023SJohn Marino { 1981*e4b17023SJohn Marino *(bool *)data = true; 1982*e4b17023SJohn Marino execute_all_ipa_transforms(); 1983*e4b17023SJohn Marino rebuild_cgraph_edges (); 1984*e4b17023SJohn Marino } 1985*e4b17023SJohn Marino } 1986*e4b17023SJohn Marino 1987*e4b17023SJohn Marino /* Check if PASS is explicitly disabled or enabled and return 1988*e4b17023SJohn Marino the gate status. FUNC is the function to be processed, and 1989*e4b17023SJohn Marino GATE_STATUS is the gate status determined by pass manager by 1990*e4b17023SJohn Marino default. */ 1991*e4b17023SJohn Marino 1992*e4b17023SJohn Marino static bool 1993*e4b17023SJohn Marino override_gate_status (struct opt_pass *pass, tree func, bool gate_status) 1994*e4b17023SJohn Marino { 1995*e4b17023SJohn Marino bool explicitly_enabled = false; 1996*e4b17023SJohn Marino bool explicitly_disabled = false; 1997*e4b17023SJohn Marino 1998*e4b17023SJohn Marino explicitly_enabled 1999*e4b17023SJohn Marino = is_pass_explicitly_enabled_or_disabled (pass, func, 2000*e4b17023SJohn Marino enabled_pass_uid_range_tab); 2001*e4b17023SJohn Marino explicitly_disabled 2002*e4b17023SJohn Marino = is_pass_explicitly_enabled_or_disabled (pass, func, 2003*e4b17023SJohn Marino disabled_pass_uid_range_tab); 2004*e4b17023SJohn Marino 2005*e4b17023SJohn Marino gate_status = !explicitly_disabled && (gate_status || explicitly_enabled); 2006*e4b17023SJohn Marino 2007*e4b17023SJohn Marino return gate_status; 2008*e4b17023SJohn Marino } 2009*e4b17023SJohn Marino 2010*e4b17023SJohn Marino 2011*e4b17023SJohn Marino /* Execute PASS. */ 2012*e4b17023SJohn Marino 2013*e4b17023SJohn Marino bool 2014*e4b17023SJohn Marino execute_one_pass (struct opt_pass *pass) 2015*e4b17023SJohn Marino { 2016*e4b17023SJohn Marino bool initializing_dump; 2017*e4b17023SJohn Marino unsigned int todo_after = 0; 2018*e4b17023SJohn Marino 2019*e4b17023SJohn Marino bool gate_status; 2020*e4b17023SJohn Marino 2021*e4b17023SJohn Marino /* IPA passes are executed on whole program, so cfun should be NULL. 2022*e4b17023SJohn Marino Other passes need function context set. */ 2023*e4b17023SJohn Marino if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS) 2024*e4b17023SJohn Marino gcc_assert (!cfun && !current_function_decl); 2025*e4b17023SJohn Marino else 2026*e4b17023SJohn Marino gcc_assert (cfun && current_function_decl); 2027*e4b17023SJohn Marino 2028*e4b17023SJohn Marino current_pass = pass; 2029*e4b17023SJohn Marino 2030*e4b17023SJohn Marino /* Check whether gate check should be avoided. 2031*e4b17023SJohn Marino User controls the value of the gate through the parameter "gate_status". */ 2032*e4b17023SJohn Marino gate_status = (pass->gate == NULL) ? true : pass->gate(); 2033*e4b17023SJohn Marino gate_status = override_gate_status (pass, current_function_decl, gate_status); 2034*e4b17023SJohn Marino 2035*e4b17023SJohn Marino /* Override gate with plugin. */ 2036*e4b17023SJohn Marino invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status); 2037*e4b17023SJohn Marino 2038*e4b17023SJohn Marino if (!gate_status) 2039*e4b17023SJohn Marino { 2040*e4b17023SJohn Marino current_pass = NULL; 2041*e4b17023SJohn Marino return false; 2042*e4b17023SJohn Marino } 2043*e4b17023SJohn Marino 2044*e4b17023SJohn Marino /* Pass execution event trigger: useful to identify passes being 2045*e4b17023SJohn Marino executed. */ 2046*e4b17023SJohn Marino invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass); 2047*e4b17023SJohn Marino 2048*e4b17023SJohn Marino /* SIPLE IPA passes do not handle callgraphs with IPA transforms in it. 2049*e4b17023SJohn Marino Apply all trnasforms first. */ 2050*e4b17023SJohn Marino if (pass->type == SIMPLE_IPA_PASS) 2051*e4b17023SJohn Marino { 2052*e4b17023SJohn Marino bool applied = false; 2053*e4b17023SJohn Marino do_per_function (apply_ipa_transforms, (void *)&applied); 2054*e4b17023SJohn Marino if (applied) 2055*e4b17023SJohn Marino cgraph_remove_unreachable_nodes (true, dump_file); 2056*e4b17023SJohn Marino /* Restore current_pass. */ 2057*e4b17023SJohn Marino current_pass = pass; 2058*e4b17023SJohn Marino } 2059*e4b17023SJohn Marino 2060*e4b17023SJohn Marino if (!quiet_flag && !cfun) 2061*e4b17023SJohn Marino fprintf (stderr, " <%s>", pass->name ? pass->name : ""); 2062*e4b17023SJohn Marino 2063*e4b17023SJohn Marino /* Note that the folders should only create gimple expressions. 2064*e4b17023SJohn Marino This is a hack until the new folder is ready. */ 2065*e4b17023SJohn Marino in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0; 2066*e4b17023SJohn Marino 2067*e4b17023SJohn Marino initializing_dump = pass_init_dump_file (pass); 2068*e4b17023SJohn Marino 2069*e4b17023SJohn Marino /* Run pre-pass verification. */ 2070*e4b17023SJohn Marino execute_todo (pass->todo_flags_start); 2071*e4b17023SJohn Marino 2072*e4b17023SJohn Marino #ifdef ENABLE_CHECKING 2073*e4b17023SJohn Marino do_per_function (verify_curr_properties, 2074*e4b17023SJohn Marino (void *)(size_t)pass->properties_required); 2075*e4b17023SJohn Marino #endif 2076*e4b17023SJohn Marino 2077*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2078*e4b17023SJohn Marino if (pass->tv_id != TV_NONE) 2079*e4b17023SJohn Marino timevar_push (pass->tv_id); 2080*e4b17023SJohn Marino 2081*e4b17023SJohn Marino /* Do it! */ 2082*e4b17023SJohn Marino if (pass->execute) 2083*e4b17023SJohn Marino { 2084*e4b17023SJohn Marino todo_after = pass->execute (); 2085*e4b17023SJohn Marino do_per_function (clear_last_verified, NULL); 2086*e4b17023SJohn Marino } 2087*e4b17023SJohn Marino 2088*e4b17023SJohn Marino /* Stop timevar. */ 2089*e4b17023SJohn Marino if (pass->tv_id != TV_NONE) 2090*e4b17023SJohn Marino timevar_pop (pass->tv_id); 2091*e4b17023SJohn Marino 2092*e4b17023SJohn Marino do_per_function (update_properties_after_pass, pass); 2093*e4b17023SJohn Marino 2094*e4b17023SJohn Marino if (initializing_dump 2095*e4b17023SJohn Marino && dump_file 2096*e4b17023SJohn Marino && graph_dump_format != no_graph 2097*e4b17023SJohn Marino && cfun 2098*e4b17023SJohn Marino && (cfun->curr_properties & (PROP_cfg | PROP_rtl)) 2099*e4b17023SJohn Marino == (PROP_cfg | PROP_rtl)) 2100*e4b17023SJohn Marino { 2101*e4b17023SJohn Marino get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH; 2102*e4b17023SJohn Marino dump_flags |= TDF_GRAPH; 2103*e4b17023SJohn Marino clean_graph_dump_file (dump_file_name); 2104*e4b17023SJohn Marino } 2105*e4b17023SJohn Marino 2106*e4b17023SJohn Marino /* Run post-pass cleanup and verification. */ 2107*e4b17023SJohn Marino execute_todo (todo_after | pass->todo_flags_finish); 2108*e4b17023SJohn Marino verify_interpass_invariants (); 2109*e4b17023SJohn Marino do_per_function (execute_function_dump, NULL); 2110*e4b17023SJohn Marino if (pass->type == IPA_PASS) 2111*e4b17023SJohn Marino { 2112*e4b17023SJohn Marino struct cgraph_node *node; 2113*e4b17023SJohn Marino FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 2114*e4b17023SJohn Marino VEC_safe_push (ipa_opt_pass, heap, node->ipa_transforms_to_apply, 2115*e4b17023SJohn Marino (struct ipa_opt_pass_d *)pass); 2116*e4b17023SJohn Marino } 2117*e4b17023SJohn Marino 2118*e4b17023SJohn Marino if (!current_function_decl) 2119*e4b17023SJohn Marino cgraph_process_new_functions (); 2120*e4b17023SJohn Marino 2121*e4b17023SJohn Marino pass_fini_dump_file (pass); 2122*e4b17023SJohn Marino 2123*e4b17023SJohn Marino if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS) 2124*e4b17023SJohn Marino gcc_assert (!(cfun->curr_properties & PROP_trees) 2125*e4b17023SJohn Marino || pass->type != RTL_PASS); 2126*e4b17023SJohn Marino 2127*e4b17023SJohn Marino current_pass = NULL; 2128*e4b17023SJohn Marino 2129*e4b17023SJohn Marino return true; 2130*e4b17023SJohn Marino } 2131*e4b17023SJohn Marino 2132*e4b17023SJohn Marino void 2133*e4b17023SJohn Marino execute_pass_list (struct opt_pass *pass) 2134*e4b17023SJohn Marino { 2135*e4b17023SJohn Marino do 2136*e4b17023SJohn Marino { 2137*e4b17023SJohn Marino gcc_assert (pass->type == GIMPLE_PASS 2138*e4b17023SJohn Marino || pass->type == RTL_PASS); 2139*e4b17023SJohn Marino if (execute_one_pass (pass) && pass->sub) 2140*e4b17023SJohn Marino execute_pass_list (pass->sub); 2141*e4b17023SJohn Marino pass = pass->next; 2142*e4b17023SJohn Marino } 2143*e4b17023SJohn Marino while (pass); 2144*e4b17023SJohn Marino } 2145*e4b17023SJohn Marino 2146*e4b17023SJohn Marino /* Same as execute_pass_list but assume that subpasses of IPA passes 2147*e4b17023SJohn Marino are local passes. If SET is not NULL, write out summaries of only 2148*e4b17023SJohn Marino those node in SET. */ 2149*e4b17023SJohn Marino 2150*e4b17023SJohn Marino static void 2151*e4b17023SJohn Marino ipa_write_summaries_2 (struct opt_pass *pass, cgraph_node_set set, 2152*e4b17023SJohn Marino varpool_node_set vset, 2153*e4b17023SJohn Marino struct lto_out_decl_state *state) 2154*e4b17023SJohn Marino { 2155*e4b17023SJohn Marino while (pass) 2156*e4b17023SJohn Marino { 2157*e4b17023SJohn Marino struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *)pass; 2158*e4b17023SJohn Marino gcc_assert (!current_function_decl); 2159*e4b17023SJohn Marino gcc_assert (!cfun); 2160*e4b17023SJohn Marino gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); 2161*e4b17023SJohn Marino if (pass->type == IPA_PASS 2162*e4b17023SJohn Marino && ipa_pass->write_summary 2163*e4b17023SJohn Marino && (!pass->gate || pass->gate ())) 2164*e4b17023SJohn Marino { 2165*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2166*e4b17023SJohn Marino if (pass->tv_id) 2167*e4b17023SJohn Marino timevar_push (pass->tv_id); 2168*e4b17023SJohn Marino 2169*e4b17023SJohn Marino pass_init_dump_file (pass); 2170*e4b17023SJohn Marino 2171*e4b17023SJohn Marino ipa_pass->write_summary (set,vset); 2172*e4b17023SJohn Marino 2173*e4b17023SJohn Marino pass_fini_dump_file (pass); 2174*e4b17023SJohn Marino 2175*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2176*e4b17023SJohn Marino if (pass->tv_id) 2177*e4b17023SJohn Marino timevar_pop (pass->tv_id); 2178*e4b17023SJohn Marino } 2179*e4b17023SJohn Marino 2180*e4b17023SJohn Marino if (pass->sub && pass->sub->type != GIMPLE_PASS) 2181*e4b17023SJohn Marino ipa_write_summaries_2 (pass->sub, set, vset, state); 2182*e4b17023SJohn Marino 2183*e4b17023SJohn Marino pass = pass->next; 2184*e4b17023SJohn Marino } 2185*e4b17023SJohn Marino } 2186*e4b17023SJohn Marino 2187*e4b17023SJohn Marino /* Helper function of ipa_write_summaries. Creates and destroys the 2188*e4b17023SJohn Marino decl state and calls ipa_write_summaries_2 for all passes that have 2189*e4b17023SJohn Marino summaries. SET is the set of nodes to be written. */ 2190*e4b17023SJohn Marino 2191*e4b17023SJohn Marino static void 2192*e4b17023SJohn Marino ipa_write_summaries_1 (cgraph_node_set set, varpool_node_set vset) 2193*e4b17023SJohn Marino { 2194*e4b17023SJohn Marino struct lto_out_decl_state *state = lto_new_out_decl_state (); 2195*e4b17023SJohn Marino compute_ltrans_boundary (state, set, vset); 2196*e4b17023SJohn Marino 2197*e4b17023SJohn Marino lto_push_out_decl_state (state); 2198*e4b17023SJohn Marino 2199*e4b17023SJohn Marino gcc_assert (!flag_wpa); 2200*e4b17023SJohn Marino ipa_write_summaries_2 (all_regular_ipa_passes, set, vset, state); 2201*e4b17023SJohn Marino ipa_write_summaries_2 (all_lto_gen_passes, set, vset, state); 2202*e4b17023SJohn Marino 2203*e4b17023SJohn Marino gcc_assert (lto_get_out_decl_state () == state); 2204*e4b17023SJohn Marino lto_pop_out_decl_state (); 2205*e4b17023SJohn Marino lto_delete_out_decl_state (state); 2206*e4b17023SJohn Marino } 2207*e4b17023SJohn Marino 2208*e4b17023SJohn Marino /* Write out summaries for all the nodes in the callgraph. */ 2209*e4b17023SJohn Marino 2210*e4b17023SJohn Marino void 2211*e4b17023SJohn Marino ipa_write_summaries (void) 2212*e4b17023SJohn Marino { 2213*e4b17023SJohn Marino cgraph_node_set set; 2214*e4b17023SJohn Marino varpool_node_set vset; 2215*e4b17023SJohn Marino struct cgraph_node **order; 2216*e4b17023SJohn Marino struct varpool_node *vnode; 2217*e4b17023SJohn Marino int i, order_pos; 2218*e4b17023SJohn Marino 2219*e4b17023SJohn Marino if (!flag_generate_lto || seen_error ()) 2220*e4b17023SJohn Marino return; 2221*e4b17023SJohn Marino 2222*e4b17023SJohn Marino set = cgraph_node_set_new (); 2223*e4b17023SJohn Marino 2224*e4b17023SJohn Marino /* Create the callgraph set in the same order used in 2225*e4b17023SJohn Marino cgraph_expand_all_functions. This mostly facilitates debugging, 2226*e4b17023SJohn Marino since it causes the gimple file to be processed in the same order 2227*e4b17023SJohn Marino as the source code. */ 2228*e4b17023SJohn Marino order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); 2229*e4b17023SJohn Marino order_pos = ipa_reverse_postorder (order); 2230*e4b17023SJohn Marino gcc_assert (order_pos == cgraph_n_nodes); 2231*e4b17023SJohn Marino 2232*e4b17023SJohn Marino for (i = order_pos - 1; i >= 0; i--) 2233*e4b17023SJohn Marino { 2234*e4b17023SJohn Marino struct cgraph_node *node = order[i]; 2235*e4b17023SJohn Marino 2236*e4b17023SJohn Marino if (cgraph_function_with_gimple_body_p (node)) 2237*e4b17023SJohn Marino { 2238*e4b17023SJohn Marino /* When streaming out references to statements as part of some IPA 2239*e4b17023SJohn Marino pass summary, the statements need to have uids assigned and the 2240*e4b17023SJohn Marino following does that for all the IPA passes here. Naturally, this 2241*e4b17023SJohn Marino ordering then matches the one IPA-passes get in their stmt_fixup 2242*e4b17023SJohn Marino hooks. */ 2243*e4b17023SJohn Marino 2244*e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 2245*e4b17023SJohn Marino renumber_gimple_stmt_uids (); 2246*e4b17023SJohn Marino pop_cfun (); 2247*e4b17023SJohn Marino } 2248*e4b17023SJohn Marino if (node->analyzed) 2249*e4b17023SJohn Marino cgraph_node_set_add (set, node); 2250*e4b17023SJohn Marino } 2251*e4b17023SJohn Marino vset = varpool_node_set_new (); 2252*e4b17023SJohn Marino 2253*e4b17023SJohn Marino for (vnode = varpool_nodes; vnode; vnode = vnode->next) 2254*e4b17023SJohn Marino if (vnode->needed && (!vnode->alias || vnode->alias_of)) 2255*e4b17023SJohn Marino varpool_node_set_add (vset, vnode); 2256*e4b17023SJohn Marino 2257*e4b17023SJohn Marino ipa_write_summaries_1 (set, vset); 2258*e4b17023SJohn Marino 2259*e4b17023SJohn Marino free (order); 2260*e4b17023SJohn Marino free_cgraph_node_set (set); 2261*e4b17023SJohn Marino free_varpool_node_set (vset); 2262*e4b17023SJohn Marino } 2263*e4b17023SJohn Marino 2264*e4b17023SJohn Marino /* Same as execute_pass_list but assume that subpasses of IPA passes 2265*e4b17023SJohn Marino are local passes. If SET is not NULL, write out optimization summaries of 2266*e4b17023SJohn Marino only those node in SET. */ 2267*e4b17023SJohn Marino 2268*e4b17023SJohn Marino static void 2269*e4b17023SJohn Marino ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set, 2270*e4b17023SJohn Marino varpool_node_set vset, 2271*e4b17023SJohn Marino struct lto_out_decl_state *state) 2272*e4b17023SJohn Marino { 2273*e4b17023SJohn Marino while (pass) 2274*e4b17023SJohn Marino { 2275*e4b17023SJohn Marino struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *)pass; 2276*e4b17023SJohn Marino gcc_assert (!current_function_decl); 2277*e4b17023SJohn Marino gcc_assert (!cfun); 2278*e4b17023SJohn Marino gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); 2279*e4b17023SJohn Marino if (pass->type == IPA_PASS 2280*e4b17023SJohn Marino && ipa_pass->write_optimization_summary 2281*e4b17023SJohn Marino && (!pass->gate || pass->gate ())) 2282*e4b17023SJohn Marino { 2283*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2284*e4b17023SJohn Marino if (pass->tv_id) 2285*e4b17023SJohn Marino timevar_push (pass->tv_id); 2286*e4b17023SJohn Marino 2287*e4b17023SJohn Marino pass_init_dump_file (pass); 2288*e4b17023SJohn Marino 2289*e4b17023SJohn Marino ipa_pass->write_optimization_summary (set, vset); 2290*e4b17023SJohn Marino 2291*e4b17023SJohn Marino pass_fini_dump_file (pass); 2292*e4b17023SJohn Marino 2293*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2294*e4b17023SJohn Marino if (pass->tv_id) 2295*e4b17023SJohn Marino timevar_pop (pass->tv_id); 2296*e4b17023SJohn Marino } 2297*e4b17023SJohn Marino 2298*e4b17023SJohn Marino if (pass->sub && pass->sub->type != GIMPLE_PASS) 2299*e4b17023SJohn Marino ipa_write_optimization_summaries_1 (pass->sub, set, vset, state); 2300*e4b17023SJohn Marino 2301*e4b17023SJohn Marino pass = pass->next; 2302*e4b17023SJohn Marino } 2303*e4b17023SJohn Marino } 2304*e4b17023SJohn Marino 2305*e4b17023SJohn Marino /* Write all the optimization summaries for the cgraph nodes in SET. If SET is 2306*e4b17023SJohn Marino NULL, write out all summaries of all nodes. */ 2307*e4b17023SJohn Marino 2308*e4b17023SJohn Marino void 2309*e4b17023SJohn Marino ipa_write_optimization_summaries (cgraph_node_set set, varpool_node_set vset) 2310*e4b17023SJohn Marino { 2311*e4b17023SJohn Marino struct lto_out_decl_state *state = lto_new_out_decl_state (); 2312*e4b17023SJohn Marino cgraph_node_set_iterator csi; 2313*e4b17023SJohn Marino compute_ltrans_boundary (state, set, vset); 2314*e4b17023SJohn Marino 2315*e4b17023SJohn Marino lto_push_out_decl_state (state); 2316*e4b17023SJohn Marino for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) 2317*e4b17023SJohn Marino { 2318*e4b17023SJohn Marino struct cgraph_node *node = csi_node (csi); 2319*e4b17023SJohn Marino /* When streaming out references to statements as part of some IPA 2320*e4b17023SJohn Marino pass summary, the statements need to have uids assigned. 2321*e4b17023SJohn Marino 2322*e4b17023SJohn Marino For functions newly born at WPA stage we need to initialize 2323*e4b17023SJohn Marino the uids here. */ 2324*e4b17023SJohn Marino if (node->analyzed 2325*e4b17023SJohn Marino && gimple_has_body_p (node->decl)) 2326*e4b17023SJohn Marino { 2327*e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 2328*e4b17023SJohn Marino renumber_gimple_stmt_uids (); 2329*e4b17023SJohn Marino pop_cfun (); 2330*e4b17023SJohn Marino } 2331*e4b17023SJohn Marino } 2332*e4b17023SJohn Marino 2333*e4b17023SJohn Marino gcc_assert (flag_wpa); 2334*e4b17023SJohn Marino ipa_write_optimization_summaries_1 (all_regular_ipa_passes, set, vset, state); 2335*e4b17023SJohn Marino ipa_write_optimization_summaries_1 (all_lto_gen_passes, set, vset, state); 2336*e4b17023SJohn Marino 2337*e4b17023SJohn Marino gcc_assert (lto_get_out_decl_state () == state); 2338*e4b17023SJohn Marino lto_pop_out_decl_state (); 2339*e4b17023SJohn Marino lto_delete_out_decl_state (state); 2340*e4b17023SJohn Marino } 2341*e4b17023SJohn Marino 2342*e4b17023SJohn Marino /* Same as execute_pass_list but assume that subpasses of IPA passes 2343*e4b17023SJohn Marino are local passes. */ 2344*e4b17023SJohn Marino 2345*e4b17023SJohn Marino static void 2346*e4b17023SJohn Marino ipa_read_summaries_1 (struct opt_pass *pass) 2347*e4b17023SJohn Marino { 2348*e4b17023SJohn Marino while (pass) 2349*e4b17023SJohn Marino { 2350*e4b17023SJohn Marino struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass; 2351*e4b17023SJohn Marino 2352*e4b17023SJohn Marino gcc_assert (!current_function_decl); 2353*e4b17023SJohn Marino gcc_assert (!cfun); 2354*e4b17023SJohn Marino gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); 2355*e4b17023SJohn Marino 2356*e4b17023SJohn Marino if (pass->gate == NULL || pass->gate ()) 2357*e4b17023SJohn Marino { 2358*e4b17023SJohn Marino if (pass->type == IPA_PASS && ipa_pass->read_summary) 2359*e4b17023SJohn Marino { 2360*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2361*e4b17023SJohn Marino if (pass->tv_id) 2362*e4b17023SJohn Marino timevar_push (pass->tv_id); 2363*e4b17023SJohn Marino 2364*e4b17023SJohn Marino pass_init_dump_file (pass); 2365*e4b17023SJohn Marino 2366*e4b17023SJohn Marino ipa_pass->read_summary (); 2367*e4b17023SJohn Marino 2368*e4b17023SJohn Marino pass_fini_dump_file (pass); 2369*e4b17023SJohn Marino 2370*e4b17023SJohn Marino /* Stop timevar. */ 2371*e4b17023SJohn Marino if (pass->tv_id) 2372*e4b17023SJohn Marino timevar_pop (pass->tv_id); 2373*e4b17023SJohn Marino } 2374*e4b17023SJohn Marino 2375*e4b17023SJohn Marino if (pass->sub && pass->sub->type != GIMPLE_PASS) 2376*e4b17023SJohn Marino ipa_read_summaries_1 (pass->sub); 2377*e4b17023SJohn Marino } 2378*e4b17023SJohn Marino pass = pass->next; 2379*e4b17023SJohn Marino } 2380*e4b17023SJohn Marino } 2381*e4b17023SJohn Marino 2382*e4b17023SJohn Marino 2383*e4b17023SJohn Marino /* Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes. */ 2384*e4b17023SJohn Marino 2385*e4b17023SJohn Marino void 2386*e4b17023SJohn Marino ipa_read_summaries (void) 2387*e4b17023SJohn Marino { 2388*e4b17023SJohn Marino ipa_read_summaries_1 (all_regular_ipa_passes); 2389*e4b17023SJohn Marino ipa_read_summaries_1 (all_lto_gen_passes); 2390*e4b17023SJohn Marino } 2391*e4b17023SJohn Marino 2392*e4b17023SJohn Marino /* Same as execute_pass_list but assume that subpasses of IPA passes 2393*e4b17023SJohn Marino are local passes. */ 2394*e4b17023SJohn Marino 2395*e4b17023SJohn Marino static void 2396*e4b17023SJohn Marino ipa_read_optimization_summaries_1 (struct opt_pass *pass) 2397*e4b17023SJohn Marino { 2398*e4b17023SJohn Marino while (pass) 2399*e4b17023SJohn Marino { 2400*e4b17023SJohn Marino struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass; 2401*e4b17023SJohn Marino 2402*e4b17023SJohn Marino gcc_assert (!current_function_decl); 2403*e4b17023SJohn Marino gcc_assert (!cfun); 2404*e4b17023SJohn Marino gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); 2405*e4b17023SJohn Marino 2406*e4b17023SJohn Marino if (pass->gate == NULL || pass->gate ()) 2407*e4b17023SJohn Marino { 2408*e4b17023SJohn Marino if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary) 2409*e4b17023SJohn Marino { 2410*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2411*e4b17023SJohn Marino if (pass->tv_id) 2412*e4b17023SJohn Marino timevar_push (pass->tv_id); 2413*e4b17023SJohn Marino 2414*e4b17023SJohn Marino pass_init_dump_file (pass); 2415*e4b17023SJohn Marino 2416*e4b17023SJohn Marino ipa_pass->read_optimization_summary (); 2417*e4b17023SJohn Marino 2418*e4b17023SJohn Marino pass_fini_dump_file (pass); 2419*e4b17023SJohn Marino 2420*e4b17023SJohn Marino /* Stop timevar. */ 2421*e4b17023SJohn Marino if (pass->tv_id) 2422*e4b17023SJohn Marino timevar_pop (pass->tv_id); 2423*e4b17023SJohn Marino } 2424*e4b17023SJohn Marino 2425*e4b17023SJohn Marino if (pass->sub && pass->sub->type != GIMPLE_PASS) 2426*e4b17023SJohn Marino ipa_read_optimization_summaries_1 (pass->sub); 2427*e4b17023SJohn Marino } 2428*e4b17023SJohn Marino pass = pass->next; 2429*e4b17023SJohn Marino } 2430*e4b17023SJohn Marino } 2431*e4b17023SJohn Marino 2432*e4b17023SJohn Marino /* Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes. */ 2433*e4b17023SJohn Marino 2434*e4b17023SJohn Marino void 2435*e4b17023SJohn Marino ipa_read_optimization_summaries (void) 2436*e4b17023SJohn Marino { 2437*e4b17023SJohn Marino ipa_read_optimization_summaries_1 (all_regular_ipa_passes); 2438*e4b17023SJohn Marino ipa_read_optimization_summaries_1 (all_lto_gen_passes); 2439*e4b17023SJohn Marino } 2440*e4b17023SJohn Marino 2441*e4b17023SJohn Marino /* Same as execute_pass_list but assume that subpasses of IPA passes 2442*e4b17023SJohn Marino are local passes. */ 2443*e4b17023SJohn Marino void 2444*e4b17023SJohn Marino execute_ipa_pass_list (struct opt_pass *pass) 2445*e4b17023SJohn Marino { 2446*e4b17023SJohn Marino do 2447*e4b17023SJohn Marino { 2448*e4b17023SJohn Marino gcc_assert (!current_function_decl); 2449*e4b17023SJohn Marino gcc_assert (!cfun); 2450*e4b17023SJohn Marino gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); 2451*e4b17023SJohn Marino if (execute_one_pass (pass) && pass->sub) 2452*e4b17023SJohn Marino { 2453*e4b17023SJohn Marino if (pass->sub->type == GIMPLE_PASS) 2454*e4b17023SJohn Marino { 2455*e4b17023SJohn Marino invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL); 2456*e4b17023SJohn Marino do_per_function_toporder ((void (*)(void *))execute_pass_list, 2457*e4b17023SJohn Marino pass->sub); 2458*e4b17023SJohn Marino invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL); 2459*e4b17023SJohn Marino } 2460*e4b17023SJohn Marino else if (pass->sub->type == SIMPLE_IPA_PASS 2461*e4b17023SJohn Marino || pass->sub->type == IPA_PASS) 2462*e4b17023SJohn Marino execute_ipa_pass_list (pass->sub); 2463*e4b17023SJohn Marino else 2464*e4b17023SJohn Marino gcc_unreachable (); 2465*e4b17023SJohn Marino } 2466*e4b17023SJohn Marino gcc_assert (!current_function_decl); 2467*e4b17023SJohn Marino cgraph_process_new_functions (); 2468*e4b17023SJohn Marino pass = pass->next; 2469*e4b17023SJohn Marino } 2470*e4b17023SJohn Marino while (pass); 2471*e4b17023SJohn Marino } 2472*e4b17023SJohn Marino 2473*e4b17023SJohn Marino /* Execute stmt fixup hooks of all passes in PASS for NODE and STMTS. */ 2474*e4b17023SJohn Marino 2475*e4b17023SJohn Marino static void 2476*e4b17023SJohn Marino execute_ipa_stmt_fixups (struct opt_pass *pass, 2477*e4b17023SJohn Marino struct cgraph_node *node, gimple *stmts) 2478*e4b17023SJohn Marino { 2479*e4b17023SJohn Marino while (pass) 2480*e4b17023SJohn Marino { 2481*e4b17023SJohn Marino /* Execute all of the IPA_PASSes in the list. */ 2482*e4b17023SJohn Marino if (pass->type == IPA_PASS 2483*e4b17023SJohn Marino && (!pass->gate || pass->gate ())) 2484*e4b17023SJohn Marino { 2485*e4b17023SJohn Marino struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass; 2486*e4b17023SJohn Marino 2487*e4b17023SJohn Marino if (ipa_pass->stmt_fixup) 2488*e4b17023SJohn Marino { 2489*e4b17023SJohn Marino pass_init_dump_file (pass); 2490*e4b17023SJohn Marino /* If a timevar is present, start it. */ 2491*e4b17023SJohn Marino if (pass->tv_id) 2492*e4b17023SJohn Marino timevar_push (pass->tv_id); 2493*e4b17023SJohn Marino 2494*e4b17023SJohn Marino ipa_pass->stmt_fixup (node, stmts); 2495*e4b17023SJohn Marino 2496*e4b17023SJohn Marino /* Stop timevar. */ 2497*e4b17023SJohn Marino if (pass->tv_id) 2498*e4b17023SJohn Marino timevar_pop (pass->tv_id); 2499*e4b17023SJohn Marino pass_fini_dump_file (pass); 2500*e4b17023SJohn Marino } 2501*e4b17023SJohn Marino if (pass->sub) 2502*e4b17023SJohn Marino execute_ipa_stmt_fixups (pass->sub, node, stmts); 2503*e4b17023SJohn Marino } 2504*e4b17023SJohn Marino pass = pass->next; 2505*e4b17023SJohn Marino } 2506*e4b17023SJohn Marino } 2507*e4b17023SJohn Marino 2508*e4b17023SJohn Marino /* Execute stmt fixup hooks of all IPA passes for NODE and STMTS. */ 2509*e4b17023SJohn Marino 2510*e4b17023SJohn Marino void 2511*e4b17023SJohn Marino execute_all_ipa_stmt_fixups (struct cgraph_node *node, gimple *stmts) 2512*e4b17023SJohn Marino { 2513*e4b17023SJohn Marino execute_ipa_stmt_fixups (all_regular_ipa_passes, node, stmts); 2514*e4b17023SJohn Marino } 2515*e4b17023SJohn Marino 2516*e4b17023SJohn Marino 2517*e4b17023SJohn Marino extern void debug_properties (unsigned int); 2518*e4b17023SJohn Marino extern void dump_properties (FILE *, unsigned int); 2519*e4b17023SJohn Marino 2520*e4b17023SJohn Marino DEBUG_FUNCTION void 2521*e4b17023SJohn Marino dump_properties (FILE *dump, unsigned int props) 2522*e4b17023SJohn Marino { 2523*e4b17023SJohn Marino fprintf (dump, "Properties:\n"); 2524*e4b17023SJohn Marino if (props & PROP_gimple_any) 2525*e4b17023SJohn Marino fprintf (dump, "PROP_gimple_any\n"); 2526*e4b17023SJohn Marino if (props & PROP_gimple_lcf) 2527*e4b17023SJohn Marino fprintf (dump, "PROP_gimple_lcf\n"); 2528*e4b17023SJohn Marino if (props & PROP_gimple_leh) 2529*e4b17023SJohn Marino fprintf (dump, "PROP_gimple_leh\n"); 2530*e4b17023SJohn Marino if (props & PROP_cfg) 2531*e4b17023SJohn Marino fprintf (dump, "PROP_cfg\n"); 2532*e4b17023SJohn Marino if (props & PROP_referenced_vars) 2533*e4b17023SJohn Marino fprintf (dump, "PROP_referenced_vars\n"); 2534*e4b17023SJohn Marino if (props & PROP_ssa) 2535*e4b17023SJohn Marino fprintf (dump, "PROP_ssa\n"); 2536*e4b17023SJohn Marino if (props & PROP_no_crit_edges) 2537*e4b17023SJohn Marino fprintf (dump, "PROP_no_crit_edges\n"); 2538*e4b17023SJohn Marino if (props & PROP_rtl) 2539*e4b17023SJohn Marino fprintf (dump, "PROP_rtl\n"); 2540*e4b17023SJohn Marino if (props & PROP_gimple_lomp) 2541*e4b17023SJohn Marino fprintf (dump, "PROP_gimple_lomp\n"); 2542*e4b17023SJohn Marino if (props & PROP_gimple_lcx) 2543*e4b17023SJohn Marino fprintf (dump, "PROP_gimple_lcx\n"); 2544*e4b17023SJohn Marino if (props & PROP_cfglayout) 2545*e4b17023SJohn Marino fprintf (dump, "PROP_cfglayout\n"); 2546*e4b17023SJohn Marino } 2547*e4b17023SJohn Marino 2548*e4b17023SJohn Marino DEBUG_FUNCTION void 2549*e4b17023SJohn Marino debug_properties (unsigned int props) 2550*e4b17023SJohn Marino { 2551*e4b17023SJohn Marino dump_properties (stderr, props); 2552*e4b17023SJohn Marino } 2553*e4b17023SJohn Marino 2554*e4b17023SJohn Marino /* Called by local passes to see if function is called by already processed nodes. 2555*e4b17023SJohn Marino Because we process nodes in topological order, this means that function is 2556*e4b17023SJohn Marino in recursive cycle or we introduced new direct calls. */ 2557*e4b17023SJohn Marino bool 2558*e4b17023SJohn Marino function_called_by_processed_nodes_p (void) 2559*e4b17023SJohn Marino { 2560*e4b17023SJohn Marino struct cgraph_edge *e; 2561*e4b17023SJohn Marino for (e = cgraph_get_node (current_function_decl)->callers; 2562*e4b17023SJohn Marino e; 2563*e4b17023SJohn Marino e = e->next_caller) 2564*e4b17023SJohn Marino { 2565*e4b17023SJohn Marino if (e->caller->decl == current_function_decl) 2566*e4b17023SJohn Marino continue; 2567*e4b17023SJohn Marino if (!cgraph_function_with_gimple_body_p (e->caller)) 2568*e4b17023SJohn Marino continue; 2569*e4b17023SJohn Marino if (TREE_ASM_WRITTEN (e->caller->decl)) 2570*e4b17023SJohn Marino continue; 2571*e4b17023SJohn Marino if (!e->caller->process && !e->caller->global.inlined_to) 2572*e4b17023SJohn Marino break; 2573*e4b17023SJohn Marino } 2574*e4b17023SJohn Marino if (dump_file && e) 2575*e4b17023SJohn Marino { 2576*e4b17023SJohn Marino fprintf (dump_file, "Already processed call to:\n"); 2577*e4b17023SJohn Marino dump_cgraph_node (dump_file, e->caller); 2578*e4b17023SJohn Marino } 2579*e4b17023SJohn Marino return e != NULL; 2580*e4b17023SJohn Marino } 2581*e4b17023SJohn Marino 2582*e4b17023SJohn Marino #include "gt-passes.h" 2583