Mercurial > hg > CbC > CbC_gcc
comparison gcc/passes.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | caeb520cebed 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Top level of GCC compilers (cc1, cc1plus, etc.) | |
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, | |
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | |
4 Free Software Foundation, Inc. | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 /* This is the top level of cc1/c++. | |
23 It parses command args, opens files, invokes the various passes | |
24 in the proper order, and counts the time used by each. | |
25 Error messages and low-level interface to malloc also handled here. */ | |
26 | |
27 #include "config.h" | |
28 #undef FLOAT /* This is for hpux. They should change hpux. */ | |
29 #undef FFS /* Some systems define this in param.h. */ | |
30 #include "system.h" | |
31 #include "coretypes.h" | |
32 #include "tm.h" | |
33 #include <signal.h> | |
34 | |
35 #ifdef HAVE_SYS_RESOURCE_H | |
36 # include <sys/resource.h> | |
37 #endif | |
38 | |
39 #ifdef HAVE_SYS_TIMES_H | |
40 # include <sys/times.h> | |
41 #endif | |
42 | |
43 #include "line-map.h" | |
44 #include "input.h" | |
45 #include "tree.h" | |
46 #include "rtl.h" | |
47 #include "tm_p.h" | |
48 #include "flags.h" | |
49 #include "insn-attr.h" | |
50 #include "insn-config.h" | |
51 #include "insn-flags.h" | |
52 #include "hard-reg-set.h" | |
53 #include "recog.h" | |
54 #include "output.h" | |
55 #include "except.h" | |
56 #include "function.h" | |
57 #include "toplev.h" | |
58 #include "expr.h" | |
59 #include "basic-block.h" | |
60 #include "intl.h" | |
61 #include "ggc.h" | |
62 #include "graph.h" | |
63 #include "regs.h" | |
64 #include "timevar.h" | |
65 #include "diagnostic.h" | |
66 #include "params.h" | |
67 #include "reload.h" | |
68 #include "dwarf2asm.h" | |
69 #include "integrate.h" | |
70 #include "real.h" | |
71 #include "debug.h" | |
72 #include "target.h" | |
73 #include "langhooks.h" | |
74 #include "cfglayout.h" | |
75 #include "cfgloop.h" | |
76 #include "hosthooks.h" | |
77 #include "cgraph.h" | |
78 #include "opts.h" | |
79 #include "coverage.h" | |
80 #include "value-prof.h" | |
81 #include "tree-inline.h" | |
82 #include "tree-flow.h" | |
83 #include "tree-pass.h" | |
84 #include "tree-dump.h" | |
85 #include "df.h" | |
86 #include "predict.h" | |
87 | |
88 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) | |
89 #include "dwarf2out.h" | |
90 #endif | |
91 | |
92 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) | |
93 #include "dbxout.h" | |
94 #endif | |
95 | |
96 #ifdef SDB_DEBUGGING_INFO | |
97 #include "sdbout.h" | |
98 #endif | |
99 | |
100 #ifdef XCOFF_DEBUGGING_INFO | |
101 #include "xcoffout.h" /* Needed for external data | |
102 declarations for e.g. AIX 4.x. */ | |
103 #endif | |
104 | |
105 /* This is used for debugging. It allows the current pass to printed | |
106 from anywhere in compilation. */ | |
107 struct opt_pass *current_pass; | |
108 | |
109 /* Call from anywhere to find out what pass this is. Useful for | |
110 printing out debugging information deep inside an service | |
111 routine. */ | |
112 void | |
113 print_current_pass (FILE *file) | |
114 { | |
115 if (current_pass) | |
116 fprintf (file, "current pass = %s (%d)\n", | |
117 current_pass->name, current_pass->static_pass_number); | |
118 else | |
119 fprintf (file, "no current pass.\n"); | |
120 } | |
121 | |
122 | |
123 /* Call from the debugger to get the current pass name. */ | |
124 void | |
125 debug_pass (void) | |
126 { | |
127 print_current_pass (stderr); | |
128 } | |
129 | |
130 | |
131 | |
132 /* Global variables used to communicate with passes. */ | |
133 int dump_flags; | |
134 bool in_gimple_form; | |
135 bool first_pass_instance; | |
136 | |
137 | |
138 /* This is called from various places for FUNCTION_DECL, VAR_DECL, | |
139 and TYPE_DECL nodes. | |
140 | |
141 This does nothing for local (non-static) variables, unless the | |
142 variable is a register variable with DECL_ASSEMBLER_NAME set. In | |
143 that case, or if the variable is not an automatic, it sets up the | |
144 RTL and outputs any assembler code (label definition, storage | |
145 allocation and initialization). | |
146 | |
147 DECL is the declaration. TOP_LEVEL is nonzero | |
148 if this declaration is not within a function. */ | |
149 | |
150 void | |
151 rest_of_decl_compilation (tree decl, | |
152 int top_level, | |
153 int at_end) | |
154 { | |
155 /* We deferred calling assemble_alias so that we could collect | |
156 other attributes such as visibility. Emit the alias now. */ | |
157 { | |
158 tree alias; | |
159 alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)); | |
160 if (alias) | |
161 { | |
162 alias = TREE_VALUE (TREE_VALUE (alias)); | |
163 alias = get_identifier (TREE_STRING_POINTER (alias)); | |
164 assemble_alias (decl, alias); | |
165 } | |
166 } | |
167 | |
168 /* Can't defer this, because it needs to happen before any | |
169 later function definitions are processed. */ | |
170 if (DECL_ASSEMBLER_NAME_SET_P (decl) && DECL_REGISTER (decl)) | |
171 make_decl_rtl (decl); | |
172 | |
173 /* Forward declarations for nested functions are not "external", | |
174 but we need to treat them as if they were. */ | |
175 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) | |
176 || TREE_CODE (decl) == FUNCTION_DECL) | |
177 { | |
178 timevar_push (TV_VARCONST); | |
179 | |
180 /* Don't output anything when a tentative file-scope definition | |
181 is seen. But at end of compilation, do output code for them. | |
182 | |
183 We do output all variables and rely on | |
184 callgraph code to defer them except for forward declarations | |
185 (see gcc.c-torture/compile/920624-1.c) */ | |
186 if ((at_end | |
187 || !DECL_DEFER_OUTPUT (decl) | |
188 || DECL_INITIAL (decl)) | |
189 && !DECL_EXTERNAL (decl)) | |
190 { | |
191 if (TREE_CODE (decl) != FUNCTION_DECL) | |
192 varpool_finalize_decl (decl); | |
193 else | |
194 assemble_variable (decl, top_level, at_end, 0); | |
195 } | |
196 | |
197 #ifdef ASM_FINISH_DECLARE_OBJECT | |
198 if (decl == last_assemble_variable_decl) | |
199 { | |
200 ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, | |
201 top_level, at_end); | |
202 } | |
203 #endif | |
204 | |
205 timevar_pop (TV_VARCONST); | |
206 } | |
207 else if (TREE_CODE (decl) == TYPE_DECL | |
208 /* Like in rest_of_type_compilation, avoid confusing the debug | |
209 information machinery when there are errors. */ | |
210 && !(sorrycount || errorcount)) | |
211 { | |
212 timevar_push (TV_SYMOUT); | |
213 debug_hooks->type_decl (decl, !top_level); | |
214 timevar_pop (TV_SYMOUT); | |
215 } | |
216 | |
217 /* Let cgraph know about the existence of variables. */ | |
218 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) | |
219 varpool_node (decl); | |
220 } | |
221 | |
222 /* Called after finishing a record, union or enumeral type. */ | |
223 | |
224 void | |
225 rest_of_type_compilation (tree type, int toplev) | |
226 { | |
227 /* Avoid confusing the debug information machinery when there are | |
228 errors. */ | |
229 if (errorcount != 0 || sorrycount != 0) | |
230 return; | |
231 | |
232 timevar_push (TV_SYMOUT); | |
233 debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev); | |
234 timevar_pop (TV_SYMOUT); | |
235 } | |
236 | |
237 | |
238 | |
239 void | |
240 finish_optimization_passes (void) | |
241 { | |
242 enum tree_dump_index i; | |
243 struct dump_file_info *dfi; | |
244 char *name; | |
245 | |
246 timevar_push (TV_DUMP); | |
247 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) | |
248 { | |
249 dump_file = dump_begin (pass_profile.pass.static_pass_number, NULL); | |
250 end_branch_prob (); | |
251 if (dump_file) | |
252 dump_end (pass_profile.pass.static_pass_number, dump_file); | |
253 } | |
254 | |
255 if (optimize > 0) | |
256 { | |
257 dump_file = dump_begin (pass_combine.pass.static_pass_number, NULL); | |
258 if (dump_file) | |
259 { | |
260 dump_combine_total_stats (dump_file); | |
261 dump_end (pass_combine.pass.static_pass_number, dump_file); | |
262 } | |
263 } | |
264 | |
265 /* Do whatever is necessary to finish printing the graphs. */ | |
266 if (graph_dump_format != no_graph) | |
267 for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i) | |
268 if (dump_initialized_p (i) | |
269 && (dfi->flags & TDF_GRAPH) != 0 | |
270 && (name = get_dump_file_name (i)) != NULL) | |
271 { | |
272 finish_graph_dump_file (name); | |
273 free (name); | |
274 } | |
275 | |
276 timevar_pop (TV_DUMP); | |
277 } | |
278 | |
279 static bool | |
280 gate_rest_of_compilation (void) | |
281 { | |
282 /* Early return if there were errors. We can run afoul of our | |
283 consistency checks, and there's not really much point in fixing them. */ | |
284 return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount); | |
285 } | |
286 | |
287 struct gimple_opt_pass pass_rest_of_compilation = | |
288 { | |
289 { | |
290 GIMPLE_PASS, | |
291 NULL, /* name */ | |
292 gate_rest_of_compilation, /* gate */ | |
293 NULL, /* execute */ | |
294 NULL, /* sub */ | |
295 NULL, /* next */ | |
296 0, /* static_pass_number */ | |
297 TV_REST_OF_COMPILATION, /* tv_id */ | |
298 PROP_rtl, /* properties_required */ | |
299 0, /* properties_provided */ | |
300 0, /* properties_destroyed */ | |
301 0, /* todo_flags_start */ | |
302 TODO_ggc_collect /* todo_flags_finish */ | |
303 } | |
304 }; | |
305 | |
306 static bool | |
307 gate_postreload (void) | |
308 { | |
309 return reload_completed; | |
310 } | |
311 | |
312 struct rtl_opt_pass pass_postreload = | |
313 { | |
314 { | |
315 RTL_PASS, | |
316 NULL, /* name */ | |
317 gate_postreload, /* gate */ | |
318 NULL, /* execute */ | |
319 NULL, /* sub */ | |
320 NULL, /* next */ | |
321 0, /* static_pass_number */ | |
322 0, /* tv_id */ | |
323 PROP_rtl, /* properties_required */ | |
324 0, /* properties_provided */ | |
325 0, /* properties_destroyed */ | |
326 0, /* todo_flags_start */ | |
327 TODO_ggc_collect | TODO_verify_rtl_sharing /* todo_flags_finish */ | |
328 } | |
329 }; | |
330 | |
331 | |
332 | |
333 /* The root of the compilation pass tree, once constructed. */ | |
334 struct opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes; | |
335 | |
336 /* A map from static pass id to optimization pass. */ | |
337 struct opt_pass **passes_by_id; | |
338 int passes_by_id_size; | |
339 | |
340 /* Set the static pass number of pass PASS to ID and record that | |
341 in the mapping from static pass number to pass. */ | |
342 | |
343 static void | |
344 set_pass_for_id (int id, struct opt_pass *pass) | |
345 { | |
346 pass->static_pass_number = id; | |
347 if (passes_by_id_size <= id) | |
348 { | |
349 passes_by_id = XRESIZEVEC (struct opt_pass *, passes_by_id, id + 1); | |
350 memset (passes_by_id + passes_by_id_size, 0, | |
351 (id + 1 - passes_by_id_size) * sizeof (void *)); | |
352 passes_by_id_size = id + 1; | |
353 } | |
354 passes_by_id[id] = pass; | |
355 } | |
356 | |
357 /* Return the pass with the static pass number ID. */ | |
358 | |
359 struct opt_pass * | |
360 get_pass_for_id (int id) | |
361 { | |
362 if (id >= passes_by_id_size) | |
363 return NULL; | |
364 return passes_by_id[id]; | |
365 } | |
366 | |
367 /* Iterate over the pass tree allocating dump file numbers. We want | |
368 to do this depth first, and independent of whether the pass is | |
369 enabled or not. */ | |
370 | |
371 static void | |
372 register_one_dump_file (struct opt_pass *pass) | |
373 { | |
374 char *dot_name, *flag_name, *glob_name; | |
375 const char *prefix; | |
376 char num[10]; | |
377 int flags, id; | |
378 | |
379 /* See below in next_pass_1. */ | |
380 num[0] = '\0'; | |
381 if (pass->static_pass_number != -1) | |
382 sprintf (num, "%d", ((int) pass->static_pass_number < 0 | |
383 ? 1 : pass->static_pass_number)); | |
384 | |
385 dot_name = concat (".", pass->name, num, NULL); | |
386 if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS) | |
387 prefix = "ipa-", flags = TDF_IPA; | |
388 else if (pass->type == GIMPLE_PASS) | |
389 prefix = "tree-", flags = TDF_TREE; | |
390 else | |
391 prefix = "rtl-", flags = TDF_RTL; | |
392 | |
393 flag_name = concat (prefix, pass->name, num, NULL); | |
394 glob_name = concat (prefix, pass->name, NULL); | |
395 id = dump_register (dot_name, flag_name, glob_name, flags); | |
396 set_pass_for_id (id, pass); | |
397 } | |
398 | |
399 /* Recursive worker function for register_dump_files. */ | |
400 | |
401 static int | |
402 register_dump_files_1 (struct opt_pass *pass, int properties) | |
403 { | |
404 do | |
405 { | |
406 int new_properties = (properties | pass->properties_provided) | |
407 & ~pass->properties_destroyed; | |
408 | |
409 if (pass->name && pass->name[0] != '*') | |
410 register_one_dump_file (pass); | |
411 | |
412 if (pass->sub) | |
413 new_properties = register_dump_files_1 (pass->sub, new_properties); | |
414 | |
415 /* If we have a gate, combine the properties that we could have with | |
416 and without the pass being examined. */ | |
417 if (pass->gate) | |
418 properties &= new_properties; | |
419 else | |
420 properties = new_properties; | |
421 | |
422 pass = pass->next; | |
423 } | |
424 while (pass); | |
425 | |
426 return properties; | |
427 } | |
428 | |
429 /* Register the dump files for the pipeline starting at PASS. | |
430 PROPERTIES reflects the properties that are guaranteed to be available at | |
431 the beginning of the pipeline. */ | |
432 | |
433 static void | |
434 register_dump_files (struct opt_pass *pass,int properties) | |
435 { | |
436 pass->properties_required |= properties; | |
437 register_dump_files_1 (pass, properties); | |
438 } | |
439 | |
440 /* Add a pass to the pass list. Duplicate the pass if it's already | |
441 in the list. */ | |
442 | |
443 static struct opt_pass ** | |
444 next_pass_1 (struct opt_pass **list, struct opt_pass *pass) | |
445 { | |
446 /* A nonzero static_pass_number indicates that the | |
447 pass is already in the list. */ | |
448 if (pass->static_pass_number) | |
449 { | |
450 struct opt_pass *new_pass; | |
451 | |
452 new_pass = XNEW (struct opt_pass); | |
453 memcpy (new_pass, pass, sizeof (*new_pass)); | |
454 new_pass->next = NULL; | |
455 | |
456 new_pass->todo_flags_start &= ~TODO_mark_first_instance; | |
457 | |
458 /* Indicate to register_dump_files that this pass has duplicates, | |
459 and so it should rename the dump file. The first instance will | |
460 be -1, and be number of duplicates = -static_pass_number - 1. | |
461 Subsequent instances will be > 0 and just the duplicate number. */ | |
462 if (pass->name) | |
463 { | |
464 pass->static_pass_number -= 1; | |
465 new_pass->static_pass_number = -pass->static_pass_number; | |
466 } | |
467 | |
468 *list = new_pass; | |
469 } | |
470 else | |
471 { | |
472 pass->todo_flags_start |= TODO_mark_first_instance; | |
473 pass->static_pass_number = -1; | |
474 *list = pass; | |
475 } | |
476 | |
477 return &(*list)->next; | |
478 | |
479 } | |
480 | |
481 | |
482 /* Construct the pass tree. The sequencing of passes is driven by | |
483 the cgraph routines: | |
484 | |
485 cgraph_finalize_compilation_unit () | |
486 for each node N in the cgraph | |
487 cgraph_analyze_function (N) | |
488 cgraph_lower_function (N) -> all_lowering_passes | |
489 | |
490 If we are optimizing, cgraph_optimize is then invoked: | |
491 | |
492 cgraph_optimize () | |
493 ipa_passes () -> all_ipa_passes | |
494 cgraph_expand_all_functions () | |
495 for each node N in the cgraph | |
496 cgraph_expand_function (N) | |
497 tree_rest_of_compilation (DECL (N)) -> all_passes | |
498 */ | |
499 | |
500 void | |
501 init_optimization_passes (void) | |
502 { | |
503 struct opt_pass **p; | |
504 | |
505 #define NEXT_PASS(PASS) (p = next_pass_1 (p, &((PASS).pass))) | |
506 | |
507 /* All passes needed to lower the function into shape optimizers can | |
508 operate on. These passes are always run first on the function, but | |
509 backend might produce already lowered functions that are not processed | |
510 by these passes. */ | |
511 p = &all_lowering_passes; | |
512 NEXT_PASS (pass_remove_useless_stmts); | |
513 NEXT_PASS (pass_mudflap_1); | |
514 NEXT_PASS (pass_lower_omp); | |
515 NEXT_PASS (pass_lower_cf); | |
516 NEXT_PASS (pass_refactor_eh); | |
517 NEXT_PASS (pass_lower_eh); | |
518 NEXT_PASS (pass_build_cfg); | |
519 NEXT_PASS (pass_lower_complex_O0); | |
520 NEXT_PASS (pass_lower_vector); | |
521 NEXT_PASS (pass_warn_function_return); | |
522 NEXT_PASS (pass_build_cgraph_edges); | |
523 NEXT_PASS (pass_inline_parameters); | |
524 *p = NULL; | |
525 | |
526 /* Interprocedural optimization passes. */ | |
527 p = &all_ipa_passes; | |
528 NEXT_PASS (pass_ipa_function_and_variable_visibility); | |
529 NEXT_PASS (pass_ipa_early_inline); | |
530 { | |
531 struct opt_pass **p = &pass_ipa_early_inline.pass.sub; | |
532 NEXT_PASS (pass_early_inline); | |
533 NEXT_PASS (pass_inline_parameters); | |
534 NEXT_PASS (pass_rebuild_cgraph_edges); | |
535 } | |
536 NEXT_PASS (pass_early_local_passes); | |
537 { | |
538 struct opt_pass **p = &pass_early_local_passes.pass.sub; | |
539 NEXT_PASS (pass_tree_profile); | |
540 NEXT_PASS (pass_cleanup_cfg); | |
541 NEXT_PASS (pass_init_datastructures); | |
542 NEXT_PASS (pass_expand_omp); | |
543 | |
544 NEXT_PASS (pass_referenced_vars); | |
545 NEXT_PASS (pass_reset_cc_flags); | |
546 NEXT_PASS (pass_build_ssa); | |
547 NEXT_PASS (pass_early_warn_uninitialized); | |
548 NEXT_PASS (pass_all_early_optimizations); | |
549 { | |
550 struct opt_pass **p = &pass_all_early_optimizations.pass.sub; | |
551 NEXT_PASS (pass_rebuild_cgraph_edges); | |
552 NEXT_PASS (pass_early_inline); | |
553 NEXT_PASS (pass_rename_ssa_copies); | |
554 NEXT_PASS (pass_ccp); | |
555 NEXT_PASS (pass_forwprop); | |
556 NEXT_PASS (pass_update_address_taken); | |
557 NEXT_PASS (pass_sra_early); | |
558 NEXT_PASS (pass_copy_prop); | |
559 NEXT_PASS (pass_merge_phi); | |
560 NEXT_PASS (pass_cd_dce); | |
561 NEXT_PASS (pass_simple_dse); | |
562 NEXT_PASS (pass_tail_recursion); | |
563 NEXT_PASS (pass_convert_switch); | |
564 NEXT_PASS (pass_profile); | |
565 } | |
566 NEXT_PASS (pass_release_ssa_names); | |
567 NEXT_PASS (pass_rebuild_cgraph_edges); | |
568 NEXT_PASS (pass_inline_parameters); | |
569 } | |
570 NEXT_PASS (pass_ipa_increase_alignment); | |
571 NEXT_PASS (pass_ipa_matrix_reorg); | |
572 NEXT_PASS (pass_ipa_cp); | |
573 NEXT_PASS (pass_ipa_inline); | |
574 NEXT_PASS (pass_ipa_reference); | |
575 NEXT_PASS (pass_ipa_pure_const); | |
576 NEXT_PASS (pass_ipa_type_escape); | |
577 NEXT_PASS (pass_ipa_pta); | |
578 NEXT_PASS (pass_ipa_struct_reorg); | |
579 *p = NULL; | |
580 | |
581 /* These passes are run after IPA passes on every function that is being | |
582 output to the assembler file. */ | |
583 p = &all_passes; | |
584 NEXT_PASS (pass_all_optimizations); | |
585 { | |
586 struct opt_pass **p = &pass_all_optimizations.pass.sub; | |
587 /* Initial scalar cleanups before alias computation. | |
588 They ensure memory accesses are not indirect wherever possible. */ | |
589 NEXT_PASS (pass_strip_predict_hints); | |
590 NEXT_PASS (pass_update_address_taken); | |
591 NEXT_PASS (pass_rename_ssa_copies); | |
592 NEXT_PASS (pass_complete_unrolli); | |
593 NEXT_PASS (pass_ccp); | |
594 NEXT_PASS (pass_forwprop); | |
595 /* Ideally the function call conditional | |
596 dead code elimination phase can be delayed | |
597 till later where potentially more opportunities | |
598 can be found. Due to lack of good ways to | |
599 update VDEFs associated with the shrink-wrapped | |
600 calls, it is better to do the transformation | |
601 here where memory SSA is not built yet. */ | |
602 NEXT_PASS (pass_call_cdce); | |
603 /* pass_build_alias is a dummy pass that ensures that we | |
604 execute TODO_rebuild_alias at this point. Re-building | |
605 alias information also rewrites no longer addressed | |
606 locals into SSA form if possible. */ | |
607 NEXT_PASS (pass_build_alias); | |
608 NEXT_PASS (pass_return_slot); | |
609 NEXT_PASS (pass_phiprop); | |
610 NEXT_PASS (pass_fre); | |
611 NEXT_PASS (pass_copy_prop); | |
612 NEXT_PASS (pass_merge_phi); | |
613 NEXT_PASS (pass_vrp); | |
614 NEXT_PASS (pass_dce); | |
615 NEXT_PASS (pass_cselim); | |
616 NEXT_PASS (pass_tree_ifcombine); | |
617 NEXT_PASS (pass_phiopt); | |
618 NEXT_PASS (pass_tail_recursion); | |
619 NEXT_PASS (pass_ch); | |
620 NEXT_PASS (pass_stdarg); | |
621 NEXT_PASS (pass_lower_complex); | |
622 NEXT_PASS (pass_sra); | |
623 NEXT_PASS (pass_rename_ssa_copies); | |
624 NEXT_PASS (pass_dominator); | |
625 /* The only const/copy propagation opportunities left after | |
626 DOM should be due to degenerate PHI nodes. So rather than | |
627 run the full propagators, run a specialized pass which | |
628 only examines PHIs to discover const/copy propagation | |
629 opportunities. */ | |
630 NEXT_PASS (pass_phi_only_cprop); | |
631 NEXT_PASS (pass_dse); | |
632 NEXT_PASS (pass_reassoc); | |
633 NEXT_PASS (pass_dce); | |
634 NEXT_PASS (pass_forwprop); | |
635 NEXT_PASS (pass_phiopt); | |
636 NEXT_PASS (pass_object_sizes); | |
637 NEXT_PASS (pass_ccp); | |
638 NEXT_PASS (pass_copy_prop); | |
639 NEXT_PASS (pass_fold_builtins); | |
640 NEXT_PASS (pass_cse_sincos); | |
641 NEXT_PASS (pass_split_crit_edges); | |
642 NEXT_PASS (pass_pre); | |
643 NEXT_PASS (pass_sink_code); | |
644 NEXT_PASS (pass_tree_loop); | |
645 { | |
646 struct opt_pass **p = &pass_tree_loop.pass.sub; | |
647 NEXT_PASS (pass_tree_loop_init); | |
648 NEXT_PASS (pass_copy_prop); | |
649 NEXT_PASS (pass_dce_loop); | |
650 NEXT_PASS (pass_lim); | |
651 NEXT_PASS (pass_predcom); | |
652 NEXT_PASS (pass_tree_unswitch); | |
653 NEXT_PASS (pass_scev_cprop); | |
654 NEXT_PASS (pass_empty_loop); | |
655 NEXT_PASS (pass_record_bounds); | |
656 NEXT_PASS (pass_check_data_deps); | |
657 NEXT_PASS (pass_loop_distribution); | |
658 NEXT_PASS (pass_linear_transform); | |
659 NEXT_PASS (pass_graphite_transforms); | |
660 NEXT_PASS (pass_iv_canon); | |
661 NEXT_PASS (pass_if_conversion); | |
662 NEXT_PASS (pass_vectorize); | |
663 { | |
664 struct opt_pass **p = &pass_vectorize.pass.sub; | |
665 NEXT_PASS (pass_lower_vector_ssa); | |
666 NEXT_PASS (pass_dce_loop); | |
667 } | |
668 NEXT_PASS (pass_complete_unroll); | |
669 NEXT_PASS (pass_parallelize_loops); | |
670 NEXT_PASS (pass_loop_prefetch); | |
671 NEXT_PASS (pass_iv_optimize); | |
672 NEXT_PASS (pass_tree_loop_done); | |
673 } | |
674 NEXT_PASS (pass_cse_reciprocals); | |
675 NEXT_PASS (pass_convert_to_rsqrt); | |
676 NEXT_PASS (pass_reassoc); | |
677 NEXT_PASS (pass_vrp); | |
678 NEXT_PASS (pass_dominator); | |
679 /* The only const/copy propagation opportunities left after | |
680 DOM should be due to degenerate PHI nodes. So rather than | |
681 run the full propagators, run a specialized pass which | |
682 only examines PHIs to discover const/copy propagation | |
683 opportunities. */ | |
684 NEXT_PASS (pass_phi_only_cprop); | |
685 NEXT_PASS (pass_cd_dce); | |
686 NEXT_PASS (pass_tracer); | |
687 | |
688 /* FIXME: If DCE is not run before checking for uninitialized uses, | |
689 we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c). | |
690 However, this also causes us to misdiagnose cases that should be | |
691 real warnings (e.g., testsuite/gcc.dg/pr18501.c). | |
692 | |
693 To fix the false positives in uninit-5.c, we would have to | |
694 account for the predicates protecting the set and the use of each | |
695 variable. Using a representation like Gated Single Assignment | |
696 may help. */ | |
697 NEXT_PASS (pass_late_warn_uninitialized); | |
698 NEXT_PASS (pass_dse); | |
699 NEXT_PASS (pass_forwprop); | |
700 NEXT_PASS (pass_phiopt); | |
701 NEXT_PASS (pass_tail_calls); | |
702 NEXT_PASS (pass_rename_ssa_copies); | |
703 NEXT_PASS (pass_uncprop); | |
704 } | |
705 NEXT_PASS (pass_del_ssa); | |
706 NEXT_PASS (pass_nrv); | |
707 NEXT_PASS (pass_mark_used_blocks); | |
708 NEXT_PASS (pass_cleanup_cfg_post_optimizing); | |
709 | |
710 NEXT_PASS (pass_warn_function_noreturn); | |
711 NEXT_PASS (pass_free_datastructures); | |
712 NEXT_PASS (pass_mudflap_2); | |
713 | |
714 NEXT_PASS (pass_free_cfg_annotations); | |
715 NEXT_PASS (pass_expand); | |
716 NEXT_PASS (pass_rest_of_compilation); | |
717 { | |
718 struct opt_pass **p = &pass_rest_of_compilation.pass.sub; | |
719 NEXT_PASS (pass_init_function); | |
720 NEXT_PASS (pass_jump); | |
721 NEXT_PASS (pass_rtl_eh); | |
722 NEXT_PASS (pass_initial_value_sets); | |
723 NEXT_PASS (pass_unshare_all_rtl); | |
724 NEXT_PASS (pass_instantiate_virtual_regs); | |
725 NEXT_PASS (pass_into_cfg_layout_mode); | |
726 NEXT_PASS (pass_jump2); | |
727 NEXT_PASS (pass_lower_subreg); | |
728 NEXT_PASS (pass_df_initialize_opt); | |
729 NEXT_PASS (pass_cse); | |
730 NEXT_PASS (pass_rtl_fwprop); | |
731 NEXT_PASS (pass_gcse); | |
732 NEXT_PASS (pass_rtl_ifcvt); | |
733 /* Perform loop optimizations. It might be better to do them a bit | |
734 sooner, but we want the profile feedback to work more | |
735 efficiently. */ | |
736 NEXT_PASS (pass_loop2); | |
737 { | |
738 struct opt_pass **p = &pass_loop2.pass.sub; | |
739 NEXT_PASS (pass_rtl_loop_init); | |
740 NEXT_PASS (pass_rtl_move_loop_invariants); | |
741 NEXT_PASS (pass_rtl_unswitch); | |
742 NEXT_PASS (pass_rtl_unroll_and_peel_loops); | |
743 NEXT_PASS (pass_rtl_doloop); | |
744 NEXT_PASS (pass_rtl_loop_done); | |
745 *p = NULL; | |
746 } | |
747 NEXT_PASS (pass_web); | |
748 NEXT_PASS (pass_jump_bypass); | |
749 NEXT_PASS (pass_cse2); | |
750 NEXT_PASS (pass_rtl_dse1); | |
751 NEXT_PASS (pass_rtl_fwprop_addr); | |
752 NEXT_PASS (pass_reginfo_init); | |
753 NEXT_PASS (pass_inc_dec); | |
754 NEXT_PASS (pass_initialize_regs); | |
755 NEXT_PASS (pass_outof_cfg_layout_mode); | |
756 NEXT_PASS (pass_ud_rtl_dce); | |
757 NEXT_PASS (pass_combine); | |
758 NEXT_PASS (pass_if_after_combine); | |
759 NEXT_PASS (pass_partition_blocks); | |
760 NEXT_PASS (pass_regmove); | |
761 NEXT_PASS (pass_split_all_insns); | |
762 NEXT_PASS (pass_lower_subreg2); | |
763 NEXT_PASS (pass_df_initialize_no_opt); | |
764 NEXT_PASS (pass_stack_ptr_mod); | |
765 NEXT_PASS (pass_mode_switching); | |
766 NEXT_PASS (pass_see); | |
767 NEXT_PASS (pass_match_asm_constraints); | |
768 NEXT_PASS (pass_sms); | |
769 NEXT_PASS (pass_sched); | |
770 NEXT_PASS (pass_subregs_of_mode_init); | |
771 NEXT_PASS (pass_ira); | |
772 NEXT_PASS (pass_subregs_of_mode_finish); | |
773 NEXT_PASS (pass_postreload); | |
774 { | |
775 struct opt_pass **p = &pass_postreload.pass.sub; | |
776 NEXT_PASS (pass_postreload_cse); | |
777 NEXT_PASS (pass_gcse2); | |
778 NEXT_PASS (pass_split_after_reload); | |
779 NEXT_PASS (pass_branch_target_load_optimize1); | |
780 NEXT_PASS (pass_thread_prologue_and_epilogue); | |
781 NEXT_PASS (pass_rtl_dse2); | |
782 NEXT_PASS (pass_rtl_seqabstr); | |
783 NEXT_PASS (pass_stack_adjustments); | |
784 NEXT_PASS (pass_peephole2); | |
785 NEXT_PASS (pass_if_after_reload); | |
786 NEXT_PASS (pass_regrename); | |
787 NEXT_PASS (pass_cprop_hardreg); | |
788 NEXT_PASS (pass_fast_rtl_dce); | |
789 NEXT_PASS (pass_reorder_blocks); | |
790 NEXT_PASS (pass_branch_target_load_optimize2); | |
791 NEXT_PASS (pass_leaf_regs); | |
792 NEXT_PASS (pass_split_before_sched2); | |
793 NEXT_PASS (pass_sched2); | |
794 NEXT_PASS (pass_stack_regs); | |
795 { | |
796 struct opt_pass **p = &pass_stack_regs.pass.sub; | |
797 NEXT_PASS (pass_split_before_regstack); | |
798 NEXT_PASS (pass_stack_regs_run); | |
799 } | |
800 NEXT_PASS (pass_compute_alignments); | |
801 NEXT_PASS (pass_duplicate_computed_gotos); | |
802 NEXT_PASS (pass_variable_tracking); | |
803 NEXT_PASS (pass_free_cfg); | |
804 NEXT_PASS (pass_machine_reorg); | |
805 NEXT_PASS (pass_cleanup_barriers); | |
806 NEXT_PASS (pass_delay_slots); | |
807 NEXT_PASS (pass_split_for_shorten_branches); | |
808 NEXT_PASS (pass_convert_to_eh_region_ranges); | |
809 NEXT_PASS (pass_shorten_branches); | |
810 NEXT_PASS (pass_set_nothrow_function_flags); | |
811 NEXT_PASS (pass_final); | |
812 } | |
813 NEXT_PASS (pass_df_finish); | |
814 } | |
815 NEXT_PASS (pass_clean_state); | |
816 *p = NULL; | |
817 | |
818 #undef NEXT_PASS | |
819 | |
820 /* Register the passes with the tree dump code. */ | |
821 register_dump_files (all_lowering_passes, PROP_gimple_any); | |
822 all_lowering_passes->todo_flags_start |= TODO_set_props; | |
823 register_dump_files (all_ipa_passes, | |
824 PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | |
825 | PROP_cfg); | |
826 register_dump_files (all_passes, | |
827 PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | |
828 | PROP_cfg); | |
829 } | |
830 | |
831 /* If we are in IPA mode (i.e., current_function_decl is NULL), call | |
832 function CALLBACK for every function in the call graph. Otherwise, | |
833 call CALLBACK on the current function. */ | |
834 | |
835 static void | |
836 do_per_function (void (*callback) (void *data), void *data) | |
837 { | |
838 if (current_function_decl) | |
839 callback (data); | |
840 else | |
841 { | |
842 struct cgraph_node *node; | |
843 for (node = cgraph_nodes; node; node = node->next) | |
844 if (node->analyzed) | |
845 { | |
846 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); | |
847 current_function_decl = node->decl; | |
848 callback (data); | |
849 free_dominance_info (CDI_DOMINATORS); | |
850 free_dominance_info (CDI_POST_DOMINATORS); | |
851 current_function_decl = NULL; | |
852 pop_cfun (); | |
853 ggc_collect (); | |
854 } | |
855 } | |
856 } | |
857 | |
858 /* Because inlining might remove no-longer reachable nodes, we need to | |
859 keep the array visible to garbage collector to avoid reading collected | |
860 out nodes. */ | |
861 static int nnodes; | |
862 static GTY ((length ("nnodes"))) struct cgraph_node **order; | |
863 | |
864 /* If we are in IPA mode (i.e., current_function_decl is NULL), call | |
865 function CALLBACK for every function in the call graph. Otherwise, | |
866 call CALLBACK on the current function. */ | |
867 | |
868 static void | |
869 do_per_function_toporder (void (*callback) (void *data), void *data) | |
870 { | |
871 int i; | |
872 | |
873 if (current_function_decl) | |
874 callback (data); | |
875 else | |
876 { | |
877 gcc_assert (!order); | |
878 order = GGC_NEWVEC (struct cgraph_node *, cgraph_n_nodes); | |
879 nnodes = cgraph_postorder (order); | |
880 for (i = nnodes - 1; i >= 0; i--) | |
881 { | |
882 struct cgraph_node *node = order[i]; | |
883 | |
884 /* Allow possibly removed nodes to be garbage collected. */ | |
885 order[i] = NULL; | |
886 if (node->analyzed && (node->needed || node->reachable)) | |
887 { | |
888 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); | |
889 current_function_decl = node->decl; | |
890 callback (data); | |
891 free_dominance_info (CDI_DOMINATORS); | |
892 free_dominance_info (CDI_POST_DOMINATORS); | |
893 current_function_decl = NULL; | |
894 pop_cfun (); | |
895 ggc_collect (); | |
896 } | |
897 } | |
898 } | |
899 ggc_free (order); | |
900 order = NULL; | |
901 nnodes = 0; | |
902 } | |
903 | |
904 /* Perform all TODO actions that ought to be done on each function. */ | |
905 | |
906 static void | |
907 execute_function_todo (void *data) | |
908 { | |
909 unsigned int flags = (size_t)data; | |
910 if (cfun->curr_properties & PROP_ssa) | |
911 flags |= TODO_verify_ssa; | |
912 flags &= ~cfun->last_verified; | |
913 if (!flags) | |
914 return; | |
915 | |
916 statistics_fini_pass (); | |
917 | |
918 /* Always cleanup the CFG before trying to update SSA. */ | |
919 if (flags & TODO_cleanup_cfg) | |
920 { | |
921 bool cleanup = cleanup_tree_cfg (); | |
922 | |
923 if (cleanup && (cfun->curr_properties & PROP_ssa)) | |
924 flags |= TODO_remove_unused_locals; | |
925 | |
926 /* When cleanup_tree_cfg merges consecutive blocks, it may | |
927 perform some simplistic propagation when removing single | |
928 valued PHI nodes. This propagation may, in turn, cause the | |
929 SSA form to become out-of-date (see PR 22037). So, even | |
930 if the parent pass had not scheduled an SSA update, we may | |
931 still need to do one. */ | |
932 if (!(flags & TODO_update_ssa_any) && need_ssa_update_p ()) | |
933 flags |= TODO_update_ssa; | |
934 } | |
935 | |
936 if (flags & TODO_update_ssa_any) | |
937 { | |
938 unsigned update_flags = flags & TODO_update_ssa_any; | |
939 update_ssa (update_flags); | |
940 cfun->last_verified &= ~TODO_verify_ssa; | |
941 } | |
942 | |
943 if (flags & TODO_rebuild_alias) | |
944 { | |
945 compute_may_aliases (); | |
946 cfun->curr_properties |= PROP_alias; | |
947 } | |
948 | |
949 if (flags & TODO_remove_unused_locals) | |
950 remove_unused_locals (); | |
951 | |
952 if ((flags & TODO_dump_func) && dump_file && current_function_decl) | |
953 { | |
954 if (cfun->curr_properties & PROP_trees) | |
955 dump_function_to_file (current_function_decl, dump_file, dump_flags); | |
956 else | |
957 { | |
958 if (dump_flags & TDF_SLIM) | |
959 print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); | |
960 else if ((cfun->curr_properties & PROP_cfg) | |
961 && (dump_flags & TDF_BLOCKS)) | |
962 print_rtl_with_bb (dump_file, get_insns ()); | |
963 else | |
964 print_rtl (dump_file, get_insns ()); | |
965 | |
966 if ((cfun->curr_properties & PROP_cfg) | |
967 && graph_dump_format != no_graph | |
968 && (dump_flags & TDF_GRAPH)) | |
969 print_rtl_graph_with_bb (dump_file_name, get_insns ()); | |
970 } | |
971 | |
972 /* Flush the file. If verification fails, we won't be able to | |
973 close the file before aborting. */ | |
974 fflush (dump_file); | |
975 } | |
976 | |
977 if (flags & TODO_rebuild_frequencies) | |
978 { | |
979 if (profile_status == PROFILE_GUESSED) | |
980 { | |
981 loop_optimizer_init (0); | |
982 add_noreturn_fake_exit_edges (); | |
983 mark_irreducible_loops (); | |
984 connect_infinite_loops_to_exit (); | |
985 estimate_bb_frequencies (); | |
986 remove_fake_exit_edges (); | |
987 loop_optimizer_finalize (); | |
988 } | |
989 else if (profile_status == PROFILE_READ) | |
990 counts_to_freqs (); | |
991 else | |
992 gcc_unreachable (); | |
993 } | |
994 | |
995 #if defined ENABLE_CHECKING | |
996 if (flags & TODO_verify_ssa) | |
997 verify_ssa (true); | |
998 if (flags & TODO_verify_flow) | |
999 verify_flow_info (); | |
1000 if (flags & TODO_verify_stmts) | |
1001 verify_stmts (); | |
1002 if (flags & TODO_verify_loops) | |
1003 verify_loop_closed_ssa (); | |
1004 if (flags & TODO_verify_rtl_sharing) | |
1005 verify_rtl_sharing (); | |
1006 #endif | |
1007 | |
1008 cfun->last_verified = flags & TODO_verify_all; | |
1009 } | |
1010 | |
1011 /* Perform all TODO actions. */ | |
1012 static void | |
1013 execute_todo (unsigned int flags) | |
1014 { | |
1015 #if defined ENABLE_CHECKING | |
1016 if (need_ssa_update_p ()) | |
1017 gcc_assert (flags & TODO_update_ssa_any); | |
1018 #endif | |
1019 | |
1020 /* Inform the pass whether it is the first time it is run. */ | |
1021 first_pass_instance = (flags & TODO_mark_first_instance) != 0; | |
1022 | |
1023 do_per_function (execute_function_todo, (void *)(size_t) flags); | |
1024 | |
1025 /* Always remove functions just as before inlining: IPA passes might be | |
1026 interested to see bodies of extern inline functions that are not inlined | |
1027 to analyze side effects. The full removal is done just at the end | |
1028 of IPA pass queue. */ | |
1029 if (flags & TODO_remove_functions) | |
1030 { | |
1031 gcc_assert (!cfun); | |
1032 cgraph_remove_unreachable_nodes (true, dump_file); | |
1033 } | |
1034 | |
1035 if ((flags & TODO_dump_cgraph) && dump_file && !current_function_decl) | |
1036 { | |
1037 gcc_assert (!cfun); | |
1038 dump_cgraph (dump_file); | |
1039 /* Flush the file. If verification fails, we won't be able to | |
1040 close the file before aborting. */ | |
1041 fflush (dump_file); | |
1042 } | |
1043 | |
1044 if (flags & TODO_ggc_collect) | |
1045 ggc_collect (); | |
1046 | |
1047 /* Now that the dumping has been done, we can get rid of the optional | |
1048 df problems. */ | |
1049 if (flags & TODO_df_finish) | |
1050 df_finish_pass ((flags & TODO_df_verify) != 0); | |
1051 } | |
1052 | |
1053 /* Verify invariants that should hold between passes. This is a place | |
1054 to put simple sanity checks. */ | |
1055 | |
1056 static void | |
1057 verify_interpass_invariants (void) | |
1058 { | |
1059 #ifdef ENABLE_CHECKING | |
1060 gcc_assert (!fold_deferring_overflow_warnings_p ()); | |
1061 #endif | |
1062 } | |
1063 | |
1064 /* Clear the last verified flag. */ | |
1065 | |
1066 static void | |
1067 clear_last_verified (void *data ATTRIBUTE_UNUSED) | |
1068 { | |
1069 cfun->last_verified = 0; | |
1070 } | |
1071 | |
1072 /* Helper function. Verify that the properties has been turn into the | |
1073 properties expected by the pass. */ | |
1074 | |
1075 #ifdef ENABLE_CHECKING | |
1076 static void | |
1077 verify_curr_properties (void *data) | |
1078 { | |
1079 unsigned int props = (size_t)data; | |
1080 gcc_assert ((cfun->curr_properties & props) == props); | |
1081 } | |
1082 #endif | |
1083 | |
1084 /* Initialize pass dump file. */ | |
1085 | |
1086 static bool | |
1087 pass_init_dump_file (struct opt_pass *pass) | |
1088 { | |
1089 /* If a dump file name is present, open it if enabled. */ | |
1090 if (pass->static_pass_number != -1) | |
1091 { | |
1092 bool initializing_dump = !dump_initialized_p (pass->static_pass_number); | |
1093 dump_file_name = get_dump_file_name (pass->static_pass_number); | |
1094 dump_file = dump_begin (pass->static_pass_number, &dump_flags); | |
1095 if (dump_file && current_function_decl) | |
1096 { | |
1097 const char *dname, *aname; | |
1098 dname = lang_hooks.decl_printable_name (current_function_decl, 2); | |
1099 aname = (IDENTIFIER_POINTER | |
1100 (DECL_ASSEMBLER_NAME (current_function_decl))); | |
1101 fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname, | |
1102 cfun->function_frequency == FUNCTION_FREQUENCY_HOT | |
1103 ? " (hot)" | |
1104 : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED | |
1105 ? " (unlikely executed)" | |
1106 : ""); | |
1107 } | |
1108 return initializing_dump; | |
1109 } | |
1110 else | |
1111 return false; | |
1112 } | |
1113 | |
1114 /* Flush PASS dump file. */ | |
1115 | |
1116 static void | |
1117 pass_fini_dump_file (struct opt_pass *pass) | |
1118 { | |
1119 /* Flush and close dump file. */ | |
1120 if (dump_file_name) | |
1121 { | |
1122 free (CONST_CAST (char *, dump_file_name)); | |
1123 dump_file_name = NULL; | |
1124 } | |
1125 | |
1126 if (dump_file) | |
1127 { | |
1128 dump_end (pass->static_pass_number, dump_file); | |
1129 dump_file = NULL; | |
1130 } | |
1131 } | |
1132 | |
1133 /* After executing the pass, apply expected changes to the function | |
1134 properties. */ | |
1135 | |
1136 static void | |
1137 update_properties_after_pass (void *data) | |
1138 { | |
1139 struct opt_pass *pass = (struct opt_pass *) data; | |
1140 cfun->curr_properties = (cfun->curr_properties | pass->properties_provided) | |
1141 & ~pass->properties_destroyed; | |
1142 } | |
1143 | |
1144 /* Schedule IPA transform pass DATA for CFUN. */ | |
1145 | |
1146 static void | |
1147 add_ipa_transform_pass (void *data) | |
1148 { | |
1149 struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *) data; | |
1150 VEC_safe_push (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply, ipa_pass); | |
1151 } | |
1152 | |
1153 /* Execute summary generation for all of the passes in IPA_PASS. */ | |
1154 | |
1155 static void | |
1156 execute_ipa_summary_passes (struct ipa_opt_pass *ipa_pass) | |
1157 { | |
1158 while (ipa_pass) | |
1159 { | |
1160 struct opt_pass *pass = &ipa_pass->pass; | |
1161 | |
1162 /* Execute all of the IPA_PASSes in the list. */ | |
1163 if (ipa_pass->pass.type == IPA_PASS | |
1164 && (!pass->gate || pass->gate ())) | |
1165 { | |
1166 pass_init_dump_file (pass); | |
1167 ipa_pass->generate_summary (); | |
1168 pass_fini_dump_file (pass); | |
1169 } | |
1170 ipa_pass = (struct ipa_opt_pass *)ipa_pass->pass.next; | |
1171 } | |
1172 } | |
1173 | |
1174 /* Execute IPA_PASS function transform on NODE. */ | |
1175 | |
1176 static void | |
1177 execute_one_ipa_transform_pass (struct cgraph_node *node, | |
1178 struct ipa_opt_pass *ipa_pass) | |
1179 { | |
1180 struct opt_pass *pass = &ipa_pass->pass; | |
1181 unsigned int todo_after = 0; | |
1182 | |
1183 current_pass = pass; | |
1184 if (!ipa_pass->function_transform) | |
1185 return; | |
1186 | |
1187 /* Note that the folders should only create gimple expressions. | |
1188 This is a hack until the new folder is ready. */ | |
1189 in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0; | |
1190 | |
1191 pass_init_dump_file (pass); | |
1192 | |
1193 /* Run pre-pass verification. */ | |
1194 execute_todo (ipa_pass->function_transform_todo_flags_start); | |
1195 | |
1196 /* If a timevar is present, start it. */ | |
1197 if (pass->tv_id) | |
1198 timevar_push (pass->tv_id); | |
1199 | |
1200 /* Do it! */ | |
1201 todo_after = ipa_pass->function_transform (node); | |
1202 | |
1203 /* Stop timevar. */ | |
1204 if (pass->tv_id) | |
1205 timevar_pop (pass->tv_id); | |
1206 | |
1207 /* Run post-pass cleanup and verification. */ | |
1208 execute_todo (todo_after); | |
1209 verify_interpass_invariants (); | |
1210 | |
1211 pass_fini_dump_file (pass); | |
1212 | |
1213 current_pass = NULL; | |
1214 } | |
1215 | |
1216 static bool | |
1217 execute_one_pass (struct opt_pass *pass) | |
1218 { | |
1219 bool initializing_dump; | |
1220 unsigned int todo_after = 0; | |
1221 | |
1222 /* IPA passes are executed on whole program, so cfun should be NULL. | |
1223 Other passes need function context set. */ | |
1224 if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS) | |
1225 gcc_assert (!cfun && !current_function_decl); | |
1226 else | |
1227 gcc_assert (cfun && current_function_decl); | |
1228 | |
1229 if (cfun && cfun->ipa_transforms_to_apply) | |
1230 { | |
1231 unsigned int i; | |
1232 struct cgraph_node *node = cgraph_node (current_function_decl); | |
1233 | |
1234 for (i = 0; i < VEC_length (ipa_opt_pass, cfun->ipa_transforms_to_apply); | |
1235 i++) | |
1236 execute_one_ipa_transform_pass (node, | |
1237 VEC_index (ipa_opt_pass, | |
1238 cfun->ipa_transforms_to_apply, | |
1239 i)); | |
1240 VEC_free (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply); | |
1241 cfun->ipa_transforms_to_apply = NULL; | |
1242 } | |
1243 | |
1244 current_pass = pass; | |
1245 | |
1246 /* See if we're supposed to run this pass. */ | |
1247 if (pass->gate && !pass->gate ()) | |
1248 return false; | |
1249 | |
1250 if (!quiet_flag && !cfun) | |
1251 fprintf (stderr, " <%s>", pass->name ? pass->name : ""); | |
1252 | |
1253 if (pass->todo_flags_start & TODO_set_props) | |
1254 cfun->curr_properties = pass->properties_required; | |
1255 | |
1256 /* Note that the folders should only create gimple expressions. | |
1257 This is a hack until the new folder is ready. */ | |
1258 in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0; | |
1259 | |
1260 /* Run pre-pass verification. */ | |
1261 execute_todo (pass->todo_flags_start); | |
1262 | |
1263 #ifdef ENABLE_CHECKING | |
1264 do_per_function (verify_curr_properties, | |
1265 (void *)(size_t)pass->properties_required); | |
1266 #endif | |
1267 | |
1268 initializing_dump = pass_init_dump_file (pass); | |
1269 | |
1270 /* If a timevar is present, start it. */ | |
1271 if (pass->tv_id) | |
1272 timevar_push (pass->tv_id); | |
1273 | |
1274 /* Do it! */ | |
1275 if (pass->execute) | |
1276 { | |
1277 todo_after = pass->execute (); | |
1278 do_per_function (clear_last_verified, NULL); | |
1279 } | |
1280 | |
1281 /* Stop timevar. */ | |
1282 if (pass->tv_id) | |
1283 timevar_pop (pass->tv_id); | |
1284 | |
1285 do_per_function (update_properties_after_pass, pass); | |
1286 | |
1287 if (initializing_dump | |
1288 && dump_file | |
1289 && graph_dump_format != no_graph | |
1290 && cfun | |
1291 && (cfun->curr_properties & (PROP_cfg | PROP_rtl)) | |
1292 == (PROP_cfg | PROP_rtl)) | |
1293 { | |
1294 get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH; | |
1295 dump_flags |= TDF_GRAPH; | |
1296 clean_graph_dump_file (dump_file_name); | |
1297 } | |
1298 | |
1299 /* Run post-pass cleanup and verification. */ | |
1300 execute_todo (todo_after | pass->todo_flags_finish); | |
1301 verify_interpass_invariants (); | |
1302 if (pass->type == IPA_PASS) | |
1303 do_per_function (add_ipa_transform_pass, pass); | |
1304 | |
1305 if (!current_function_decl) | |
1306 cgraph_process_new_functions (); | |
1307 | |
1308 pass_fini_dump_file (pass); | |
1309 | |
1310 if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS) | |
1311 gcc_assert (!(cfun->curr_properties & PROP_trees) | |
1312 || pass->type != RTL_PASS); | |
1313 | |
1314 current_pass = NULL; | |
1315 | |
1316 return true; | |
1317 } | |
1318 | |
1319 void | |
1320 execute_pass_list (struct opt_pass *pass) | |
1321 { | |
1322 do | |
1323 { | |
1324 gcc_assert (pass->type == GIMPLE_PASS | |
1325 || pass->type == RTL_PASS); | |
1326 if (execute_one_pass (pass) && pass->sub) | |
1327 execute_pass_list (pass->sub); | |
1328 pass = pass->next; | |
1329 } | |
1330 while (pass); | |
1331 } | |
1332 | |
1333 /* Same as execute_pass_list but assume that subpasses of IPA passes | |
1334 are local passes. */ | |
1335 void | |
1336 execute_ipa_pass_list (struct opt_pass *pass) | |
1337 { | |
1338 bool summaries_generated = false; | |
1339 do | |
1340 { | |
1341 gcc_assert (!current_function_decl); | |
1342 gcc_assert (!cfun); | |
1343 gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); | |
1344 if (pass->type == IPA_PASS && (!pass->gate || pass->gate ())) | |
1345 { | |
1346 if (!summaries_generated) | |
1347 { | |
1348 if (!quiet_flag && !cfun) | |
1349 fprintf (stderr, " <summary generate>"); | |
1350 execute_ipa_summary_passes ((struct ipa_opt_pass *) pass); | |
1351 } | |
1352 summaries_generated = true; | |
1353 } | |
1354 if (execute_one_pass (pass) && pass->sub) | |
1355 { | |
1356 if (pass->sub->type == GIMPLE_PASS) | |
1357 do_per_function_toporder ((void (*)(void *))execute_pass_list, | |
1358 pass->sub); | |
1359 else if (pass->sub->type == SIMPLE_IPA_PASS | |
1360 || pass->sub->type == IPA_PASS) | |
1361 execute_ipa_pass_list (pass->sub); | |
1362 else | |
1363 gcc_unreachable (); | |
1364 } | |
1365 if (!current_function_decl) | |
1366 cgraph_process_new_functions (); | |
1367 pass = pass->next; | |
1368 } | |
1369 while (pass); | |
1370 } | |
1371 | |
1372 #include "gt-passes.h" |