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