mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 03:20:27 +08:00
tree-optimize.c (has_abnormal_outgoing_edge_p): Move to tree-inline.
* tree-optimize.c (has_abnormal_outgoing_edge_p): Move to tree-inline. (execute_fixup_cfg): Break out the abnormal goto code. * tree-inline.c (has_abnormal_outgoing_edge_p): Move here from tree-optimize.c. (make_nonlocal_label_edges): Move here from execute_fixup_cfg. (optimize_inline_calls): Call make_nonlocal_label_edges. Co-Authored-By: Eric Botcazou <ebotcazou@libertysurf.fr> From-SVN: r121572
This commit is contained in:
parent
facbf9482d
commit
1084e68953
@ -1,3 +1,13 @@
|
||||
2007-02-04 Jan Hubicka <jh@suse.cz>
|
||||
Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* tree-optimize.c (has_abnormal_outgoing_edge_p): Move to tree-inline.
|
||||
(execute_fixup_cfg): Break out the abnormal goto code.
|
||||
* tree-inline.c (has_abnormal_outgoing_edge_p): Move here from
|
||||
tree-optimize.c.
|
||||
(make_nonlocal_label_edges): Move here from execute_fixup_cfg.
|
||||
(optimize_inline_calls): Call make_nonlocal_label_edges.
|
||||
|
||||
2007-02-04 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Return
|
||||
|
@ -2676,6 +2676,75 @@ fold_marked_statements (int first, struct pointer_set_t *statements)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* When a block from the inlined function contains a call with side-effects
|
||||
in the middle gets inlined in a function with non-locals labels, the call
|
||||
becomes a potential non-local goto so we need to add appropriate edge. */
|
||||
|
||||
static void
|
||||
make_nonlocal_label_edges (void)
|
||||
{
|
||||
block_stmt_iterator bsi;
|
||||
basic_block bb;
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand calls to inline functions in the body of FN. */
|
||||
|
||||
unsigned int
|
||||
@ -2751,6 +2820,8 @@ optimize_inline_calls (tree fn)
|
||||
fold_marked_statements (last, id.statements_to_fold);
|
||||
pointer_set_destroy (id.statements_to_fold);
|
||||
fold_cond_expr_cond ();
|
||||
if (current_function_has_nonlocal_label)
|
||||
make_nonlocal_label_edges ();
|
||||
/* We make no attempts to keep dominance info up-to-date. */
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
|
@ -267,25 +267,9 @@ struct tree_opt_pass pass_free_cfg_annotations =
|
||||
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.
|
||||
|
||||
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. */
|
||||
@ -327,53 +311,6 @@ execute_fixup_cfg (void)
|
||||
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))
|
||||
{
|
||||
todo |= TODO_update_ssa | TODO_cleanup_cfg;
|
||||
gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI
|
||||
(PHI_RESULT (phi)));
|
||||
mark_sym_for_renaming
|
||||
(SSA_NAME_VAR (PHI_RESULT (phi)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump a textual representation of the flowgraph. */
|
||||
if (dump_file)
|
||||
dump_tree_cfg (dump_file, dump_flags);
|
||||
|
Loading…
x
Reference in New Issue
Block a user