1 /* Top-level control of tree optimizations.
2 Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
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/>. */
24 #include "coretypes.h"
28 #include "basic-block.h"
31 #include "tree-flow.h"
32 #include "tree-dump.h"
35 #include "langhooks.h"
36 #include "diagnostic-core.h"
40 #include "tree-inline.h"
41 #include "tree-mudflap.h"
42 #include "tree-pass.h"
49 #include "regset.h" /* FIXME: For reg_obstack. */
51 /* Gate: execute, or not, all of the non-trivial optimizations. */
54 gate_all_optimizations (void)
57 /* Don't bother doing anything if the program has errors.
58 We have to pass down the queue if we already went into SSA */
59 && (!seen_error () || gimple_in_ssa_p (cfun)));
62 struct gimple_opt_pass pass_all_optimizations =
66 "*all_optimizations", /* name */
67 gate_all_optimizations, /* gate */
71 0, /* static_pass_number */
73 0, /* properties_required */
74 0, /* properties_provided */
75 0, /* properties_destroyed */
76 0, /* todo_flags_start */
77 0 /* todo_flags_finish */
81 /* Gate: execute, or not, all of the non-trivial optimizations. */
84 gate_all_early_local_passes (void)
86 /* Don't bother doing anything if the program has errors. */
87 return (!seen_error () && !in_lto_p);
90 struct simple_ipa_opt_pass pass_early_local_passes =
94 "early_local_cleanups", /* name */
95 gate_all_early_local_passes, /* gate */
99 0, /* static_pass_number */
101 0, /* properties_required */
102 0, /* properties_provided */
103 0, /* properties_destroyed */
104 0, /* todo_flags_start */
105 TODO_remove_functions /* todo_flags_finish */
110 execute_early_local_optimizations (void)
112 /* First time we start with early optimization we need to advance
113 cgraph state so newly inserted functions are also early optimized.
114 However we execute early local optimizations for lately inserted
115 functions, in that case don't reset cgraph state back to IPA_SSA. */
116 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
117 cgraph_state = CGRAPH_STATE_IPA_SSA;
121 /* Gate: execute, or not, all of the non-trivial optimizations. */
124 gate_all_early_optimizations (void)
126 return (optimize >= 1
127 /* Don't bother doing anything if the program has errors. */
131 struct gimple_opt_pass pass_all_early_optimizations =
135 "early_optimizations", /* name */
136 gate_all_early_optimizations, /* gate */
137 execute_early_local_optimizations, /* execute */
140 0, /* static_pass_number */
142 0, /* properties_required */
143 0, /* properties_provided */
144 0, /* properties_destroyed */
145 0, /* todo_flags_start */
146 0 /* todo_flags_finish */
150 /* Pass: cleanup the CFG just before expanding trees to RTL.
151 This is just a round of label cleanups and case node grouping
152 because after the tree optimizers have run such cleanups may
156 execute_cleanup_cfg_pre_ipa (void)
162 struct gimple_opt_pass pass_cleanup_cfg =
166 "cleanup_cfg", /* name */
168 execute_cleanup_cfg_pre_ipa, /* execute */
171 0, /* static_pass_number */
173 PROP_cfg, /* properties_required */
174 0, /* properties_provided */
175 0, /* properties_destroyed */
176 0, /* todo_flags_start */
177 TODO_dump_func /* todo_flags_finish */
182 /* Pass: cleanup the CFG just before expanding trees to RTL.
183 This is just a round of label cleanups and case node grouping
184 because after the tree optimizers have run such cleanups may
188 execute_cleanup_cfg_post_optimizing (void)
190 fold_cond_expr_cond ();
192 cleanup_dead_labels ();
193 group_case_labels ();
194 if ((flag_compare_debug_opt || flag_compare_debug)
195 && flag_dump_final_insns)
197 FILE *final_output = fopen (flag_dump_final_insns, "a");
201 error ("could not open final insn dump file %qs: %m",
202 flag_dump_final_insns);
203 flag_dump_final_insns = NULL;
207 int save_unnumbered = flag_dump_unnumbered;
208 int save_noaddr = flag_dump_noaddr;
210 flag_dump_noaddr = flag_dump_unnumbered = 1;
211 fprintf (final_output, "\n");
212 dump_enumerated_decls (final_output, dump_flags | TDF_NOUID);
213 flag_dump_noaddr = save_noaddr;
214 flag_dump_unnumbered = save_unnumbered;
215 if (fclose (final_output))
217 error ("could not close final insn dump file %qs: %m",
218 flag_dump_final_insns);
219 flag_dump_final_insns = NULL;
226 struct gimple_opt_pass pass_cleanup_cfg_post_optimizing =
230 "optimized", /* name */
232 execute_cleanup_cfg_post_optimizing, /* execute */
235 0, /* static_pass_number */
237 PROP_cfg, /* properties_required */
238 0, /* properties_provided */
239 0, /* properties_destroyed */
240 0, /* todo_flags_start */
241 TODO_dump_func /* todo_flags_finish */
242 | TODO_remove_unused_locals
246 /* Pass: do the actions required to finish with tree-ssa optimization
250 execute_free_datastructures (void)
252 free_dominance_info (CDI_DOMINATORS);
253 free_dominance_info (CDI_POST_DOMINATORS);
255 /* And get rid of annotations we no longer need. */
256 delete_tree_cfg_annotations ();
261 /* Pass: fixup_cfg. IPA passes, compilation of earlier functions or inlining
262 might have changed some properties, such as marked functions nothrow,
263 pure, const or noreturn.
264 Remove redundant edges and basic blocks, and create new ones if necessary.
266 This pass can't be executed as stand alone pass from pass manager, because
267 in between inlining and this fixup the verify_flow_info would fail. */
270 execute_fixup_cfg (void)
273 gimple_stmt_iterator gsi;
274 int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
275 gcov_type count_scale;
279 if (ENTRY_BLOCK_PTR->count)
280 count_scale = (cgraph_node (current_function_decl)->count * REG_BR_PROB_BASE
281 + ENTRY_BLOCK_PTR->count / 2) / ENTRY_BLOCK_PTR->count;
283 count_scale = REG_BR_PROB_BASE;
285 ENTRY_BLOCK_PTR->count = cgraph_node (current_function_decl)->count;
286 EXIT_BLOCK_PTR->count = (EXIT_BLOCK_PTR->count * count_scale
287 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
291 bb->count = (bb->count * count_scale
292 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
293 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
295 gimple stmt = gsi_stmt (gsi);
296 tree decl = is_gimple_call (stmt)
297 ? gimple_call_fndecl (stmt)
301 int flags = gimple_call_flags (stmt);
302 if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
304 if (gimple_in_ssa_p (cfun))
306 todo |= TODO_update_ssa | TODO_cleanup_cfg;
307 mark_symbols_for_renaming (stmt);
312 if (flags & ECF_NORETURN
313 && fixup_noreturn_call (stmt))
314 todo |= TODO_cleanup_cfg;
317 maybe_clean_eh_stmt (stmt);
320 if (gimple_purge_dead_eh_edges (bb))
321 todo |= TODO_cleanup_cfg;
322 FOR_EACH_EDGE (e, ei, bb->succs)
323 e->count = (e->count * count_scale
324 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
326 if (count_scale != REG_BR_PROB_BASE)
327 compute_function_frequency ();
329 /* We just processed all calls. */
332 VEC_free (gimple, gc, MODIFIED_NORETURN_CALLS (cfun));
333 MODIFIED_NORETURN_CALLS (cfun) = NULL;
336 /* Dump a textual representation of the flowgraph. */
338 gimple_dump_cfg (dump_file, dump_flags);
343 struct gimple_opt_pass pass_fixup_cfg =
347 "*free_cfg_annotations", /* name */
349 execute_fixup_cfg, /* execute */
352 0, /* static_pass_number */
354 PROP_cfg, /* properties_required */
355 0, /* properties_provided */
356 0, /* properties_destroyed */
357 0, /* todo_flags_start */
358 0 /* todo_flags_finish */
362 /* Do the actions required to initialize internal data structures used
363 in tree-ssa optimization passes. */
366 execute_init_datastructures (void)
368 /* Allocate hash tables, arrays and other structures. */
369 init_tree_ssa (cfun);
373 struct gimple_opt_pass pass_init_datastructures =
377 "*init_datastructures", /* name */
379 execute_init_datastructures, /* execute */
382 0, /* static_pass_number */
384 PROP_cfg, /* properties_required */
385 0, /* properties_provided */
386 0, /* properties_destroyed */
387 0, /* todo_flags_start */
388 0 /* todo_flags_finish */
393 tree_lowering_passes (tree fn)
395 tree saved_current_function_decl = current_function_decl;
397 current_function_decl = fn;
398 push_cfun (DECL_STRUCT_FUNCTION (fn));
399 gimple_register_cfg_hooks ();
400 bitmap_obstack_initialize (NULL);
401 execute_pass_list (all_lowering_passes);
402 if (optimize && cgraph_global_info_ready)
403 execute_pass_list (pass_early_local_passes.pass.sub);
404 free_dominance_info (CDI_POST_DOMINATORS);
405 free_dominance_info (CDI_DOMINATORS);
407 current_function_decl = saved_current_function_decl;
408 bitmap_obstack_release (NULL);
412 /* For functions-as-trees languages, this performs all optimization and
413 compilation for FNDECL. */
416 tree_rest_of_compilation (tree fndecl)
418 location_t saved_loc;
420 timevar_push (TV_EXPAND);
422 gcc_assert (cgraph_global_info_ready);
424 /* Initialize the default bitmap obstack. */
425 bitmap_obstack_initialize (NULL);
427 /* Initialize the RTL code for the function. */
428 current_function_decl = fndecl;
429 saved_loc = input_location;
430 input_location = DECL_SOURCE_LOCATION (fndecl);
431 init_function_start (fndecl);
433 /* Even though we're inside a function body, we still don't want to
434 call expand_expr to calculate the size of a variable-sized array.
435 We haven't necessarily assigned RTL to all variables yet, so it's
436 not safe to try to expand expressions involving them. */
437 cfun->dont_save_pending_sizes_p = 1;
439 gimple_register_cfg_hooks ();
441 bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/
443 execute_all_ipa_transforms ();
445 /* Perform all tree transforms and optimizations. */
447 /* Signal the start of passes. */
448 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
450 execute_pass_list (all_passes);
452 /* Signal the end of passes. */
453 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
455 bitmap_obstack_release (®_obstack);
457 /* Release the default bitmap obstack. */
458 bitmap_obstack_release (NULL);
462 /* If requested, warn about function definitions where the function will
463 return a value (usually of some struct or union type) which itself will
464 take up a lot of stack space. */
465 if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
467 tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
469 if (ret_type && TYPE_SIZE_UNIT (ret_type)
470 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
471 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
474 unsigned int size_as_int
475 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
477 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
478 warning (OPT_Wlarger_than_eq, "size of return value of %q+D is %u bytes",
479 fndecl, size_as_int);
481 warning (OPT_Wlarger_than_eq, "size of return value of %q+D is larger than %wd bytes",
482 fndecl, larger_than_size);
486 gimple_set_body (fndecl, NULL);
487 if (DECL_STRUCT_FUNCTION (fndecl) == 0
488 && !cgraph_node (fndecl)->origin)
490 /* Stop pointing to the local nodes about to be freed.
491 But DECL_INITIAL must remain nonzero so we know this
492 was an actual function definition.
493 For a nested function, this is done in c_pop_function_context.
494 If rest_of_compilation set this to 0, leave it 0. */
495 if (DECL_INITIAL (fndecl) != 0)
496 DECL_INITIAL (fndecl) = error_mark_node;
499 input_location = saved_loc;
502 timevar_pop (TV_EXPAND);