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