0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- 0, /* todo_flags_finish */
+ TODO_remove_functions, /* todo_flags_finish */
0 /* letter */
};
static unsigned int
execute_free_datastructures (void)
{
- /* ??? This isn't the right place for this. Worse, it got computed
- more or less at random in various passes. */
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
- /* Remove the ssa structures. Do it here since this includes statement
- annotations that need to be intact during disband_implicit_edges. */
+ /* Remove the ssa structures. */
if (cfun->gimple_df)
delete_tree_ssa ();
return 0;
static unsigned int
execute_free_cfg_annotations (void)
{
- /* Emit gotos for implicit jumps. */
- disband_implicit_edges ();
-
/* And get rid of annotations we no longer need. */
delete_tree_cfg_annotations ();
-#ifdef ENABLE_CHECKING
- /* Once the statement annotations have been removed, we can verify
- the integrity of statements in the EH throw table. */
- verify_eh_throw_table_statements ();
-#endif
return 0;
}
0 /* letter */
};
-/* Return true if BB has at least one abnormal outgoing edge. */
-
-static inline bool
-has_abnormal_outgoing_edge_p (basic_block bb)
-{
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->flags & EDGE_ABNORMAL)
- return true;
-
- return false;
-}
-
/* Pass: fixup_cfg. IPA passes, compilation of earlier functions or inlining
- might have changed some properties, such as marked functions nothrow or
- added calls that can potentially go to non-local labels. Remove redundant
- edges and basic blocks, and create new ones if necessary. */
+ might have changed some properties, such as marked functions nothrow.
+ Remove redundant edges and basic blocks, and create new ones if necessary.
-static unsigned int
+ This pass can't be executed as stand alone pass from pass manager, because
+ in between inlining and this fixup the verify_flow_info would fail. */
+
+unsigned int
execute_fixup_cfg (void)
{
basic_block bb;
block_stmt_iterator bsi;
+ int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
cfun->after_inlining = true;
if (decl && call_expr_flags (call) & (ECF_CONST | ECF_PURE)
&& TREE_SIDE_EFFECTS (call))
{
- update_stmt (stmt);
+ if (gimple_in_ssa_p (cfun))
+ {
+ todo |= TODO_update_ssa | TODO_cleanup_cfg;
+ update_stmt (stmt);
+ }
TREE_SIDE_EFFECTS (call) = 0;
}
if (decl && TREE_NOTHROW (decl))
if (!tree_could_throw_p (stmt) && lookup_stmt_eh_region (stmt))
remove_stmt_from_eh_region (stmt);
}
- tree_purge_dead_eh_edges (bb);
+ if (tree_purge_dead_eh_edges (bb))
+ todo |= TODO_cleanup_cfg;
}
- if (current_function_has_nonlocal_label)
- {
- FOR_EACH_BB (bb)
- {
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- tree stmt = bsi_stmt (bsi);
- if (tree_can_make_abnormal_goto (stmt))
- {
- if (stmt == bsi_stmt (bsi_last (bb)))
- {
- if (!has_abnormal_outgoing_edge_p (bb))
- make_abnormal_goto_edges (bb, true);
- }
- else
- {
- edge e = split_block (bb, stmt);
- bb = e->src;
- make_abnormal_goto_edges (bb, true);
- }
- break;
- }
-
- /* Update PHIs on nonlocal goto receivers we (possibly)
- just created new edges into. */
- if (TREE_CODE (stmt) == LABEL_EXPR
- && gimple_in_ssa_p (cfun))
- {
- tree target = LABEL_EXPR_LABEL (stmt);
- if (DECL_NONLOCAL (target))
- {
- tree phi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- {
- gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI
- (PHI_RESULT (phi)));
- mark_sym_for_renaming
- (SSA_NAME_VAR (PHI_RESULT (phi)));
- }
- }
- }
- }
- }
- }
-
- if (gimple_in_ssa_p (cfun))
- {
- delete_unreachable_blocks ();
- update_ssa (TODO_update_ssa);
- }
- cleanup_tree_cfg ();
-
/* Dump a textual representation of the flowgraph. */
if (dump_file)
dump_tree_cfg (dump_file, dump_flags);
- return 0;
+ return todo;
}
-struct tree_opt_pass pass_fixup_cfg =
-{
- "fixupcfg", /* name */
- NULL, /* gate */
- execute_fixup_cfg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- 0, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- 0 /* letter */
-};
-
/* Do the actions required to initialize internal data structures used
in tree-ssa optimization passes. */
bitmap_obstack_release (NULL);
pop_cfun ();
}
-
-/* Update recursively all inlined_to pointers of functions
- inlined into NODE to INLINED_TO. */
-static void
-update_inlined_to_pointers (struct cgraph_node *node,
- struct cgraph_node *inlined_to)
-{
- struct cgraph_edge *e;
- for (e = node->callees; e; e = e->next_callee)
- {
- if (e->callee->global.inlined_to)
- {
- e->callee->global.inlined_to = inlined_to;
- update_inlined_to_pointers (e->callee, inlined_to);
- }
- }
-}
-
\f
/* For functions-as-trees languages, this performs all optimization and
compilation for FNDECL. */
/* Initialize the default bitmap obstack. */
bitmap_obstack_initialize (NULL);
- /* We might need the body of this function so that we can expand
- it inline somewhere else. */
- if (cgraph_preserve_function_body_p (fndecl))
- save_inline_function_body (node);
-
/* Initialize the RTL code for the function. */
current_function_decl = fndecl;
+ cfun = DECL_STRUCT_FUNCTION (fndecl);
saved_loc = input_location;
input_location = DECL_SOURCE_LOCATION (fndecl);
init_function_start (fndecl);
tree_register_cfg_hooks ();
- if (flag_inline_trees)
- {
- struct cgraph_edge *e;
- for (e = node->callees; e; e = e->next_callee)
- if (!e->inline_failed || warn_inline)
- break;
- if (e)
- {
- timevar_push (TV_INTEGRATION);
- optimize_inline_calls (fndecl);
- timevar_pop (TV_INTEGRATION);
- }
- }
- /* In non-unit-at-a-time we must mark all referenced functions as needed.
- */
- if (!flag_unit_at_a_time)
- {
- struct cgraph_edge *e;
- for (e = node->callees; e; e = e->next_callee)
- if (e->callee->analyzed)
- cgraph_mark_needed_node (e->callee);
- }
-
- /* We are not going to maintain the cgraph edges up to date.
- Kill it so it won't confuse us. */
- cgraph_node_remove_callees (node);
-
bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/
/* Perform all tree transforms and optimizations. */
execute_pass_list (all_passes);