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