x86: Add a test for PR rtl-optimization/111673
[official-gcc.git] / gcc / passes.cc
blob47c8029440890d97932c12c8580771843f124ebe
1 /* Top level of GCC compilers (cc1, cc1plus, etc.)
2 Copyright (C) 1987-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 /* This is the top level of cc1/c++.
21 It parses command args, opens files, invokes the various passes
22 in the proper order, and counts the time used by each.
23 Error messages and low-level interface to malloc also handled here. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "backend.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "gimple.h"
33 #include "cfghooks.h"
34 #include "df.h"
35 #include "memmodel.h"
36 #include "tm_p.h"
37 #include "ssa.h"
38 #include "emit-rtl.h"
39 #include "cgraph.h"
40 #include "lto-streamer.h"
41 #include "fold-const.h"
42 #include "varasm.h"
43 #include "output.h"
44 #include "graph.h"
45 #include "debug.h"
46 #include "cfgloop.h"
47 #include "value-prof.h"
48 #include "tree-cfg.h"
49 #include "tree-ssa-loop-manip.h"
50 #include "tree-into-ssa.h"
51 #include "tree-dfa.h"
52 #include "tree-ssa.h"
53 #include "tree-pass.h"
54 #include "plugin.h"
55 #include "ipa-utils.h"
56 #include "tree-pretty-print.h" /* for dump_function_header */
57 #include "context.h"
58 #include "pass_manager.h"
59 #include "cfgrtl.h"
60 #include "tree-ssa-live.h" /* For remove_unused_locals. */
61 #include "tree-cfgcleanup.h"
62 #include "insn-addr.h" /* for INSN_ADDRESSES_ALLOC. */
63 #include "diagnostic-core.h" /* for fnotice */
64 #include "stringpool.h"
65 #include "attribs.h"
67 using namespace gcc;
69 /* This is used for debugging. It allows the current pass to printed
70 from anywhere in compilation.
71 The variable current_pass is also used for statistics and plugins. */
72 opt_pass *current_pass;
74 /* Most passes are single-instance (within their context) and thus don't
75 need to implement cloning, but passes that support multiple instances
76 *must* provide their own implementation of the clone method.
78 Handle this by providing a default implemenation, but make it a fatal
79 error to call it. */
81 opt_pass *
82 opt_pass::clone ()
84 internal_error ("pass %s does not support cloning", name);
87 void
88 opt_pass::set_pass_param (unsigned int, bool)
90 internal_error ("pass %s needs a %<set_pass_param%> implementation "
91 "to handle the extra argument in %<NEXT_PASS%>", name);
94 bool
95 opt_pass::gate (function *)
97 return true;
100 unsigned int
101 opt_pass::execute (function *)
103 return 0;
106 opt_pass::opt_pass (const pass_data &data, context *ctxt)
107 : pass_data (data),
108 sub (NULL),
109 next (NULL),
110 static_pass_number (0),
111 m_ctxt (ctxt)
116 void
117 pass_manager::execute_early_local_passes ()
119 execute_pass_list (cfun, pass_build_ssa_passes_1->sub);
120 execute_pass_list (cfun, pass_local_optimization_passes_1->sub);
123 unsigned int
124 pass_manager::execute_pass_mode_switching ()
126 return pass_mode_switching_1->execute (cfun);
130 /* Call from anywhere to find out what pass this is. Useful for
131 printing out debugging information deep inside an service
132 routine. */
133 void
134 print_current_pass (FILE *file)
136 if (current_pass)
137 fprintf (file, "current pass = %s (%d)\n",
138 current_pass->name, current_pass->static_pass_number);
139 else
140 fprintf (file, "no current pass.\n");
144 /* Call from the debugger to get the current pass name. */
145 DEBUG_FUNCTION void
146 debug_pass (void)
148 print_current_pass (stderr);
153 /* Global variables used to communicate with passes. */
154 bool in_gimple_form;
157 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
158 and TYPE_DECL nodes.
160 This does nothing for local (non-static) variables, unless the
161 variable is a register variable with DECL_ASSEMBLER_NAME set. In
162 that case, or if the variable is not an automatic, it sets up the
163 RTL and outputs any assembler code (label definition, storage
164 allocation and initialization).
166 DECL is the declaration. TOP_LEVEL is nonzero
167 if this declaration is not within a function. */
169 void
170 rest_of_decl_compilation (tree decl,
171 int top_level,
172 int at_end)
174 bool finalize = true;
176 /* We deferred calling assemble_alias so that we could collect
177 other attributes such as visibility. Emit the alias now. */
178 if (!in_lto_p)
180 tree alias;
181 alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
182 if (alias)
184 alias = TREE_VALUE (TREE_VALUE (alias));
185 alias = get_identifier (TREE_STRING_POINTER (alias));
186 /* A quirk of the initial implementation of aliases required that the
187 user add "extern" to all of them. Which is silly, but now
188 historical. Do note that the symbol is in fact locally defined. */
189 DECL_EXTERNAL (decl) = 0;
190 TREE_STATIC (decl) = 1;
191 assemble_alias (decl, alias);
192 finalize = false;
196 /* Can't defer this, because it needs to happen before any
197 later function definitions are processed. */
198 if (HAS_DECL_ASSEMBLER_NAME_P (decl)
199 && DECL_ASSEMBLER_NAME_SET_P (decl)
200 && DECL_REGISTER (decl))
201 make_decl_rtl (decl);
203 /* Forward declarations for nested functions are not "external",
204 but we need to treat them as if they were. */
205 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
206 || TREE_CODE (decl) == FUNCTION_DECL)
208 timevar_push (TV_VARCONST);
210 /* Don't output anything when a tentative file-scope definition
211 is seen. But at end of compilation, do output code for them.
213 We do output all variables and rely on
214 callgraph code to defer them except for forward declarations
215 (see gcc.c-torture/compile/920624-1.c) */
216 if ((at_end
217 || !DECL_DEFER_OUTPUT (decl)
218 || DECL_INITIAL (decl))
219 && (!VAR_P (decl) || !DECL_HAS_VALUE_EXPR_P (decl))
220 && !DECL_EXTERNAL (decl))
222 /* When reading LTO unit, we also read varpool, so do not
223 rebuild it. */
224 if (in_lto_p && !at_end)
226 else if (finalize && TREE_CODE (decl) != FUNCTION_DECL)
227 varpool_node::finalize_decl (decl);
230 #ifdef ASM_FINISH_DECLARE_OBJECT
231 if (decl == last_assemble_variable_decl)
233 ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
234 top_level, at_end);
236 #endif
238 /* Now that we have activated any function-specific attributes
239 that might affect function decl, particularly align, relayout it. */
240 if (TREE_CODE (decl) == FUNCTION_DECL)
241 targetm.target_option.relayout_function (decl);
243 timevar_pop (TV_VARCONST);
245 else if (TREE_CODE (decl) == TYPE_DECL
246 /* Like in rest_of_type_compilation, avoid confusing the debug
247 information machinery when there are errors. */
248 && !seen_error ())
250 timevar_push (TV_SYMOUT);
251 debug_hooks->type_decl (decl, !top_level);
252 timevar_pop (TV_SYMOUT);
255 /* Let cgraph know about the existence of variables. */
256 if (in_lto_p && !at_end)
258 else if (VAR_P (decl) && !DECL_EXTERNAL (decl)
259 && TREE_STATIC (decl))
260 varpool_node::get_create (decl);
262 /* Generate early debug for global variables. Any local variables will
263 be handled by either handling reachable functions from
264 finalize_compilation_unit (and by consequence, locally scoped
265 symbols), or by rest_of_type_compilation below.
267 For Go's hijack of the debug_hooks to implement -fdump-go-spec, pick up
268 function prototypes. Go's debug_hooks will not forward them to the
269 wrapped hooks. */
270 if (!in_lto_p
271 && (TREE_CODE (decl) != FUNCTION_DECL
272 /* This will pick up function prototypes with no bodies,
273 which are not visible in finalize_compilation_unit()
274 while iterating with FOR_EACH_*_FUNCTION through the
275 symbol table. */
276 || (flag_dump_go_spec != NULL
277 && !DECL_SAVED_TREE (decl)
278 && DECL_STRUCT_FUNCTION (decl) == NULL))
280 /* We need to check both decl_function_context and
281 current_function_decl here to make sure local extern
282 declarations end up with the correct context.
284 For local extern declarations, decl_function_context is
285 empty, but current_function_decl is set to the function where
286 the extern was declared . Without the check for
287 !current_function_decl below, the local extern ends up
288 incorrectly with a top-level context.
290 For example:
292 namespace S
298 int i = 42;
300 extern int i; // Local extern declaration.
301 return i;
307 && !decl_function_context (decl)
308 && !current_function_decl
309 && DECL_SOURCE_LOCATION (decl) != BUILTINS_LOCATION
310 && (!decl_type_context (decl)
311 /* If we created a varpool node for the decl make sure to
312 call early_global_decl. Otherwise we miss changes
313 introduced by member definitions like
314 struct A { static int staticdatamember; };
315 int A::staticdatamember;
316 and thus have incomplete early debug and late debug
317 called from varpool node removal fails to handle it
318 properly. */
319 || (finalize
320 && VAR_P (decl)
321 && TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
322 /* Avoid confusing the debug information machinery when there are
323 errors. */
324 && !seen_error ())
325 (*debug_hooks->early_global_decl) (decl);
328 /* Called after finishing a record, union or enumeral type. */
330 void
331 rest_of_type_compilation (tree type, int toplev)
333 /* Avoid confusing the debug information machinery when there are
334 errors. */
335 if (seen_error ())
336 return;
338 timevar_push (TV_SYMOUT);
339 debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev);
340 timevar_pop (TV_SYMOUT);
345 void
346 pass_manager::
347 finish_optimization_passes (void)
349 int i;
350 struct dump_file_info *dfi;
351 char *name;
352 gcc::dump_manager *dumps = m_ctxt->get_dumps ();
354 timevar_push (TV_DUMP);
355 if (profile_arc_flag || condition_coverage_flag || flag_test_coverage
356 || flag_branch_probabilities)
358 dumps->dump_start (pass_profile_1->static_pass_number, NULL);
359 end_branch_prob ();
360 dumps->dump_finish (pass_profile_1->static_pass_number);
363 /* Do whatever is necessary to finish printing the graphs. */
364 for (i = TDI_end; (dfi = dumps->get_dump_file_info (i)) != NULL; ++i)
365 if (dfi->graph_dump_initialized)
367 name = dumps->get_dump_file_name (dfi);
368 finish_graph_dump_file (name);
369 free (name);
372 timevar_pop (TV_DUMP);
375 static unsigned int
376 execute_build_ssa_passes (void)
378 /* Once this pass (and its sub-passes) are complete, all functions
379 will be in SSA form. Technically this state change is happening
380 a tad early, since the sub-passes have not yet run, but since
381 none of the sub-passes are IPA passes and do not create new
382 functions, this is ok. We're setting this value for the benefit
383 of IPA passes that follow. */
384 if (symtab->state < IPA_SSA)
385 symtab->state = IPA_SSA;
386 return 0;
389 namespace {
391 const pass_data pass_data_build_ssa_passes =
393 SIMPLE_IPA_PASS, /* type */
394 "build_ssa_passes", /* name */
395 OPTGROUP_NONE, /* optinfo_flags */
396 TV_EARLY_LOCAL, /* tv_id */
397 0, /* properties_required */
398 0, /* properties_provided */
399 0, /* properties_destroyed */
400 0, /* todo_flags_start */
401 /* todo_flags_finish is executed before subpases. For this reason
402 it makes no sense to remove unreachable functions here. */
403 0, /* todo_flags_finish */
406 class pass_build_ssa_passes : public simple_ipa_opt_pass
408 public:
409 pass_build_ssa_passes (gcc::context *ctxt)
410 : simple_ipa_opt_pass (pass_data_build_ssa_passes, ctxt)
413 /* opt_pass methods: */
414 bool gate (function *) final override
416 /* Don't bother doing anything if the program has errors. */
417 return (!seen_error () && !in_lto_p);
420 unsigned int execute (function *) final override
422 return execute_build_ssa_passes ();
425 }; // class pass_build_ssa_passes
427 const pass_data pass_data_local_optimization_passes =
429 SIMPLE_IPA_PASS, /* type */
430 "opt_local_passes", /* name */
431 OPTGROUP_NONE, /* optinfo_flags */
432 TV_NONE, /* tv_id */
433 0, /* properties_required */
434 0, /* properties_provided */
435 0, /* properties_destroyed */
436 0, /* todo_flags_start */
437 0, /* todo_flags_finish */
440 class pass_local_optimization_passes : public simple_ipa_opt_pass
442 public:
443 pass_local_optimization_passes (gcc::context *ctxt)
444 : simple_ipa_opt_pass (pass_data_local_optimization_passes, ctxt)
447 /* opt_pass methods: */
448 bool gate (function *) final override
450 /* Don't bother doing anything if the program has errors. */
451 return (!seen_error () && !in_lto_p);
454 }; // class pass_local_optimization_passes
456 const pass_data pass_data_ipa_remove_symbols =
458 SIMPLE_IPA_PASS, /* type */
459 "remove_symbols", /* name */
460 OPTGROUP_NONE, /* optinfo_flags */
461 TV_NONE, /* tv_id */
462 0, /* properties_required */
463 0, /* properties_provided */
464 0, /* properties_destroyed */
465 0, /* todo_flags_start */
466 TODO_remove_functions | TODO_dump_symtab, /* todo_flags_finish */
469 class pass_ipa_remove_symbols : public simple_ipa_opt_pass
471 public:
472 pass_ipa_remove_symbols (gcc::context *ctxt)
473 : simple_ipa_opt_pass (pass_data_ipa_remove_symbols, ctxt)
476 /* opt_pass methods: */
477 bool gate (function *) final override
479 /* Don't bother doing anything if the program has errors. */
480 return (!seen_error () && !in_lto_p);
483 }; // class pass_local_optimization_passes
485 } // anon namespace
487 simple_ipa_opt_pass *
488 make_pass_build_ssa_passes (gcc::context *ctxt)
490 return new pass_build_ssa_passes (ctxt);
493 simple_ipa_opt_pass *
494 make_pass_local_optimization_passes (gcc::context *ctxt)
496 return new pass_local_optimization_passes (ctxt);
499 simple_ipa_opt_pass *
500 make_pass_ipa_remove_symbols (gcc::context *ctxt)
502 return new pass_ipa_remove_symbols (ctxt);
505 namespace {
507 const pass_data pass_data_all_early_optimizations =
509 GIMPLE_PASS, /* type */
510 "early_optimizations", /* name */
511 OPTGROUP_NONE, /* optinfo_flags */
512 TV_NONE, /* tv_id */
513 0, /* properties_required */
514 0, /* properties_provided */
515 0, /* properties_destroyed */
516 0, /* todo_flags_start */
517 0, /* todo_flags_finish */
520 class pass_all_early_optimizations : public gimple_opt_pass
522 public:
523 pass_all_early_optimizations (gcc::context *ctxt)
524 : gimple_opt_pass (pass_data_all_early_optimizations, ctxt)
527 /* opt_pass methods: */
528 bool gate (function *) final override
530 return (optimize >= 1
531 /* Don't bother doing anything if the program has errors. */
532 && !seen_error ());
535 }; // class pass_all_early_optimizations
537 } // anon namespace
539 static gimple_opt_pass *
540 make_pass_all_early_optimizations (gcc::context *ctxt)
542 return new pass_all_early_optimizations (ctxt);
545 namespace {
547 const pass_data pass_data_all_optimizations =
549 GIMPLE_PASS, /* type */
550 "*all_optimizations", /* name */
551 OPTGROUP_NONE, /* optinfo_flags */
552 TV_OPTIMIZE, /* tv_id */
553 0, /* properties_required */
554 0, /* properties_provided */
555 0, /* properties_destroyed */
556 0, /* todo_flags_start */
557 0, /* todo_flags_finish */
560 class pass_all_optimizations : public gimple_opt_pass
562 public:
563 pass_all_optimizations (gcc::context *ctxt)
564 : gimple_opt_pass (pass_data_all_optimizations, ctxt)
567 /* opt_pass methods: */
568 bool gate (function *) final override
570 return optimize >= 1 && !optimize_debug;
573 }; // class pass_all_optimizations
575 } // anon namespace
577 static gimple_opt_pass *
578 make_pass_all_optimizations (gcc::context *ctxt)
580 return new pass_all_optimizations (ctxt);
583 namespace {
585 const pass_data pass_data_all_optimizations_g =
587 GIMPLE_PASS, /* type */
588 "*all_optimizations_g", /* name */
589 OPTGROUP_NONE, /* optinfo_flags */
590 TV_OPTIMIZE, /* tv_id */
591 0, /* properties_required */
592 0, /* properties_provided */
593 0, /* properties_destroyed */
594 0, /* todo_flags_start */
595 0, /* todo_flags_finish */
598 class pass_all_optimizations_g : public gimple_opt_pass
600 public:
601 pass_all_optimizations_g (gcc::context *ctxt)
602 : gimple_opt_pass (pass_data_all_optimizations_g, ctxt)
605 /* opt_pass methods: */
606 bool gate (function *) final override
608 return optimize >= 1 && optimize_debug;
611 }; // class pass_all_optimizations_g
613 } // anon namespace
615 static gimple_opt_pass *
616 make_pass_all_optimizations_g (gcc::context *ctxt)
618 return new pass_all_optimizations_g (ctxt);
621 namespace {
623 const pass_data pass_data_rest_of_compilation =
625 RTL_PASS, /* type */
626 "*rest_of_compilation", /* name */
627 OPTGROUP_NONE, /* optinfo_flags */
628 TV_REST_OF_COMPILATION, /* tv_id */
629 PROP_rtl, /* properties_required */
630 0, /* properties_provided */
631 0, /* properties_destroyed */
632 0, /* todo_flags_start */
633 0, /* todo_flags_finish */
636 class pass_rest_of_compilation : public rtl_opt_pass
638 public:
639 pass_rest_of_compilation (gcc::context *ctxt)
640 : rtl_opt_pass (pass_data_rest_of_compilation, ctxt)
643 /* opt_pass methods: */
644 bool gate (function *) final override
646 /* Early return if there were errors. We can run afoul of our
647 consistency checks, and there's not really much point in fixing them. */
648 return !(rtl_dump_and_exit || flag_syntax_only || seen_error ());
651 }; // class pass_rest_of_compilation
653 } // anon namespace
655 static rtl_opt_pass *
656 make_pass_rest_of_compilation (gcc::context *ctxt)
658 return new pass_rest_of_compilation (ctxt);
661 namespace {
663 /* A container pass (only) for '!targetm.no_register_allocation' targets, for
664 passes to run if reload completed (..., but not run them if it failed, for
665 example for an invalid 'asm'). See also 'pass_late_compilation'. */
667 const pass_data pass_data_postreload =
669 RTL_PASS, /* type */
670 "*all-postreload", /* name */
671 OPTGROUP_NONE, /* optinfo_flags */
672 TV_POSTRELOAD, /* tv_id */
673 PROP_rtl, /* properties_required */
674 0, /* properties_provided */
675 0, /* properties_destroyed */
676 0, /* todo_flags_start */
677 0, /* todo_flags_finish */
680 class pass_postreload : public rtl_opt_pass
682 public:
683 pass_postreload (gcc::context *ctxt)
684 : rtl_opt_pass (pass_data_postreload, ctxt)
687 /* opt_pass methods: */
688 bool gate (function *) final override
690 if (reload_completed)
691 gcc_checking_assert (!targetm.no_register_allocation);
692 return reload_completed;
695 }; // class pass_postreload
697 } // anon namespace
699 static rtl_opt_pass *
700 make_pass_postreload (gcc::context *ctxt)
702 return new pass_postreload (ctxt);
705 namespace {
707 /* A container pass like 'pass_postreload', but for passes to run also for
708 'targetm.no_register_allocation' targets. */
710 const pass_data pass_data_late_compilation =
712 RTL_PASS, /* type */
713 "*all-late_compilation", /* name */
714 OPTGROUP_NONE, /* optinfo_flags */
715 TV_LATE_COMPILATION, /* tv_id */
716 PROP_rtl, /* properties_required */
717 0, /* properties_provided */
718 0, /* properties_destroyed */
719 0, /* todo_flags_start */
720 0, /* todo_flags_finish */
723 class pass_late_compilation : public rtl_opt_pass
725 public:
726 pass_late_compilation (gcc::context *ctxt)
727 : rtl_opt_pass (pass_data_late_compilation, ctxt)
730 /* opt_pass methods: */
731 bool gate (function *) final override
733 return reload_completed || targetm.no_register_allocation;
736 }; // class pass_late_compilation
738 } // anon namespace
740 static rtl_opt_pass *
741 make_pass_late_compilation (gcc::context *ctxt)
743 return new pass_late_compilation (ctxt);
746 /* Pre-SLP scalar cleanup, it has several cleanup passes like FRE, DSE. */
748 namespace {
750 const pass_data pass_data_pre_slp_scalar_cleanup =
752 GIMPLE_PASS, /* type */
753 "*pre_slp_scalar_cleanup", /* name */
754 OPTGROUP_LOOP, /* optinfo_flags */
755 TV_SCALAR_CLEANUP, /* tv_id */
756 ( PROP_cfg | PROP_ssa ), /* properties_required */
757 0, /* properties_provided */
758 0, /* properties_destroyed */
759 0, /* todo_flags_start */
760 0, /* todo_flags_finish */
763 class pass_pre_slp_scalar_cleanup : public gimple_opt_pass
765 public:
766 pass_pre_slp_scalar_cleanup (gcc::context *ctxt)
767 : gimple_opt_pass (pass_data_pre_slp_scalar_cleanup, ctxt)
771 bool
772 gate (function *fun) final override
774 return flag_tree_slp_vectorize
775 && (fun->pending_TODOs & PENDING_TODO_force_next_scalar_cleanup);
778 unsigned int
779 execute (function *fun) final override
781 fun->pending_TODOs &= ~PENDING_TODO_force_next_scalar_cleanup;
782 return 0;
785 }; // class pass_pre_slp_scalar_cleanup
787 } // anon namespace
789 gimple_opt_pass *
790 make_pass_pre_slp_scalar_cleanup (gcc::context *ctxt)
792 return new pass_pre_slp_scalar_cleanup (ctxt);
795 /* Set the static pass number of pass PASS to ID and record that
796 in the mapping from static pass number to pass. */
798 void
799 pass_manager::
800 set_pass_for_id (int id, opt_pass *pass)
802 pass->static_pass_number = id;
803 if (passes_by_id_size <= id)
805 passes_by_id = XRESIZEVEC (opt_pass *, passes_by_id, id + 1);
806 memset (passes_by_id + passes_by_id_size, 0,
807 (id + 1 - passes_by_id_size) * sizeof (void *));
808 passes_by_id_size = id + 1;
810 passes_by_id[id] = pass;
813 /* Return the pass with the static pass number ID. */
815 opt_pass *
816 pass_manager::get_pass_for_id (int id) const
818 if (id >= passes_by_id_size)
819 return NULL;
820 return passes_by_id[id];
823 /* Iterate over the pass tree allocating dump file numbers. We want
824 to do this depth first, and independent of whether the pass is
825 enabled or not. */
827 void
828 register_one_dump_file (opt_pass *pass)
830 g->get_passes ()->register_one_dump_file (pass);
833 void
834 pass_manager::register_one_dump_file (opt_pass *pass)
836 char *dot_name, *flag_name, *glob_name;
837 const char *name, *full_name, *prefix;
839 /* Buffer big enough to format a 32-bit UINT_MAX into. */
840 char num[11];
841 dump_kind dkind;
842 int id;
843 optgroup_flags_t optgroup_flags = OPTGROUP_NONE;
844 gcc::dump_manager *dumps = m_ctxt->get_dumps ();
846 /* See below in next_pass_1. */
847 num[0] = '\0';
848 if (pass->static_pass_number != -1)
849 sprintf (num, "%u", ((int) pass->static_pass_number < 0
850 ? 1 : pass->static_pass_number));
852 /* The name is both used to identify the pass for the purposes of plugins,
853 and to specify dump file name and option.
854 The latter two might want something short which is not quite unique; for
855 that reason, we may have a disambiguating prefix, followed by a space
856 to mark the start of the following dump file name / option string. */
857 name = strchr (pass->name, ' ');
858 name = name ? name + 1 : pass->name;
859 dot_name = concat (".", name, num, NULL);
860 if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
862 prefix = "ipa-";
863 dkind = DK_ipa;
864 optgroup_flags |= OPTGROUP_IPA;
866 else if (pass->type == GIMPLE_PASS)
868 prefix = "tree-";
869 dkind = DK_tree;
871 else
873 prefix = "rtl-";
874 dkind = DK_rtl;
877 flag_name = concat (prefix, name, num, NULL);
878 glob_name = concat (prefix, name, NULL);
879 optgroup_flags |= pass->optinfo_flags;
880 /* For any passes that do not have an optgroup set, and which are not
881 IPA passes setup above, set the optgroup to OPTGROUP_OTHER so that
882 any dump messages are emitted properly under -fopt-info(-optall). */
883 if (optgroup_flags == OPTGROUP_NONE)
884 optgroup_flags = OPTGROUP_OTHER;
885 id = dumps->dump_register (dot_name, flag_name, glob_name, dkind,
886 optgroup_flags,
887 true);
888 set_pass_for_id (id, pass);
889 full_name = concat (prefix, pass->name, num, NULL);
890 register_pass_name (pass, full_name);
891 free (CONST_CAST (char *, full_name));
894 /* Register the dump files for the pass_manager starting at PASS. */
896 void
897 pass_manager::register_dump_files (opt_pass *pass)
901 if (pass->name && pass->name[0] != '*')
902 register_one_dump_file (pass);
904 if (pass->sub)
905 register_dump_files (pass->sub);
907 pass = pass->next;
909 while (pass);
912 /* Register PASS with NAME. */
914 void
915 pass_manager::register_pass_name (opt_pass *pass, const char *name)
917 if (!m_name_to_pass_map)
918 m_name_to_pass_map = new hash_map<free_string_hash, opt_pass *> (256);
920 if (m_name_to_pass_map->get (name))
921 return; /* Ignore plugin passes. */
923 const char *unique_name = xstrdup (name);
924 m_name_to_pass_map->put (unique_name, pass);
927 /* Map from pass id to canonicalized pass name. */
929 typedef const char *char_ptr;
930 static vec<char_ptr> pass_tab;
932 /* Callback function for traversing NAME_TO_PASS_MAP. */
934 bool
935 passes_pass_traverse (const char *const &name, opt_pass *const &pass, void *)
937 gcc_assert (pass->static_pass_number > 0);
938 gcc_assert (pass_tab.exists ());
940 pass_tab[pass->static_pass_number] = name;
942 return 1;
945 /* The function traverses NAME_TO_PASS_MAP and creates a pass info
946 table for dumping purpose. */
948 void
949 pass_manager::create_pass_tab (void) const
951 if (!flag_dump_passes)
952 return;
954 pass_tab.safe_grow_cleared (passes_by_id_size + 1, true);
955 m_name_to_pass_map->traverse <void *, passes_pass_traverse> (NULL);
958 static bool override_gate_status (opt_pass *, tree, bool);
960 /* Dump the instantiated name for PASS. IS_ON indicates if PASS
961 is turned on or not. */
963 static void
964 dump_one_pass (opt_pass *pass, int pass_indent)
966 int indent = 3 * pass_indent;
967 const char *pn;
968 bool is_on, is_really_on;
970 is_on = pass->gate (cfun);
971 is_really_on = override_gate_status (pass, current_function_decl, is_on);
973 if (pass->static_pass_number <= 0)
974 pn = pass->name;
975 else
976 pn = pass_tab[pass->static_pass_number];
978 fprintf (stderr, "%*s%-40s%*s:%s%s\n", indent, " ", pn,
979 (15 - indent < 0 ? 0 : 15 - indent), " ",
980 is_on ? " ON" : " OFF",
981 ((!is_on) == (!is_really_on) ? ""
982 : (is_really_on ? " (FORCED_ON)" : " (FORCED_OFF)")));
985 /* Dump pass list PASS with indentation INDENT. */
987 static void
988 dump_pass_list (opt_pass *pass, int indent)
992 dump_one_pass (pass, indent);
993 if (pass->sub)
994 dump_pass_list (pass->sub, indent + 1);
995 pass = pass->next;
997 while (pass);
1000 /* Dump all optimization passes. */
1002 void
1003 dump_passes (void)
1005 g->get_passes ()->dump_passes ();
1008 void
1009 pass_manager::dump_passes () const
1011 push_dummy_function (true);
1012 cgraph_node *node = cgraph_node::get_create (current_function_decl);
1014 create_pass_tab ();
1016 dump_pass_list (all_lowering_passes, 1);
1017 dump_pass_list (all_small_ipa_passes, 1);
1018 dump_pass_list (all_regular_ipa_passes, 1);
1019 dump_pass_list (all_late_ipa_passes, 1);
1020 dump_pass_list (all_passes, 1);
1022 node->remove ();
1023 pop_dummy_function ();
1026 /* Returns the pass with NAME. */
1028 opt_pass *
1029 pass_manager::get_pass_by_name (const char *name)
1031 opt_pass **p = m_name_to_pass_map->get (name);
1032 if (p)
1033 return *p;
1035 return NULL;
1039 /* Range [start, last]. */
1041 struct uid_range
1043 unsigned int start;
1044 unsigned int last;
1045 const char *assem_name;
1046 struct uid_range *next;
1049 typedef struct uid_range *uid_range_p;
1052 static vec<uid_range_p> enabled_pass_uid_range_tab;
1053 static vec<uid_range_p> disabled_pass_uid_range_tab;
1056 /* Parse option string for -fdisable- and -fenable-
1057 The syntax of the options:
1059 -fenable-<pass_name>
1060 -fdisable-<pass_name>
1062 -fenable-<pass_name>=s1:e1,s2:e2,...
1063 -fdisable-<pass_name>=s1:e1,s2:e2,...
1066 static void
1067 enable_disable_pass (const char *arg, bool is_enable)
1069 opt_pass *pass;
1070 char *range_str, *phase_name;
1071 char *argstr = xstrdup (arg);
1072 vec<uid_range_p> *tab = 0;
1074 range_str = strchr (argstr,'=');
1075 if (range_str)
1077 *range_str = '\0';
1078 range_str++;
1081 phase_name = argstr;
1082 if (!*phase_name)
1084 if (is_enable)
1085 error ("unrecognized option %<-fenable%>");
1086 else
1087 error ("unrecognized option %<-fdisable%>");
1088 free (argstr);
1089 return;
1091 pass = g->get_passes ()->get_pass_by_name (phase_name);
1092 if (!pass || pass->static_pass_number == -1)
1094 if (is_enable)
1095 error ("unknown pass %s specified in %<-fenable%>", phase_name);
1096 else
1097 error ("unknown pass %s specified in %<-fdisable%>", phase_name);
1098 free (argstr);
1099 return;
1102 if (is_enable)
1103 tab = &enabled_pass_uid_range_tab;
1104 else
1105 tab = &disabled_pass_uid_range_tab;
1107 if ((unsigned) pass->static_pass_number >= tab->length ())
1108 tab->safe_grow_cleared (pass->static_pass_number + 1, true);
1110 if (!range_str)
1112 uid_range_p slot;
1113 uid_range_p new_range = XCNEW (struct uid_range);
1115 new_range->start = 0;
1116 new_range->last = (unsigned)-1;
1118 slot = (*tab)[pass->static_pass_number];
1119 new_range->next = slot;
1120 (*tab)[pass->static_pass_number] = new_range;
1121 if (is_enable)
1122 inform (UNKNOWN_LOCATION, "enable pass %s for functions in the range "
1123 "of [%u, %u]", phase_name, new_range->start, new_range->last);
1124 else
1125 inform (UNKNOWN_LOCATION, "disable pass %s for functions in the range "
1126 "of [%u, %u]", phase_name, new_range->start, new_range->last);
1128 else
1130 char *next_range = NULL;
1131 char *one_range = range_str;
1132 char *end_val = NULL;
1136 uid_range_p slot;
1137 uid_range_p new_range;
1138 char *invalid = NULL;
1139 long start;
1140 char *func_name = NULL;
1142 next_range = strchr (one_range, ',');
1143 if (next_range)
1145 *next_range = '\0';
1146 next_range++;
1149 end_val = strchr (one_range, ':');
1150 if (end_val)
1152 *end_val = '\0';
1153 end_val++;
1155 start = strtol (one_range, &invalid, 10);
1156 if (*invalid || start < 0)
1158 if (end_val || (one_range[0] >= '0'
1159 && one_range[0] <= '9'))
1161 error ("Invalid range %s in option %s",
1162 one_range,
1163 is_enable ? "-fenable" : "-fdisable");
1164 free (argstr);
1165 return;
1167 func_name = one_range;
1169 if (!end_val)
1171 new_range = XCNEW (struct uid_range);
1172 if (!func_name)
1174 new_range->start = (unsigned) start;
1175 new_range->last = (unsigned) start;
1177 else
1179 new_range->start = (unsigned) -1;
1180 new_range->last = (unsigned) -1;
1181 new_range->assem_name = xstrdup (func_name);
1184 else
1186 long last = strtol (end_val, &invalid, 10);
1187 if (*invalid || last < start)
1189 error ("Invalid range %s in option %s",
1190 end_val,
1191 is_enable ? "-fenable" : "-fdisable");
1192 free (argstr);
1193 return;
1195 new_range = XCNEW (struct uid_range);
1196 new_range->start = (unsigned) start;
1197 new_range->last = (unsigned) last;
1200 slot = (*tab)[pass->static_pass_number];
1201 new_range->next = slot;
1202 (*tab)[pass->static_pass_number] = new_range;
1203 if (is_enable)
1205 if (new_range->assem_name)
1206 inform (UNKNOWN_LOCATION,
1207 "enable pass %s for function %s",
1208 phase_name, new_range->assem_name);
1209 else
1210 inform (UNKNOWN_LOCATION,
1211 "enable pass %s for functions in the range of [%u, %u]",
1212 phase_name, new_range->start, new_range->last);
1214 else
1216 if (new_range->assem_name)
1217 inform (UNKNOWN_LOCATION,
1218 "disable pass %s for function %s",
1219 phase_name, new_range->assem_name);
1220 else
1221 inform (UNKNOWN_LOCATION,
1222 "disable pass %s for functions in the range of [%u, %u]",
1223 phase_name, new_range->start, new_range->last);
1226 one_range = next_range;
1227 } while (next_range);
1230 free (argstr);
1233 /* Enable pass specified by ARG. */
1235 void
1236 enable_pass (const char *arg)
1238 enable_disable_pass (arg, true);
1241 /* Disable pass specified by ARG. */
1243 void
1244 disable_pass (const char *arg)
1246 enable_disable_pass (arg, false);
1249 /* Returns true if PASS is explicitly enabled/disabled for FUNC. */
1251 static bool
1252 is_pass_explicitly_enabled_or_disabled (opt_pass *pass,
1253 tree func,
1254 vec<uid_range_p> tab)
1256 uid_range_p slot, range;
1257 int cgraph_uid;
1258 const char *aname = NULL;
1260 if (!tab.exists ()
1261 || (unsigned) pass->static_pass_number >= tab.length ()
1262 || pass->static_pass_number == -1)
1263 return false;
1265 slot = tab[pass->static_pass_number];
1266 if (!slot)
1267 return false;
1269 cgraph_uid = func ? cgraph_node::get (func)->get_uid () : 0;
1270 if (func && DECL_ASSEMBLER_NAME_SET_P (func))
1271 aname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func));
1273 range = slot;
1274 while (range)
1276 if ((unsigned) cgraph_uid >= range->start
1277 && (unsigned) cgraph_uid <= range->last)
1278 return true;
1279 if (range->assem_name && aname
1280 && !strcmp (range->assem_name, aname))
1281 return true;
1282 range = range->next;
1285 return false;
1289 /* Update static_pass_number for passes (and the flag
1290 TODO_mark_first_instance).
1292 Passes are constructed with static_pass_number preinitialized to 0
1294 This field is used in two different ways: initially as instance numbers
1295 of their kind, and then as ids within the entire pass manager.
1297 Within pass_manager::pass_manager:
1299 * In add_pass_instance(), as called by next_pass_1 in
1300 NEXT_PASS in init_optimization_passes
1302 * When the initial instance of a pass within a pass manager is seen,
1303 it is flagged, and its static_pass_number is set to -1
1305 * On subsequent times that it is seen, the static pass number
1306 is decremented each time, so that if there are e.g. 4 dups,
1307 they have static_pass_number -4, 2, 3, 4 respectively (note
1308 how the initial one is negative and gives the count); these
1309 can be thought of as instance numbers of the specific pass
1311 * Within the register_dump_files () traversal, set_pass_for_id()
1312 is called on each pass, using these instance numbers to create
1313 dumpfile switches, and then overwriting them with a pass id,
1314 which are global to the whole pass manager (based on
1315 (TDI_end + current value of extra_dump_files_in_use) ) */
1317 static void
1318 add_pass_instance (opt_pass *new_pass, bool track_duplicates,
1319 opt_pass *initial_pass)
1321 /* Are we dealing with the first pass of its kind, or a clone? */
1322 if (new_pass != initial_pass)
1324 /* We're dealing with a clone. */
1325 new_pass->todo_flags_start &= ~TODO_mark_first_instance;
1327 /* Indicate to register_dump_files that this pass has duplicates,
1328 and so it should rename the dump file. The first instance will
1329 be -1, and be number of duplicates = -static_pass_number - 1.
1330 Subsequent instances will be > 0 and just the duplicate number. */
1331 if ((new_pass->name && new_pass->name[0] != '*') || track_duplicates)
1333 initial_pass->static_pass_number -= 1;
1334 new_pass->static_pass_number = -initial_pass->static_pass_number;
1337 else
1339 /* We're dealing with the first pass of its kind. */
1340 new_pass->todo_flags_start |= TODO_mark_first_instance;
1341 new_pass->static_pass_number = -1;
1343 invoke_plugin_callbacks (PLUGIN_NEW_PASS, new_pass);
1347 /* Add a pass to the pass list. Duplicate the pass if it's already
1348 in the list. */
1350 static opt_pass **
1351 next_pass_1 (opt_pass **list, opt_pass *pass, opt_pass *initial_pass)
1353 /* Every pass should have a name so that plugins can refer to them. */
1354 gcc_assert (pass->name != NULL);
1356 add_pass_instance (pass, false, initial_pass);
1357 *list = pass;
1359 return &(*list)->next;
1362 /* List node for an inserted pass instance. We need to keep track of all
1363 the newly-added pass instances (with 'added_pass_nodes' defined below)
1364 so that we can register their dump files after pass-positioning is finished.
1365 Registering dumping files needs to be post-processed or the
1366 static_pass_number of the opt_pass object would be modified and mess up
1367 the dump file names of future pass instances to be added. */
1369 struct pass_list_node
1371 opt_pass *pass;
1372 struct pass_list_node *next;
1375 static struct pass_list_node *added_pass_nodes = NULL;
1376 static struct pass_list_node *prev_added_pass_node;
1378 /* Insert the pass at the proper position. Return true if the pass
1379 is successfully added.
1381 NEW_PASS_INFO - new pass to be inserted
1382 PASS_LIST - root of the pass list to insert the new pass to */
1384 static bool
1385 position_pass (struct register_pass_info *new_pass_info, opt_pass **pass_list)
1387 opt_pass *pass = *pass_list, *prev_pass = NULL;
1388 bool success = false;
1390 for ( ; pass; prev_pass = pass, pass = pass->next)
1392 /* Check if the current pass is of the same type as the new pass and
1393 matches the name and the instance number of the reference pass. */
1394 if (pass->type == new_pass_info->pass->type
1395 && pass->name
1396 && !strcmp (pass->name, new_pass_info->reference_pass_name)
1397 && ((new_pass_info->ref_pass_instance_number == 0)
1398 || (new_pass_info->ref_pass_instance_number ==
1399 pass->static_pass_number)
1400 || (new_pass_info->ref_pass_instance_number == 1
1401 && pass->todo_flags_start & TODO_mark_first_instance)))
1403 opt_pass *new_pass;
1404 struct pass_list_node *new_pass_node;
1406 if (new_pass_info->ref_pass_instance_number == 0)
1408 new_pass = new_pass_info->pass->clone ();
1409 add_pass_instance (new_pass, true, new_pass_info->pass);
1411 else
1413 new_pass = new_pass_info->pass;
1414 add_pass_instance (new_pass, true, new_pass);
1417 /* Insert the new pass instance based on the positioning op. */
1418 switch (new_pass_info->pos_op)
1420 case PASS_POS_INSERT_AFTER:
1421 new_pass->next = pass->next;
1422 pass->next = new_pass;
1424 /* Skip newly inserted pass to avoid repeated
1425 insertions in the case where the new pass and the
1426 existing one have the same name. */
1427 pass = new_pass;
1428 break;
1429 case PASS_POS_INSERT_BEFORE:
1430 new_pass->next = pass;
1431 if (prev_pass)
1432 prev_pass->next = new_pass;
1433 else
1434 *pass_list = new_pass;
1435 break;
1436 case PASS_POS_REPLACE:
1437 new_pass->next = pass->next;
1438 if (prev_pass)
1439 prev_pass->next = new_pass;
1440 else
1441 *pass_list = new_pass;
1442 new_pass->sub = pass->sub;
1443 new_pass->tv_id = pass->tv_id;
1444 pass = new_pass;
1445 break;
1446 default:
1447 error ("invalid pass positioning operation");
1448 return false;
1451 /* Save the newly added pass (instance) in the added_pass_nodes
1452 list so that we can register its dump file later. Note that
1453 we cannot register the dump file now because doing so will modify
1454 the static_pass_number of the opt_pass object and therefore
1455 mess up the dump file name of future instances. */
1456 new_pass_node = XCNEW (struct pass_list_node);
1457 new_pass_node->pass = new_pass;
1458 if (!added_pass_nodes)
1459 added_pass_nodes = new_pass_node;
1460 else
1461 prev_added_pass_node->next = new_pass_node;
1462 prev_added_pass_node = new_pass_node;
1464 success = true;
1467 if (pass->sub && position_pass (new_pass_info, &pass->sub))
1468 success = true;
1471 return success;
1474 /* Hooks a new pass into the pass lists.
1476 PASS_INFO - pass information that specifies the opt_pass object,
1477 reference pass, instance number, and how to position
1478 the pass */
1480 void
1481 register_pass (struct register_pass_info *pass_info)
1483 g->get_passes ()->register_pass (pass_info);
1486 void
1487 register_pass (opt_pass* pass, pass_positioning_ops pos,
1488 const char* ref_pass_name, int ref_pass_inst_number)
1490 register_pass_info i;
1491 i.pass = pass;
1492 i.reference_pass_name = ref_pass_name;
1493 i.ref_pass_instance_number = ref_pass_inst_number;
1494 i.pos_op = pos;
1496 g->get_passes ()->register_pass (&i);
1499 void
1500 pass_manager::register_pass (struct register_pass_info *pass_info)
1502 bool all_instances, success;
1504 /* The checks below could fail in buggy plugins. Existing GCC
1505 passes should never fail these checks, so we mention plugin in
1506 the messages. */
1507 if (!pass_info->pass)
1508 fatal_error (input_location, "plugin cannot register a missing pass");
1510 if (!pass_info->pass->name)
1511 fatal_error (input_location, "plugin cannot register an unnamed pass");
1513 if (!pass_info->reference_pass_name)
1514 fatal_error
1515 (input_location,
1516 "plugin cannot register pass %qs without reference pass name",
1517 pass_info->pass->name);
1519 /* Try to insert the new pass to the pass lists. We need to check
1520 all five lists as the reference pass could be in one (or all) of
1521 them. */
1522 all_instances = pass_info->ref_pass_instance_number == 0;
1523 success = position_pass (pass_info, &all_lowering_passes);
1524 if (!success || all_instances)
1525 success |= position_pass (pass_info, &all_small_ipa_passes);
1526 if (!success || all_instances)
1527 success |= position_pass (pass_info, &all_regular_ipa_passes);
1528 if (!success || all_instances)
1529 success |= position_pass (pass_info, &all_late_ipa_passes);
1530 if (!success || all_instances)
1531 success |= position_pass (pass_info, &all_passes);
1532 if (!success)
1533 fatal_error
1534 (input_location,
1535 "pass %qs not found but is referenced by new pass %qs",
1536 pass_info->reference_pass_name, pass_info->pass->name);
1538 /* OK, we have successfully inserted the new pass. We need to register
1539 the dump files for the newly added pass and its duplicates (if any).
1540 While doing so, we also delete the pass_list_node
1541 objects created during pass positioning. */
1542 gcc::dump_manager *dumps = m_ctxt->get_dumps ();
1543 while (added_pass_nodes)
1545 struct pass_list_node *next_node = added_pass_nodes->next;
1547 /* Handle -fdump-* and -fopt-info. */
1548 dumps->register_pass (added_pass_nodes->pass);
1550 XDELETE (added_pass_nodes);
1551 added_pass_nodes = next_node;
1555 /* Construct the pass tree. The sequencing of passes is driven by
1556 the cgraph routines:
1558 finalize_compilation_unit ()
1559 for each node N in the cgraph
1560 cgraph_analyze_function (N)
1561 cgraph_lower_function (N) -> all_lowering_passes
1563 If we are optimizing, compile is then invoked:
1565 compile ()
1566 ipa_passes () -> all_small_ipa_passes
1567 -> Analysis of all_regular_ipa_passes
1568 * possible LTO streaming at compilation time *
1569 -> Execution of all_regular_ipa_passes
1570 * possible LTO streaming at link time *
1571 -> all_late_ipa_passes
1572 expand_all_functions ()
1573 for each node N in the cgraph
1574 expand_function (N) -> Transformation of all_regular_ipa_passes
1575 -> all_passes
1578 pass_manager::pass_manager (context *ctxt)
1579 : all_passes (NULL), all_small_ipa_passes (NULL), all_lowering_passes (NULL),
1580 all_regular_ipa_passes (NULL),
1581 all_late_ipa_passes (NULL), passes_by_id (NULL), passes_by_id_size (0),
1582 m_ctxt (ctxt), m_name_to_pass_map (NULL)
1584 opt_pass **p;
1586 /* Zero-initialize pass members. */
1587 #define INSERT_PASSES_AFTER(PASS)
1588 #define PUSH_INSERT_PASSES_WITHIN(PASS, NUM)
1589 #define POP_INSERT_PASSES()
1590 #define NEXT_PASS(PASS, NUM) PASS ## _ ## NUM = NULL
1591 #define NEXT_PASS_WITH_ARG(PASS, NUM, ARG) NEXT_PASS (PASS, NUM)
1592 #define NEXT_PASS_WITH_ARGS(PASS, NUM, ...) NEXT_PASS (PASS, NUM)
1593 #define TERMINATE_PASS_LIST(PASS)
1594 #include "pass-instances.def"
1596 /* Initialize the pass_lists array. */
1597 #define DEF_PASS_LIST(LIST) pass_lists[PASS_LIST_NO_##LIST] = &LIST;
1598 GCC_PASS_LISTS
1599 #undef DEF_PASS_LIST
1601 /* Build the tree of passes. */
1603 #define INSERT_PASSES_AFTER(PASS) \
1605 opt_pass **p_start; \
1606 p_start = p = &(PASS);
1608 #define TERMINATE_PASS_LIST(PASS) \
1609 gcc_assert (p_start == &PASS); \
1610 *p = NULL; \
1613 #define PUSH_INSERT_PASSES_WITHIN(PASS, NUM) \
1615 opt_pass **p = &(PASS ## _ ## NUM)->sub;
1617 #define POP_INSERT_PASSES() \
1620 #define NEXT_PASS(PASS, NUM) \
1621 do { \
1622 gcc_assert (PASS ## _ ## NUM == NULL); \
1623 if ((NUM) == 1) \
1624 PASS ## _1 = make_##PASS (m_ctxt); \
1625 else \
1627 gcc_assert (PASS ## _1); \
1628 PASS ## _ ## NUM = PASS ## _1->clone (); \
1630 p = next_pass_1 (p, PASS ## _ ## NUM, PASS ## _1); \
1631 } while (0)
1633 #define NEXT_PASS_WITH_ARG(PASS, NUM, ARG) \
1634 do { \
1635 NEXT_PASS (PASS, NUM); \
1636 PASS ## _ ## NUM->set_pass_param (0, ARG); \
1637 } while (0)
1639 #define NEXT_PASS_WITH_ARGS(PASS, NUM, ...) \
1640 do { \
1641 NEXT_PASS (PASS, NUM); \
1642 static constexpr bool values[] = { __VA_ARGS__ }; \
1643 unsigned i = 0; \
1644 for (bool value : values) \
1646 PASS ## _ ## NUM->set_pass_param (i, value); \
1647 i++; \
1649 } while (0)
1651 #include "pass-instances.def"
1653 /* Register the passes with the tree dump code. */
1654 register_dump_files (all_lowering_passes);
1655 register_dump_files (all_small_ipa_passes);
1656 register_dump_files (all_regular_ipa_passes);
1657 register_dump_files (all_late_ipa_passes);
1658 register_dump_files (all_passes);
1661 static void
1662 delete_pass_tree (opt_pass *pass)
1664 while (pass)
1666 /* Recurse into child passes. */
1667 delete_pass_tree (pass->sub);
1669 opt_pass *next = pass->next;
1671 /* Delete this pass. */
1672 delete pass;
1674 /* Iterate onto sibling passes. */
1675 pass = next;
1679 pass_manager::~pass_manager ()
1681 XDELETEVEC (passes_by_id);
1683 /* Call delete_pass_tree on each of the pass_lists. */
1684 #define DEF_PASS_LIST(LIST) \
1685 delete_pass_tree (*pass_lists[PASS_LIST_NO_##LIST]);
1686 GCC_PASS_LISTS
1687 #undef DEF_PASS_LIST
1689 delete m_name_to_pass_map;
1692 /* If we are in IPA mode (i.e., current_function_decl is NULL), call
1693 function CALLBACK for every function in the call graph. Otherwise,
1694 call CALLBACK on the current function. */
1696 static void
1697 do_per_function (void (*callback) (function *, void *data), void *data)
1699 if (current_function_decl)
1700 callback (cfun, data);
1701 else
1703 struct cgraph_node *node;
1704 FOR_EACH_DEFINED_FUNCTION (node)
1705 if (node->analyzed && (gimple_has_body_p (node->decl) && !in_lto_p)
1706 && (!node->clone_of || node->decl != node->clone_of->decl))
1707 callback (DECL_STRUCT_FUNCTION (node->decl), data);
1711 /* Hook called when NODE is removed and therefore should be
1712 excluded from order vector. DATA is a hash set with removed nodes. */
1714 static void
1715 remove_cgraph_node_from_order (cgraph_node *node, void *data)
1717 hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
1718 removed_nodes->add (node);
1721 /* Hook called when NODE is insert and therefore should be
1722 excluded from removed_nodes. DATA is a hash set with removed nodes. */
1724 static void
1725 insert_cgraph_node_to_order (cgraph_node *node, void *data)
1727 hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
1728 removed_nodes->remove (node);
1731 /* Hook called when NODE is duplicated and therefore should be
1732 excluded from removed_nodes. DATA is a hash set with removed nodes. */
1734 static void
1735 duplicate_cgraph_node_to_order (cgraph_node *node, cgraph_node *node2,
1736 void *data)
1738 hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
1739 gcc_checking_assert (!removed_nodes->contains (node));
1740 removed_nodes->remove (node2);
1744 /* If we are in IPA mode (i.e., current_function_decl is NULL), call
1745 function CALLBACK for every function in the call graph. Otherwise,
1746 call CALLBACK on the current function.
1747 This function is global so that plugins can use it. */
1748 void
1749 do_per_function_toporder (void (*callback) (function *, void *data), void *data)
1751 int i;
1753 if (current_function_decl)
1754 callback (cfun, data);
1755 else
1757 hash_set<cgraph_node *> removed_nodes;
1758 unsigned nnodes = symtab->cgraph_count;
1759 cgraph_node **order = XNEWVEC (cgraph_node *, nnodes);
1761 nnodes = ipa_reverse_postorder (order);
1762 for (i = nnodes - 1; i >= 0; i--)
1763 order[i]->process = 1;
1764 cgraph_node_hook_list *removal_hook
1765 = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
1766 &removed_nodes);
1767 cgraph_node_hook_list *insertion_hook
1768 = symtab->add_cgraph_insertion_hook (insert_cgraph_node_to_order,
1769 &removed_nodes);
1770 cgraph_2node_hook_list *duplication_hook
1771 = symtab->add_cgraph_duplication_hook (duplicate_cgraph_node_to_order,
1772 &removed_nodes);
1773 for (i = nnodes - 1; i >= 0; i--)
1775 cgraph_node *node = order[i];
1777 /* Function could be inlined and removed as unreachable. */
1778 if (node == NULL || removed_nodes.contains (node))
1779 continue;
1781 node->process = 0;
1782 if (node->has_gimple_body_p ())
1784 struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
1785 push_cfun (fn);
1786 callback (fn, data);
1787 pop_cfun ();
1790 symtab->remove_cgraph_removal_hook (removal_hook);
1791 symtab->remove_cgraph_insertion_hook (insertion_hook);
1792 symtab->remove_cgraph_duplication_hook (duplication_hook);
1794 free (order);
1798 /* Helper function to perform function body dump. */
1800 static void
1801 execute_function_dump (function *fn, void *data)
1803 opt_pass *pass = (opt_pass *)data;
1805 if (dump_file)
1807 push_cfun (fn);
1809 if (fn->curr_properties & PROP_gimple)
1810 dump_function_to_file (fn->decl, dump_file, dump_flags);
1811 else
1812 print_rtl_with_bb (dump_file, get_insns (), dump_flags);
1814 /* Flush the file. If verification fails, we won't be able to
1815 close the file before aborting. */
1816 fflush (dump_file);
1818 if ((fn->curr_properties & PROP_cfg)
1819 && (dump_flags & TDF_GRAPH))
1821 gcc::dump_manager *dumps = g->get_dumps ();
1822 struct dump_file_info *dfi
1823 = dumps->get_dump_file_info (pass->static_pass_number);
1824 if (!dfi->graph_dump_initialized)
1826 clean_graph_dump_file (dump_file_name);
1827 dfi->graph_dump_initialized = true;
1829 print_graph_cfg (dump_file_name, fn);
1832 pop_cfun ();
1836 /* This function is called when an internal compiler error is encountered.
1837 Ensure that function dump is made available before compiler is aborted. */
1839 void
1840 emergency_dump_function ()
1842 if (!current_pass)
1843 return;
1844 enum opt_pass_type pt = current_pass->type;
1845 fnotice (stderr, "during %s pass: %s\n",
1846 pt == GIMPLE_PASS ? "GIMPLE" : pt == RTL_PASS ? "RTL" : "IPA",
1847 current_pass->name);
1848 if (!dump_file || !cfun)
1849 return;
1850 fnotice (stderr, "dump file: %s\n", dump_file_name);
1851 fprintf (dump_file, "\n\n\nEMERGENCY DUMP:\n\n");
1852 execute_function_dump (cfun, current_pass);
1854 /* Normally the passmanager will close the graphs as a pass could be wanting
1855 to print multiple digraphs. But during an emergency dump there can only be
1856 one and we must finish the graph manually. */
1857 if ((cfun->curr_properties & PROP_cfg)
1858 && (dump_flags & TDF_GRAPH))
1859 finish_graph_dump_file (dump_file_name);
1861 if (symtab && current_pass->type == IPA_PASS)
1862 symtab->dump (dump_file);
1865 static struct profile_record *profile_record;
1867 /* Do profile consistency book-keeping for the pass with static number INDEX.
1868 RUN is true if the pass really runs, or FALSE
1869 if we are only book-keeping on passes that may have selectively disabled
1870 themselves on a given function. */
1872 static void
1873 check_profile_consistency (int index, bool run)
1875 pass_manager *passes = g->get_passes ();
1876 if (index == -1)
1877 return;
1878 if (!profile_record)
1879 profile_record = XCNEWVEC (struct profile_record,
1880 passes->passes_by_id_size);
1881 gcc_assert (index < passes->passes_by_id_size && index >= 0);
1882 profile_record[index].run |= run;
1883 profile_record_check_consistency (&profile_record[index]);
1886 /* Account profile the pass with static number INDEX.
1887 RUN is true if the pass really runs, or FALSE
1888 if we are only book-keeping on passes that may have selectively disabled
1889 themselves on a given function. */
1891 static void
1892 account_profile (int index, bool run)
1894 pass_manager *passes = g->get_passes ();
1895 if (index == -1)
1896 return;
1897 if (!profile_record)
1898 profile_record = XCNEWVEC (struct profile_record,
1899 passes->passes_by_id_size);
1900 gcc_assert (index < passes->passes_by_id_size && index >= 0);
1901 profile_record[index].run |= run;
1902 profile_record_account_profile (&profile_record[index]);
1905 /* Account profile for IPA pass. Callback for do_per_function. */
1907 static void
1908 account_profile_1 (function *fn, void *data)
1910 opt_pass *pass = (opt_pass *)data;
1912 push_cfun (fn);
1913 check_profile_consistency (pass->static_pass_number, true);
1914 account_profile (pass->static_pass_number, true);
1915 pop_cfun ();
1918 /* Account profile chnages to all passes in list starting in SUB. */
1920 static void
1921 account_profile_in_list (opt_pass *sub)
1923 for (; sub; sub = sub->next)
1925 check_profile_consistency (sub->static_pass_number, false);
1926 account_profile (sub->static_pass_number, false);
1927 if (sub->sub)
1928 account_profile_in_list (sub->sub);
1932 /* Output profile consistency. */
1934 void
1935 dump_profile_report (void)
1937 g->get_passes ()->dump_profile_report ();
1940 void
1941 pass_manager::dump_profile_report () const
1943 int last_count_in = 0, last_prob_out = 0;
1944 double last_dyn_count_in = 0, last_dyn_prob_out = 0;
1945 double last_time = 0;
1946 int last_size = 0;
1947 double rel_time_change, rel_size_change;
1948 gcc::dump_manager *dumps = m_ctxt->get_dumps ();
1950 if (!profile_record)
1951 return;
1953 FILE *dump_file = dump_begin (TDI_profile_report, NULL);
1954 if (dump_file == NULL)
1955 dump_file = stderr;
1957 fprintf (dump_file, "Profile consistency report:\n\n");
1958 fprintf (dump_file,
1959 "Pass dump id and name |static mismatch "
1960 "|dynamic mismatch "
1961 "|overall |\n");
1962 fprintf (dump_file,
1963 " |in count |out prob "
1964 "|in count |out prob "
1965 "|size |time |\n");
1967 for (int i = 1; i < passes_by_id_size; i++)
1968 if (profile_record[i].run)
1970 if (last_time)
1971 rel_time_change = (profile_record[i].time
1972 - last_time) * 100 / last_time;
1973 else
1974 rel_time_change = 0;
1975 if (last_size)
1976 rel_size_change = (profile_record[i].size
1977 - (double)last_size) * 100 / (double)last_size;
1978 else
1979 rel_size_change = 0;
1981 dump_file_info *dfi = dumps->get_dump_file_info (i);
1983 fprintf (dump_file, "%3i%c %-28s| %6i",
1984 dfi->num,
1985 passes_by_id[i]->type == GIMPLE_PASS ? 't'
1986 : passes_by_id[i]->type == RTL_PASS ? 'r'
1987 : 'i',
1988 passes_by_id[i]->name,
1989 profile_record[i].num_mismatched_count_in);
1990 if (profile_record[i].num_mismatched_count_in != last_count_in)
1991 fprintf (dump_file, " %+5i",
1992 profile_record[i].num_mismatched_count_in
1993 - last_count_in);
1994 else
1995 fprintf (dump_file, " ");
1996 fprintf (dump_file, "| %6i",
1997 profile_record[i].num_mismatched_prob_out);
1998 if (profile_record[i].num_mismatched_prob_out != last_prob_out)
1999 fprintf (dump_file, " %+5i",
2000 profile_record[i].num_mismatched_prob_out
2001 - last_prob_out);
2002 else
2003 fprintf (dump_file, " ");
2005 fprintf (dump_file, "| %12.0f",
2006 profile_record[i].dyn_mismatched_count_in);
2007 if (profile_record[i].dyn_mismatched_count_in != last_dyn_count_in)
2008 fprintf (dump_file, " %+12.0f",
2009 profile_record[i].dyn_mismatched_count_in
2010 - last_dyn_count_in);
2011 else
2012 fprintf (dump_file, " ");
2013 fprintf (dump_file, "| %12.0f",
2014 profile_record[i].dyn_mismatched_prob_out);
2015 if (profile_record[i].dyn_mismatched_prob_out != last_dyn_prob_out)
2016 fprintf (dump_file, " %+12.0f",
2017 profile_record[i].dyn_mismatched_prob_out
2018 - last_dyn_prob_out);
2019 else
2020 fprintf (dump_file, " ");
2022 /* Size/time units change across gimple and RTL. */
2023 if (i == pass_expand_1->static_pass_number)
2024 fprintf (dump_file,
2025 "|-------------------|--------------------------");
2026 else
2028 fprintf (dump_file, "| %8i", profile_record[i].size);
2029 if (rel_size_change)
2030 fprintf (dump_file, " %+8.1f%%", rel_size_change);
2031 else
2032 fprintf (dump_file, " ");
2033 fprintf (dump_file, "| %12.0f", profile_record[i].time);
2034 /* Time units changes with profile estimate and feedback. */
2035 if (i == pass_profile_1->static_pass_number
2036 || i == pass_ipa_tree_profile_1->static_pass_number)
2037 fprintf (dump_file, "-------------");
2038 else if (rel_time_change)
2039 fprintf (dump_file, " %+11.1f%%", rel_time_change);
2040 else
2041 fprintf (dump_file, " ");
2043 fprintf (dump_file, "|\n");
2044 last_prob_out = profile_record[i].num_mismatched_prob_out;
2045 last_count_in = profile_record[i].num_mismatched_count_in;
2046 last_dyn_prob_out = profile_record[i].dyn_mismatched_prob_out;
2047 last_dyn_count_in = profile_record[i].dyn_mismatched_count_in;
2048 last_time = profile_record[i].time;
2049 last_size = profile_record[i].size;
2052 dump_end (TDI_profile_report, dump_file);
2055 /* Perform all TODO actions that ought to be done on each function. */
2057 static void
2058 execute_function_todo (function *fn, void *data)
2060 bool from_ipa_pass = (cfun == NULL);
2061 unsigned int flags = (size_t)data;
2062 flags &= ~fn->last_verified;
2063 if (!flags)
2064 return;
2066 push_cfun (fn);
2068 /* If we need to cleanup the CFG let it perform a needed SSA update. */
2069 if (flags & TODO_cleanup_cfg)
2070 cleanup_tree_cfg (flags & TODO_update_ssa_any);
2071 else if (flags & TODO_update_ssa_any)
2072 update_ssa (flags & TODO_update_ssa_any);
2073 gcc_assert (!need_ssa_update_p (fn));
2075 if (flag_tree_pta && (flags & TODO_rebuild_alias))
2076 compute_may_aliases ();
2078 if (optimize && (flags & TODO_update_address_taken))
2079 execute_update_addresses_taken ();
2081 if (flags & TODO_remove_unused_locals)
2082 remove_unused_locals ();
2084 if (flags & TODO_rebuild_cgraph_edges)
2085 cgraph_edge::rebuild_edges ();
2087 gcc_assert (dom_info_state (fn, CDI_POST_DOMINATORS) == DOM_NONE);
2088 /* If we've seen errors do not bother running any verifiers. */
2089 if (flag_checking && !seen_error ())
2091 dom_state pre_verify_state = dom_info_state (fn, CDI_DOMINATORS);
2092 dom_state pre_verify_pstate = dom_info_state (fn, CDI_POST_DOMINATORS);
2094 if (flags & TODO_verify_il)
2096 if (cfun->curr_properties & PROP_gimple)
2098 if (cfun->curr_properties & PROP_cfg)
2099 /* IPA passes leave stmts to be fixed up, so make sure to
2100 not verify stmts really throw. */
2101 verify_gimple_in_cfg (cfun, !from_ipa_pass);
2102 else
2103 verify_gimple_in_seq (gimple_body (cfun->decl));
2105 if (cfun->curr_properties & PROP_ssa)
2106 /* IPA passes leave stmts to be fixed up, so make sure to
2107 not verify SSA operands whose verifier will choke on that. */
2108 verify_ssa (true, !from_ipa_pass);
2109 /* IPA passes leave basic-blocks unsplit, so make sure to
2110 not trip on that. */
2111 if ((cfun->curr_properties & PROP_cfg)
2112 && !from_ipa_pass)
2113 verify_flow_info ();
2114 if (current_loops
2115 && ! loops_state_satisfies_p (LOOPS_NEED_FIXUP))
2117 verify_loop_structure ();
2118 if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
2119 verify_loop_closed_ssa (false);
2121 if (cfun->curr_properties & PROP_rtl)
2122 verify_rtl_sharing ();
2125 /* Make sure verifiers don't change dominator state. */
2126 gcc_assert (dom_info_state (fn, CDI_DOMINATORS) == pre_verify_state);
2127 gcc_assert (dom_info_state (fn, CDI_POST_DOMINATORS) == pre_verify_pstate);
2130 fn->last_verified = flags & TODO_verify_all;
2132 pop_cfun ();
2134 /* For IPA passes make sure to release dominator info, it can be
2135 computed by non-verifying TODOs. */
2136 if (from_ipa_pass)
2138 free_dominance_info (fn, CDI_DOMINATORS);
2139 free_dominance_info (fn, CDI_POST_DOMINATORS);
2143 /* Perform all TODO actions. */
2144 static void
2145 execute_todo (unsigned int flags)
2147 if (flag_checking
2148 && cfun
2149 && need_ssa_update_p (cfun))
2150 gcc_assert (flags & TODO_update_ssa_any);
2152 statistics_fini_pass ();
2154 if (flags)
2155 do_per_function (execute_function_todo, (void *)(size_t) flags);
2157 /* At this point we should not have any unreachable code in the
2158 CFG, so it is safe to flush the pending freelist for SSA_NAMES. */
2159 if (cfun && cfun->gimple_df)
2160 flush_ssaname_freelist ();
2162 /* Always remove functions just as before inlining: IPA passes might be
2163 interested to see bodies of extern inline functions that are not inlined
2164 to analyze side effects. The full removal is done just at the end
2165 of IPA pass queue. */
2166 if (flags & TODO_remove_functions)
2168 gcc_assert (!cfun);
2169 symtab->remove_unreachable_nodes (dump_file);
2172 if ((flags & TODO_dump_symtab) && dump_file && !current_function_decl)
2174 gcc_assert (!cfun);
2175 symtab->dump (dump_file);
2176 /* Flush the file. If verification fails, we won't be able to
2177 close the file before aborting. */
2178 fflush (dump_file);
2181 /* Now that the dumping has been done, we can get rid of the optional
2182 df problems. */
2183 if (flags & TODO_df_finish)
2184 df_finish_pass ((flags & TODO_df_verify) != 0);
2187 /* Verify invariants that should hold between passes. This is a place
2188 to put simple sanity checks. */
2190 static void
2191 verify_interpass_invariants (void)
2193 gcc_checking_assert (!fold_deferring_overflow_warnings_p ());
2196 /* Clear the last verified flag. */
2198 static void
2199 clear_last_verified (function *fn, void *data ATTRIBUTE_UNUSED)
2201 fn->last_verified = 0;
2204 /* Helper function. Verify that the properties has been turn into the
2205 properties expected by the pass. */
2207 static void
2208 verify_curr_properties (function *fn, void *data)
2210 unsigned int props = (size_t)data;
2211 gcc_assert ((fn->curr_properties & props) == props);
2214 /* Release dump file name if set. */
2216 static void
2217 release_dump_file_name (void)
2219 if (dump_file_name)
2221 free (CONST_CAST (char *, dump_file_name));
2222 dump_file_name = NULL;
2226 /* Initialize pass dump file. */
2227 /* This is non-static so that the plugins can use it. */
2229 bool
2230 pass_init_dump_file (opt_pass *pass)
2232 /* If a dump file name is present, open it if enabled. */
2233 if (pass->static_pass_number != -1)
2235 timevar_push (TV_DUMP);
2236 gcc::dump_manager *dumps = g->get_dumps ();
2237 bool initializing_dump =
2238 !dumps->dump_initialized_p (pass->static_pass_number);
2239 release_dump_file_name ();
2240 dump_file_name = dumps->get_dump_file_name (pass->static_pass_number);
2241 dumps->dump_start (pass->static_pass_number, &dump_flags);
2242 if (dump_file && current_function_decl && ! (dump_flags & TDF_GIMPLE))
2243 dump_function_header (dump_file, current_function_decl, dump_flags);
2244 if (initializing_dump
2245 && dump_file && (dump_flags & TDF_GRAPH)
2246 && cfun && (cfun->curr_properties & PROP_cfg))
2248 clean_graph_dump_file (dump_file_name);
2249 struct dump_file_info *dfi
2250 = dumps->get_dump_file_info (pass->static_pass_number);
2251 dfi->graph_dump_initialized = true;
2253 timevar_pop (TV_DUMP);
2254 return initializing_dump;
2256 else
2257 return false;
2260 /* Flush PASS dump file. */
2261 /* This is non-static so that plugins can use it. */
2263 void
2264 pass_fini_dump_file (opt_pass *pass)
2266 timevar_push (TV_DUMP);
2268 /* Flush and close dump file. */
2269 release_dump_file_name ();
2271 g->get_dumps ()->dump_finish (pass->static_pass_number);
2272 timevar_pop (TV_DUMP);
2275 /* After executing the pass, apply expected changes to the function
2276 properties. */
2278 static void
2279 update_properties_after_pass (function *fn, void *data)
2281 opt_pass *pass = (opt_pass *) data;
2282 fn->curr_properties = (fn->curr_properties | pass->properties_provided)
2283 & ~pass->properties_destroyed;
2286 /* Execute summary generation for all of the passes in IPA_PASS. */
2288 void
2289 execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
2291 while (ipa_pass)
2293 opt_pass *pass = ipa_pass;
2295 /* Execute all of the IPA_PASSes in the list. */
2296 if (ipa_pass->type == IPA_PASS
2297 && pass->gate (cfun)
2298 && ipa_pass->generate_summary)
2300 pass_init_dump_file (pass);
2302 /* If a timevar is present, start it. */
2303 if (pass->tv_id)
2304 timevar_push (pass->tv_id);
2306 current_pass = pass;
2307 ipa_pass->generate_summary ();
2309 /* Stop timevar. */
2310 if (pass->tv_id)
2311 timevar_pop (pass->tv_id);
2313 pass_fini_dump_file (pass);
2315 ipa_pass = (ipa_opt_pass_d *)ipa_pass->next;
2319 /* Execute IPA_PASS function transform on NODE. */
2321 static void
2322 execute_one_ipa_transform_pass (struct cgraph_node *node,
2323 ipa_opt_pass_d *ipa_pass, bool do_not_collect)
2325 opt_pass *pass = ipa_pass;
2326 unsigned int todo_after = 0;
2328 current_pass = pass;
2329 if (!ipa_pass->function_transform)
2330 return;
2332 /* Note that the folders should only create gimple expressions.
2333 This is a hack until the new folder is ready. */
2334 in_gimple_form = (cfun && (cfun->curr_properties & PROP_gimple)) != 0;
2336 pass_init_dump_file (pass);
2338 /* If a timevar is present, start it. */
2339 if (pass->tv_id != TV_NONE)
2340 timevar_push (pass->tv_id);
2342 /* Run pre-pass verification. */
2343 execute_todo (ipa_pass->function_transform_todo_flags_start);
2345 /* Do it! */
2346 todo_after = ipa_pass->function_transform (node);
2348 /* Run post-pass cleanup and verification. */
2349 execute_todo (todo_after);
2350 verify_interpass_invariants ();
2352 /* Stop timevar. */
2353 if (pass->tv_id != TV_NONE)
2354 timevar_pop (pass->tv_id);
2356 if (dump_file)
2357 do_per_function (execute_function_dump, pass);
2358 pass_fini_dump_file (pass);
2360 current_pass = NULL;
2361 redirect_edge_var_map_empty ();
2363 /* Signal this is a suitable GC collection point. */
2364 if (!do_not_collect && !(todo_after & TODO_do_not_ggc_collect))
2365 ggc_collect ();
2368 /* For the current function, execute all ipa transforms. */
2370 void
2371 execute_all_ipa_transforms (bool do_not_collect)
2373 struct cgraph_node *node;
2374 node = cgraph_node::get (current_function_decl);
2377 cgraph_node *next_clone;
2378 for (cgraph_node *n = node->clones; n; n = next_clone)
2380 next_clone = n->next_sibling_clone;
2381 if (n->decl != node->decl)
2382 n->materialize_clone ();
2385 int j = 0;
2386 gcc::pass_manager *passes = g->get_passes ();
2387 bool report = profile_report && (cfun->curr_properties & PROP_gimple) != 0;
2389 if (report)
2390 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2392 for (auto p : node->ipa_transforms_to_apply)
2394 /* To get consistent statistics, we need to account each functio
2395 to each IPA pass. */
2396 if (report)
2398 for (;j < p->static_pass_number; j++)
2399 if (passes->get_pass_for_id (j)
2400 && passes->get_pass_for_id (j)->type == IPA_PASS
2401 && ((ipa_opt_pass_d *)passes->get_pass_for_id (j))
2402 ->function_transform)
2404 check_profile_consistency (j, true);
2405 account_profile (j, true);
2407 gcc_checking_assert (passes->get_pass_for_id (j) == p);
2409 execute_one_ipa_transform_pass (node, p, do_not_collect);
2411 /* Account remaining IPA passes. */
2412 if (report)
2414 for (;!passes->get_pass_for_id (j)
2415 || passes->get_pass_for_id (j)->type != RTL_PASS; j++)
2416 if (passes->get_pass_for_id (j)
2417 && passes->get_pass_for_id (j)->type == IPA_PASS
2418 && ((ipa_opt_pass_d *)passes->get_pass_for_id (j))
2419 ->function_transform)
2421 check_profile_consistency (j, true);
2422 account_profile (j, true);
2424 pop_cfun ();
2426 node->ipa_transforms_to_apply.release ();
2429 /* Check if PASS is explicitly disabled or enabled and return
2430 the gate status. FUNC is the function to be processed, and
2431 GATE_STATUS is the gate status determined by pass manager by
2432 default. */
2434 static bool
2435 override_gate_status (opt_pass *pass, tree func, bool gate_status)
2437 bool explicitly_enabled = false;
2438 bool explicitly_disabled = false;
2440 explicitly_enabled
2441 = is_pass_explicitly_enabled_or_disabled (pass, func,
2442 enabled_pass_uid_range_tab);
2443 explicitly_disabled
2444 = is_pass_explicitly_enabled_or_disabled (pass, func,
2445 disabled_pass_uid_range_tab);
2447 gate_status = !explicitly_disabled && (gate_status || explicitly_enabled);
2449 return gate_status;
2452 /* Determine if PASS_NAME matches CRITERION.
2453 Not a pure predicate, since it can update CRITERION, to support
2454 matching the Nth invocation of a pass.
2455 Subroutine of should_skip_pass_p. */
2457 static bool
2458 determine_pass_name_match (const char *pass_name, char *criterion)
2460 size_t namelen = strlen (pass_name);
2461 if (! strncmp (pass_name, criterion, namelen))
2463 /* The following supports starting with the Nth invocation
2464 of a pass (where N does not necessarily is equal to the
2465 dump file suffix). */
2466 if (criterion[namelen] == '\0'
2467 || (criterion[namelen] == '1'
2468 && criterion[namelen + 1] == '\0'))
2469 return true;
2470 else
2472 if (criterion[namelen + 1] == '\0')
2473 --criterion[namelen];
2474 return false;
2477 else
2478 return false;
2481 /* For skipping passes until "startwith" pass.
2482 Return true iff PASS should be skipped.
2483 Clear cfun->pass_startwith when encountering the "startwith" pass,
2484 so that all subsequent passes are run. */
2486 static bool
2487 should_skip_pass_p (opt_pass *pass)
2489 if (!cfun)
2490 return false;
2491 if (!cfun->pass_startwith)
2492 return false;
2494 /* For __GIMPLE functions, we have to at least start when we leave
2495 SSA. Hence, we need to detect the "expand" pass, and stop skipping
2496 when we encounter it. A cheap way to identify "expand" is it to
2497 detect the destruction of PROP_ssa.
2498 For __RTL functions, we invoke "rest_of_compilation" directly, which
2499 is after "expand", and hence we don't reach this conditional. */
2500 if (pass->properties_destroyed & PROP_ssa)
2502 if (!quiet_flag)
2503 fprintf (stderr, "starting anyway when leaving SSA: %s\n", pass->name);
2504 cfun->pass_startwith = NULL;
2505 return false;
2508 if (determine_pass_name_match (pass->name, cfun->pass_startwith))
2510 if (!quiet_flag)
2511 fprintf (stderr, "found starting pass: %s\n", pass->name);
2512 cfun->pass_startwith = NULL;
2513 return false;
2516 /* For GIMPLE passes, run any property provider (but continue skipping
2517 afterwards).
2518 We don't want to force running RTL passes that are property providers:
2519 "expand" is covered above, and the only pass other than "expand" that
2520 provides a property is "into_cfglayout" (PROP_cfglayout), which does
2521 too much for a dumped __RTL function. */
2522 if (pass->type == GIMPLE_PASS
2523 && pass->properties_provided != 0)
2524 return false;
2526 /* We need to (re-)build cgraph edges as needed. */
2527 if (strstr (pass->name, "build_cgraph_edges") != NULL)
2528 return false;
2530 /* We need to run ISEL as that lowers VEC_COND_EXPR but doesn't provide
2531 a property. */
2532 if (strstr (pass->name, "isel") != NULL)
2533 return false;
2535 /* Don't skip df init; later RTL passes need it. */
2536 if (strstr (pass->name, "dfinit") != NULL
2537 || strstr (pass->name, "dfinish") != NULL)
2538 return false;
2540 if (!quiet_flag)
2541 fprintf (stderr, "skipping pass: %s\n", pass->name);
2543 /* If we get here, then we have a "startwith" that we haven't seen yet;
2544 skip the pass. */
2545 return true;
2548 /* Skip the given pass, for handling passes before "startwith"
2549 in __GIMPLE and__RTL-marked functions.
2550 In theory, this ought to be a no-op, but some of the RTL passes
2551 need additional processing here. */
2553 static void
2554 skip_pass (opt_pass *pass)
2556 /* Pass "reload" sets the global "reload_completed", and many
2557 things depend on this (e.g. instructions in .md files). */
2558 if (strcmp (pass->name, "reload") == 0)
2559 reload_completed = 1;
2561 /* Similar for pass "pro_and_epilogue" and the "epilogue_completed" global
2562 variable. */
2563 if (strcmp (pass->name, "pro_and_epilogue") == 0)
2564 epilogue_completed = 1;
2566 /* The INSN_ADDRESSES vec is normally set up by
2567 shorten_branches; set it up for the benefit of passes that
2568 run after this. */
2569 if (strcmp (pass->name, "shorten") == 0)
2570 INSN_ADDRESSES_ALLOC (get_max_uid ());
2572 /* Update the cfg hooks as appropriate. */
2573 if (strcmp (pass->name, "into_cfglayout") == 0)
2575 cfg_layout_rtl_register_cfg_hooks ();
2576 cfun->curr_properties |= PROP_cfglayout;
2578 if (strcmp (pass->name, "outof_cfglayout") == 0)
2580 rtl_register_cfg_hooks ();
2581 cfun->curr_properties &= ~PROP_cfglayout;
2585 /* Execute PASS. */
2587 bool
2588 execute_one_pass (opt_pass *pass)
2590 unsigned int todo_after = 0;
2592 bool gate_status;
2594 /* IPA passes are executed on whole program, so cfun should be NULL.
2595 Other passes need function context set. */
2596 if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
2597 gcc_assert (!cfun && !current_function_decl);
2598 else
2599 gcc_assert (cfun && current_function_decl);
2601 current_pass = pass;
2603 /* Check whether gate check should be avoided.
2604 User controls the value of the gate through the parameter "gate_status". */
2605 gate_status = pass->gate (cfun);
2606 gate_status = override_gate_status (pass, current_function_decl, gate_status);
2608 /* Override gate with plugin. */
2609 invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status);
2611 if (!gate_status)
2613 /* Run so passes selectively disabling themselves on a given function
2614 are not miscounted. */
2615 if (profile_report && cfun && (cfun->curr_properties & PROP_cfg)
2616 && pass->type != IPA_PASS && pass->type != SIMPLE_IPA_PASS)
2618 check_profile_consistency (pass->static_pass_number, false);
2619 account_profile (pass->static_pass_number, false);
2620 if (pass->sub)
2621 account_profile_in_list (pass->sub);
2623 current_pass = NULL;
2624 return false;
2627 if (should_skip_pass_p (pass))
2629 skip_pass (pass);
2630 return true;
2633 /* Pass execution event trigger: useful to identify passes being
2634 executed. */
2635 invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
2637 if (!quiet_flag && !cfun)
2638 fprintf (stderr, " <%s>", pass->name ? pass->name : "");
2640 /* Note that the folders should only create gimple expressions.
2641 This is a hack until the new folder is ready. */
2642 in_gimple_form = (cfun && (cfun->curr_properties & PROP_gimple)) != 0;
2644 pass_init_dump_file (pass);
2646 /* If a timevar is present, start it. */
2647 if (pass->tv_id != TV_NONE)
2648 timevar_push (pass->tv_id);
2651 /* Run pre-pass verification. */
2652 execute_todo (pass->todo_flags_start);
2654 if (flag_checking)
2655 do_per_function (verify_curr_properties,
2656 (void *)(size_t)pass->properties_required);
2658 /* Do it! */
2659 todo_after = pass->execute (cfun);
2661 if (todo_after & TODO_discard_function)
2663 /* Stop timevar. */
2664 if (pass->tv_id != TV_NONE)
2665 timevar_pop (pass->tv_id);
2667 pass_fini_dump_file (pass);
2669 gcc_assert (cfun);
2670 /* As cgraph_node::release_body expects release dominators info,
2671 we have to release it. */
2672 if (dom_info_available_p (CDI_DOMINATORS))
2673 free_dominance_info (CDI_DOMINATORS);
2675 if (dom_info_available_p (CDI_POST_DOMINATORS))
2676 free_dominance_info (CDI_POST_DOMINATORS);
2678 if (cfun->assume_function)
2680 /* For assume functions, don't release body, keep it around. */
2681 cfun->curr_properties |= PROP_assumptions_done;
2682 pop_cfun ();
2683 current_pass = NULL;
2684 return true;
2687 tree fn = cfun->decl;
2688 pop_cfun ();
2689 gcc_assert (!cfun);
2690 cgraph_node::get (fn)->release_body ();
2692 current_pass = NULL;
2693 redirect_edge_var_map_empty ();
2695 ggc_collect ();
2697 return true;
2700 do_per_function (clear_last_verified, NULL);
2702 do_per_function (update_properties_after_pass, pass);
2704 /* Run post-pass cleanup and verification. */
2705 execute_todo (todo_after | pass->todo_flags_finish | TODO_verify_il);
2706 if (profile_report)
2708 /* IPA passes are accounted at transform time. */
2709 if (pass->type == IPA_PASS)
2711 else if (pass->type == SIMPLE_IPA_PASS)
2712 do_per_function (account_profile_1, pass);
2713 else if (cfun && (cfun->curr_properties & PROP_cfg))
2715 check_profile_consistency (pass->static_pass_number, true);
2716 account_profile (pass->static_pass_number, true);
2720 verify_interpass_invariants ();
2722 /* Stop timevar. */
2723 if (pass->tv_id != TV_NONE)
2724 timevar_pop (pass->tv_id);
2726 if (pass->type == IPA_PASS
2727 && ((ipa_opt_pass_d *)pass)->function_transform)
2729 struct cgraph_node *node;
2730 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
2731 if (!node->inlined_to)
2732 node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass);
2734 else if (dump_file)
2735 do_per_function (execute_function_dump, pass);
2737 if (!current_function_decl)
2738 symtab->process_new_functions ();
2740 pass_fini_dump_file (pass);
2742 if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS)
2743 gcc_assert (!(cfun->curr_properties & PROP_gimple)
2744 || pass->type != RTL_PASS);
2746 current_pass = NULL;
2747 redirect_edge_var_map_empty ();
2749 /* Signal this is a suitable GC collection point. */
2750 if (!((todo_after | pass->todo_flags_finish) & TODO_do_not_ggc_collect))
2751 ggc_collect ();
2753 if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
2754 report_heap_memory_use ();
2755 return true;
2758 static void
2759 execute_pass_list_1 (opt_pass *pass)
2763 gcc_assert (pass->type == GIMPLE_PASS
2764 || pass->type == RTL_PASS);
2766 if (cfun == NULL)
2767 return;
2768 if (execute_one_pass (pass) && pass->sub)
2769 execute_pass_list_1 (pass->sub);
2770 pass = pass->next;
2772 while (pass);
2775 void
2776 execute_pass_list (function *fn, opt_pass *pass)
2778 gcc_assert (fn == cfun);
2779 execute_pass_list_1 (pass);
2780 if (cfun && fn->cfg)
2782 free_dominance_info (CDI_DOMINATORS);
2783 free_dominance_info (CDI_POST_DOMINATORS);
2787 /* Write out all LTO data. */
2788 static void
2789 write_lto (void)
2791 timevar_push (TV_IPA_LTO_GIMPLE_OUT);
2792 lto_output ();
2793 timevar_pop (TV_IPA_LTO_GIMPLE_OUT);
2794 timevar_push (TV_IPA_LTO_DECL_OUT);
2795 produce_asm_for_decls ();
2796 timevar_pop (TV_IPA_LTO_DECL_OUT);
2799 /* Same as execute_pass_list but assume that subpasses of IPA passes
2800 are local passes. If SET is not NULL, write out summaries of only
2801 those node in SET. */
2803 static void
2804 ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
2806 while (pass)
2808 ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *)pass;
2809 gcc_assert (!current_function_decl);
2810 gcc_assert (!cfun);
2811 gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
2812 if (pass->type == IPA_PASS
2813 && ipa_pass->write_summary
2814 && pass->gate (cfun))
2816 /* If a timevar is present, start it. */
2817 if (pass->tv_id)
2818 timevar_push (pass->tv_id);
2820 pass_init_dump_file (pass);
2822 current_pass = pass;
2823 ipa_pass->write_summary ();
2825 pass_fini_dump_file (pass);
2827 /* If a timevar is present, start it. */
2828 if (pass->tv_id)
2829 timevar_pop (pass->tv_id);
2832 if (pass->sub && pass->sub->type != GIMPLE_PASS)
2833 ipa_write_summaries_2 (pass->sub, state);
2835 pass = pass->next;
2839 /* Helper function of ipa_write_summaries. Creates and destroys the
2840 decl state and calls ipa_write_summaries_2 for all passes that have
2841 summaries. SET is the set of nodes to be written. */
2843 static void
2844 ipa_write_summaries_1 (lto_symtab_encoder_t encoder,
2845 bool output_offload_tables_p)
2847 pass_manager *passes = g->get_passes ();
2848 struct lto_out_decl_state *state = lto_new_out_decl_state ();
2849 state->symtab_node_encoder = encoder;
2850 state->output_offload_tables_p = output_offload_tables_p;
2852 lto_output_init_mode_table ();
2853 lto_push_out_decl_state (state);
2855 gcc_assert (!flag_wpa);
2856 ipa_write_summaries_2 (passes->all_regular_ipa_passes, state);
2858 write_lto ();
2860 gcc_assert (lto_get_out_decl_state () == state);
2861 lto_pop_out_decl_state ();
2862 lto_delete_out_decl_state (state);
2865 /* Write out summaries for all the nodes in the callgraph. */
2867 void
2868 ipa_write_summaries (void)
2870 lto_symtab_encoder_t encoder;
2871 int i, order_pos;
2872 varpool_node *vnode;
2873 struct cgraph_node *node;
2874 struct cgraph_node **order;
2876 if ((!flag_generate_lto && !flag_generate_offload) || seen_error ())
2877 return;
2879 gcc_assert (!dump_file);
2880 streamer_dump_file = dump_begin (TDI_lto_stream_out, NULL);
2882 select_what_to_stream ();
2884 encoder = lto_symtab_encoder_new (false);
2886 /* Create the callgraph set in the same order used in
2887 cgraph_expand_all_functions. This mostly facilitates debugging,
2888 since it causes the gimple file to be processed in the same order
2889 as the source code. */
2890 order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
2891 order_pos = ipa_reverse_postorder (order);
2892 gcc_assert (order_pos == symtab->cgraph_count);
2894 for (i = order_pos - 1; i >= 0; i--)
2896 struct cgraph_node *node = order[i];
2898 if (node->definition && node->need_lto_streaming)
2900 if (gimple_has_body_p (node->decl))
2901 lto_prepare_function_for_streaming (node);
2902 lto_set_symtab_encoder_in_partition (encoder, node);
2906 FOR_EACH_DEFINED_FUNCTION (node)
2907 if (node->alias && node->need_lto_streaming)
2908 lto_set_symtab_encoder_in_partition (encoder, node);
2909 FOR_EACH_DEFINED_VARIABLE (vnode)
2910 if (vnode->need_lto_streaming)
2911 lto_set_symtab_encoder_in_partition (encoder, vnode);
2913 ipa_write_summaries_1 (compute_ltrans_boundary (encoder),
2914 flag_generate_offload);
2916 free (order);
2917 if (streamer_dump_file)
2919 dump_end (TDI_lto_stream_out, streamer_dump_file);
2920 streamer_dump_file = NULL;
2924 /* Same as execute_pass_list but assume that subpasses of IPA passes
2925 are local passes. If SET is not NULL, write out optimization summaries of
2926 only those node in SET. */
2928 static void
2929 ipa_write_optimization_summaries_1 (opt_pass *pass,
2930 struct lto_out_decl_state *state)
2932 while (pass)
2934 ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *)pass;
2935 gcc_assert (!current_function_decl);
2936 gcc_assert (!cfun);
2937 gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
2938 if (pass->type == IPA_PASS
2939 && ipa_pass->write_optimization_summary
2940 && pass->gate (cfun))
2942 /* If a timevar is present, start it. */
2943 if (pass->tv_id)
2944 timevar_push (pass->tv_id);
2946 pass_init_dump_file (pass);
2948 current_pass = pass;
2949 ipa_pass->write_optimization_summary ();
2951 pass_fini_dump_file (pass);
2953 /* If a timevar is present, start it. */
2954 if (pass->tv_id)
2955 timevar_pop (pass->tv_id);
2958 if (pass->sub && pass->sub->type != GIMPLE_PASS)
2959 ipa_write_optimization_summaries_1 (pass->sub, state);
2961 pass = pass->next;
2965 /* Write all the optimization summaries for the cgraph nodes in SET. If SET is
2966 NULL, write out all summaries of all nodes. */
2968 void
2969 ipa_write_optimization_summaries (lto_symtab_encoder_t encoder,
2970 bool output_offload_tables_p)
2972 struct lto_out_decl_state *state = lto_new_out_decl_state ();
2973 state->symtab_node_encoder = encoder;
2974 state->output_offload_tables_p = output_offload_tables_p;
2976 lto_output_init_mode_table ();
2977 lto_push_out_decl_state (state);
2979 /* Be sure that we did not forget to renumber stmt uids. */
2980 gcc_checking_assert (flag_wpa);
2982 gcc_assert (flag_wpa);
2983 pass_manager *passes = g->get_passes ();
2984 ipa_write_optimization_summaries_1 (passes->all_regular_ipa_passes, state);
2986 write_lto ();
2988 gcc_assert (lto_get_out_decl_state () == state);
2989 lto_pop_out_decl_state ();
2990 lto_delete_out_decl_state (state);
2993 /* Same as execute_pass_list but assume that subpasses of IPA passes
2994 are local passes. */
2996 static void
2997 ipa_read_summaries_1 (opt_pass *pass)
2999 while (pass)
3001 ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
3003 gcc_assert (!current_function_decl);
3004 gcc_assert (!cfun);
3005 gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
3007 if (pass->gate (cfun))
3009 if (pass->type == IPA_PASS && ipa_pass->read_summary)
3011 /* If a timevar is present, start it. */
3012 if (pass->tv_id)
3013 timevar_push (pass->tv_id);
3014 if (!quiet_flag)
3015 fprintf (stderr, " <%s>", pass->name ? pass->name : "");
3017 pass_init_dump_file (pass);
3019 current_pass = pass;
3020 ipa_pass->read_summary ();
3022 pass_fini_dump_file (pass);
3024 /* Stop timevar. */
3025 if (pass->tv_id)
3026 timevar_pop (pass->tv_id);
3027 ggc_grow ();
3028 report_heap_memory_use ();
3031 if (pass->sub && pass->sub->type != GIMPLE_PASS)
3032 ipa_read_summaries_1 (pass->sub);
3034 pass = pass->next;
3039 /* Read all the summaries for all_regular_ipa_passes. */
3041 void
3042 ipa_read_summaries (void)
3044 pass_manager *passes = g->get_passes ();
3045 ipa_read_summaries_1 (passes->all_regular_ipa_passes);
3048 /* Same as execute_pass_list but assume that subpasses of IPA passes
3049 are local passes. */
3051 static void
3052 ipa_read_optimization_summaries_1 (opt_pass *pass)
3054 while (pass)
3056 ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
3058 gcc_assert (!current_function_decl);
3059 gcc_assert (!cfun);
3060 gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
3062 if (pass->gate (cfun))
3064 if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
3066 /* If a timevar is present, start it. */
3067 if (pass->tv_id)
3068 timevar_push (pass->tv_id);
3069 if (!quiet_flag)
3070 fprintf (stderr, " <%s>", pass->name ? pass->name : "");
3072 pass_init_dump_file (pass);
3074 current_pass = pass;
3075 ipa_pass->read_optimization_summary ();
3077 pass_fini_dump_file (pass);
3079 /* Stop timevar. */
3080 if (pass->tv_id)
3081 timevar_pop (pass->tv_id);
3084 if (pass->sub && pass->sub->type != GIMPLE_PASS)
3085 ipa_read_optimization_summaries_1 (pass->sub);
3086 ggc_grow ();
3087 report_heap_memory_use ();
3089 pass = pass->next;
3093 /* Read all the summaries for all_regular_ipa_passes. */
3095 void
3096 ipa_read_optimization_summaries (void)
3098 pass_manager *passes = g->get_passes ();
3099 ipa_read_optimization_summaries_1 (passes->all_regular_ipa_passes);
3102 /* Same as execute_pass_list but assume that subpasses of IPA passes
3103 are local passes. */
3104 void
3105 execute_ipa_pass_list (opt_pass *pass)
3109 gcc_assert (!current_function_decl);
3110 gcc_assert (!cfun);
3111 gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
3112 if (execute_one_pass (pass) && pass->sub)
3114 if (pass->sub->type == GIMPLE_PASS)
3116 invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
3117 do_per_function_toporder ((void (*)(function *, void *))
3118 execute_pass_list,
3119 pass->sub);
3120 invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
3122 else if (pass->sub->type == SIMPLE_IPA_PASS
3123 || pass->sub->type == IPA_PASS)
3124 execute_ipa_pass_list (pass->sub);
3125 else
3126 gcc_unreachable ();
3128 gcc_assert (!current_function_decl);
3129 symtab->process_new_functions ();
3130 pass = pass->next;
3132 while (pass);
3135 /* Execute stmt fixup hooks of all passes in PASS for NODE and STMTS. */
3137 static void
3138 execute_ipa_stmt_fixups (opt_pass *pass,
3139 struct cgraph_node *node, gimple **stmts)
3141 while (pass)
3143 /* Execute all of the IPA_PASSes in the list. */
3144 if (pass->type == IPA_PASS
3145 && pass->gate (cfun))
3147 ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
3149 if (ipa_pass->stmt_fixup)
3151 pass_init_dump_file (pass);
3152 /* If a timevar is present, start it. */
3153 if (pass->tv_id)
3154 timevar_push (pass->tv_id);
3156 current_pass = pass;
3157 ipa_pass->stmt_fixup (node, stmts);
3159 /* Stop timevar. */
3160 if (pass->tv_id)
3161 timevar_pop (pass->tv_id);
3162 pass_fini_dump_file (pass);
3164 if (pass->sub)
3165 execute_ipa_stmt_fixups (pass->sub, node, stmts);
3167 pass = pass->next;
3171 /* Execute stmt fixup hooks of all IPA passes for NODE and STMTS. */
3173 void
3174 execute_all_ipa_stmt_fixups (struct cgraph_node *node, gimple **stmts)
3176 pass_manager *passes = g->get_passes ();
3177 execute_ipa_stmt_fixups (passes->all_regular_ipa_passes, node, stmts);
3181 extern void debug_properties (unsigned int);
3182 extern void dump_properties (FILE *, unsigned int);
3184 DEBUG_FUNCTION void
3185 dump_properties (FILE *dump, unsigned int props)
3187 fprintf (dump, "Properties:\n");
3188 if (props & PROP_gimple_any)
3189 fprintf (dump, "PROP_gimple_any\n");
3190 if (props & PROP_gimple_lcf)
3191 fprintf (dump, "PROP_gimple_lcf\n");
3192 if (props & PROP_gimple_leh)
3193 fprintf (dump, "PROP_gimple_leh\n");
3194 if (props & PROP_cfg)
3195 fprintf (dump, "PROP_cfg\n");
3196 if (props & PROP_ssa)
3197 fprintf (dump, "PROP_ssa\n");
3198 if (props & PROP_no_crit_edges)
3199 fprintf (dump, "PROP_no_crit_edges\n");
3200 if (props & PROP_rtl)
3201 fprintf (dump, "PROP_rtl\n");
3202 if (props & PROP_gimple_lomp)
3203 fprintf (dump, "PROP_gimple_lomp\n");
3204 if (props & PROP_gimple_lomp_dev)
3205 fprintf (dump, "PROP_gimple_lomp_dev\n");
3206 if (props & PROP_gimple_lcx)
3207 fprintf (dump, "PROP_gimple_lcx\n");
3208 if (props & PROP_gimple_lvec)
3209 fprintf (dump, "PROP_gimple_lvec\n");
3210 if (props & PROP_cfglayout)
3211 fprintf (dump, "PROP_cfglayout\n");
3214 DEBUG_FUNCTION void
3215 debug_properties (unsigned int props)
3217 dump_properties (stderr, props);
3220 /* Called by local passes to see if function is called by already processed nodes.
3221 Because we process nodes in topological order, this means that function is
3222 in recursive cycle or we introduced new direct calls. */
3223 bool
3224 function_called_by_processed_nodes_p (void)
3226 struct cgraph_edge *e;
3227 for (e = cgraph_node::get (current_function_decl)->callers;
3229 e = e->next_caller)
3231 if (e->caller->decl == current_function_decl)
3232 continue;
3233 if (!e->caller->has_gimple_body_p ())
3234 continue;
3235 if (TREE_ASM_WRITTEN (e->caller->decl))
3236 continue;
3237 if (!e->caller->process && !e->caller->inlined_to)
3238 break;
3240 if (dump_file && e)
3242 fprintf (dump_file, "Already processed call to:\n");
3243 e->caller->dump (dump_file);
3245 return e != NULL;