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