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