1 /* Top-level control of tree optimizations.
2 Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Diego Novillo <dnovillo@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
24 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
33 #include "diagnostic.h"
34 #include "basic-block.h"
36 #include "tree-flow.h"
37 #include "tree-dump.h"
40 #include "langhooks.h"
44 #include "tree-inline.h"
45 #include "tree-mudflap.h"
46 #include "tree-pass.h"
54 /* Gate: execute, or not, all of the non-trivial optimizations. */
57 gate_all_optimizations (void)
60 /* Don't bother doing anything if the program has errors.
61 We have to pass down the queue if we already went into SSA */
62 && (!(errorcount
|| sorrycount
) || gimple_in_ssa_p (cfun
)));
65 struct tree_opt_pass pass_all_optimizations
=
68 gate_all_optimizations
, /* gate */
72 0, /* static_pass_number */
74 0, /* properties_required */
75 0, /* properties_provided */
76 0, /* properties_destroyed */
77 0, /* todo_flags_start */
78 0, /* todo_flags_finish */
82 /* Gate: execute, or not, all of the non-trivial optimizations. */
85 gate_all_early_local_passes (void)
87 /* Don't bother doing anything if the program has errors. */
88 return (!errorcount
&& !sorrycount
);
91 struct tree_opt_pass pass_early_local_passes
=
93 "early_local_cleanups", /* name */
94 gate_all_early_local_passes
, /* gate */
98 0, /* static_pass_number */
100 0, /* properties_required */
101 0, /* properties_provided */
102 0, /* properties_destroyed */
103 0, /* todo_flags_start */
104 TODO_remove_functions
, /* todo_flags_finish */
109 execute_early_local_optimizations (void)
111 if (flag_unit_at_a_time
)
112 cgraph_state
= CGRAPH_STATE_IPA_SSA
;
116 /* Gate: execute, or not, all of the non-trivial optimizations. */
119 gate_all_early_optimizations (void)
121 return (optimize
>= 1
122 /* Don't bother doing anything if the program has errors. */
123 && !(errorcount
|| sorrycount
));
126 struct tree_opt_pass pass_all_early_optimizations
=
128 "early_optimizations", /* name */
129 gate_all_early_optimizations
, /* gate */
130 execute_early_local_optimizations
, /* execute */
133 0, /* static_pass_number */
135 0, /* properties_required */
136 0, /* properties_provided */
137 0, /* properties_destroyed */
138 0, /* todo_flags_start */
139 0, /* todo_flags_finish */
143 /* Pass: cleanup the CFG just before expanding trees to RTL.
144 This is just a round of label cleanups and case node grouping
145 because after the tree optimizers have run such cleanups may
149 execute_cleanup_cfg_pre_ipa (void)
155 struct tree_opt_pass pass_cleanup_cfg
=
157 "cleanup_cfg", /* name */
159 execute_cleanup_cfg_pre_ipa
, /* execute */
162 0, /* static_pass_number */
164 PROP_cfg
, /* properties_required */
165 0, /* properties_provided */
166 0, /* properties_destroyed */
167 0, /* todo_flags_start */
168 TODO_dump_func
, /* todo_flags_finish */
173 /* Pass: cleanup the CFG just before expanding trees to RTL.
174 This is just a round of label cleanups and case node grouping
175 because after the tree optimizers have run such cleanups may
179 execute_cleanup_cfg_post_optimizing (void)
181 fold_cond_expr_cond ();
183 cleanup_dead_labels ();
184 group_case_labels ();
188 struct tree_opt_pass pass_cleanup_cfg_post_optimizing
=
190 "final_cleanup", /* name */
192 execute_cleanup_cfg_post_optimizing
, /* execute */
195 0, /* static_pass_number */
197 PROP_cfg
, /* properties_required */
198 0, /* properties_provided */
199 0, /* properties_destroyed */
200 0, /* todo_flags_start */
201 TODO_dump_func
, /* todo_flags_finish */
205 /* Pass: do the actions required to finish with tree-ssa optimization
209 execute_free_datastructures (void)
211 free_dominance_info (CDI_DOMINATORS
);
212 free_dominance_info (CDI_POST_DOMINATORS
);
214 /* Remove the ssa structures. */
220 struct tree_opt_pass pass_free_datastructures
=
224 execute_free_datastructures
, /* execute */
227 0, /* static_pass_number */
229 PROP_cfg
, /* properties_required */
230 0, /* properties_provided */
231 0, /* properties_destroyed */
232 0, /* todo_flags_start */
233 0, /* todo_flags_finish */
236 /* Pass: free cfg annotations. */
239 execute_free_cfg_annotations (void)
241 /* And get rid of annotations we no longer need. */
242 delete_tree_cfg_annotations ();
247 struct tree_opt_pass pass_free_cfg_annotations
=
251 execute_free_cfg_annotations
, /* execute */
254 0, /* static_pass_number */
256 PROP_cfg
, /* properties_required */
257 0, /* properties_provided */
258 0, /* properties_destroyed */
259 0, /* todo_flags_start */
260 0, /* todo_flags_finish */
264 /* Pass: fixup_cfg. IPA passes, compilation of earlier functions or inlining
265 might have changed some properties, such as marked functions nothrow.
266 Remove redundant edges and basic blocks, and create new ones if necessary.
268 This pass can't be executed as stand alone pass from pass manager, because
269 in between inlining and this fixup the verify_flow_info would fail. */
272 execute_fixup_cfg (void)
275 block_stmt_iterator bsi
;
276 int todo
= gimple_in_ssa_p (cfun
) ? TODO_verify_ssa
: 0;
278 cfun
->after_inlining
= true;
283 for (bsi
= bsi_start (bb
); !bsi_end_p (bsi
); bsi_next (&bsi
))
285 tree stmt
= bsi_stmt (bsi
);
286 tree call
= get_call_expr_in (stmt
);
287 tree decl
= call
? get_callee_fndecl (call
) : NULL
;
289 if (decl
&& call_expr_flags (call
) & (ECF_CONST
| ECF_PURE
)
290 && TREE_SIDE_EFFECTS (call
))
292 if (gimple_in_ssa_p (cfun
))
294 todo
|= TODO_update_ssa
| TODO_cleanup_cfg
;
297 TREE_SIDE_EFFECTS (call
) = 0;
299 if (decl
&& TREE_NOTHROW (decl
))
300 TREE_NOTHROW (call
) = 1;
301 if (!tree_could_throw_p (stmt
) && lookup_stmt_eh_region (stmt
))
302 remove_stmt_from_eh_region (stmt
);
304 if (tree_purge_dead_eh_edges (bb
))
305 todo
|= TODO_cleanup_cfg
;
308 /* Dump a textual representation of the flowgraph. */
310 dump_tree_cfg (dump_file
, dump_flags
);
315 /* Do the actions required to initialize internal data structures used
316 in tree-ssa optimization passes. */
319 execute_init_datastructures (void)
321 /* Allocate hash tables, arrays and other structures. */
326 /* Gate: initialize or not the SSA datastructures. */
329 gate_init_datastructures (void)
331 return (optimize
>= 1);
334 struct tree_opt_pass pass_init_datastructures
=
337 gate_init_datastructures
, /* gate */
338 execute_init_datastructures
, /* execute */
341 0, /* static_pass_number */
343 PROP_cfg
, /* properties_required */
344 0, /* properties_provided */
345 0, /* properties_destroyed */
346 0, /* todo_flags_start */
347 0, /* todo_flags_finish */
352 tree_lowering_passes (tree fn
)
354 tree saved_current_function_decl
= current_function_decl
;
356 current_function_decl
= fn
;
357 push_cfun (DECL_STRUCT_FUNCTION (fn
));
358 tree_register_cfg_hooks ();
359 bitmap_obstack_initialize (NULL
);
360 execute_pass_list (all_lowering_passes
);
361 if (optimize
&& cgraph_global_info_ready
)
362 execute_pass_list (pass_early_local_passes
.sub
);
363 free_dominance_info (CDI_POST_DOMINATORS
);
364 free_dominance_info (CDI_DOMINATORS
);
366 current_function_decl
= saved_current_function_decl
;
367 bitmap_obstack_release (NULL
);
371 /* For functions-as-trees languages, this performs all optimization and
372 compilation for FNDECL. */
375 tree_rest_of_compilation (tree fndecl
)
377 location_t saved_loc
;
378 struct cgraph_node
*node
;
380 timevar_push (TV_EXPAND
);
382 gcc_assert (!flag_unit_at_a_time
|| cgraph_global_info_ready
);
384 node
= cgraph_node (fndecl
);
386 /* Initialize the default bitmap obstack. */
387 bitmap_obstack_initialize (NULL
);
389 /* Initialize the RTL code for the function. */
390 current_function_decl
= fndecl
;
391 cfun
= DECL_STRUCT_FUNCTION (fndecl
);
392 saved_loc
= input_location
;
393 input_location
= DECL_SOURCE_LOCATION (fndecl
);
394 init_function_start (fndecl
);
396 /* Even though we're inside a function body, we still don't want to
397 call expand_expr to calculate the size of a variable-sized array.
398 We haven't necessarily assigned RTL to all variables yet, so it's
399 not safe to try to expand expressions involving them. */
400 cfun
->x_dont_save_pending_sizes_p
= 1;
402 tree_register_cfg_hooks ();
404 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
405 /* Perform all tree transforms and optimizations. */
406 execute_pass_list (all_passes
);
408 bitmap_obstack_release (®_obstack
);
410 /* Release the default bitmap obstack. */
411 bitmap_obstack_release (NULL
);
413 DECL_SAVED_TREE (fndecl
) = NULL
;
416 /* If requested, warn about function definitions where the function will
417 return a value (usually of some struct or union type) which itself will
418 take up a lot of stack space. */
419 if (warn_larger_than
&& !DECL_EXTERNAL (fndecl
) && TREE_TYPE (fndecl
))
421 tree ret_type
= TREE_TYPE (TREE_TYPE (fndecl
));
423 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
424 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
425 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
428 unsigned int size_as_int
429 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
431 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
432 warning (0, "size of return value of %q+D is %u bytes",
433 fndecl
, size_as_int
);
435 warning (0, "size of return value of %q+D is larger than %wd bytes",
436 fndecl
, larger_than_size
);
440 if (!flag_inline_trees
)
442 DECL_SAVED_TREE (fndecl
) = NULL
;
443 if (DECL_STRUCT_FUNCTION (fndecl
) == 0
444 && !cgraph_node (fndecl
)->origin
)
446 /* Stop pointing to the local nodes about to be freed.
447 But DECL_INITIAL must remain nonzero so we know this
448 was an actual function definition.
449 For a nested function, this is done in c_pop_function_context.
450 If rest_of_compilation set this to 0, leave it 0. */
451 if (DECL_INITIAL (fndecl
) != 0)
452 DECL_INITIAL (fndecl
) = error_mark_node
;
456 input_location
= saved_loc
;
459 timevar_pop (TV_EXPAND
);