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