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