diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-07 17:53:03 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-07 17:53:03 +0000 |
commit | 22e30d4e88b409c985b8ab88a5c51cda27c47e0b (patch) | |
tree | ae09b8f6224714650658af6382e87de0bae03de0 /gcc/gimple-low.c | |
parent | d201fb451bc3fb576a48800121e49a1930b5a5e4 (diff) | |
download | gcc-22e30d4e88b409c985b8ab88a5c51cda27c47e0b.tar.gz |
* gimple-low.c (struct lower_data): Add the_return_label and
one_return_stmt.
(lower_function_body): Initialize and use them.
(lower_return_expr): New.
(lower_stmt): Call it.
* gimplify.c (gimplify_return_expr): Force the argument to be either
null or a result_decl.
* tree-gimple.c: Update gimple grammer to match.
* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Deny
coalescing of result_decls.
testsuite/
* gcc.dg/tree-ssa/20030728-1.c: Fixup return value to not match
if temporaries.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82701 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimple-low.c')
-rw-r--r-- | gcc/gimple-low.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 56f02b7a1ee..458980f898f 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -46,11 +46,16 @@ struct lower_data { /* Block the current statement belongs to. */ tree block; + + /* Label that unifies the return statements. */ + tree the_return_label; + tree one_return_stmt; }; static void lower_stmt (tree_stmt_iterator *, struct lower_data *); static void lower_bind_expr (tree_stmt_iterator *, struct lower_data *); static void lower_cond_expr (tree_stmt_iterator *, struct lower_data *); +static void lower_return_expr (tree_stmt_iterator *, struct lower_data *); static bool expand_var_p (tree); /* Lowers the body of current_function_decl. */ @@ -71,11 +76,25 @@ lower_function_body (void) BLOCK_CHAIN (data.block) = NULL_TREE; TREE_ASM_WRITTEN (data.block) = 1; + data.the_return_label = NULL_TREE; + data.one_return_stmt = NULL_TREE; + *body_p = alloc_stmt_list (); i = tsi_start (*body_p); tsi_link_after (&i, bind, TSI_NEW_STMT); lower_bind_expr (&i, &data); + /* If we lowered any return statements, emit the representative at the + end of the function. */ + if (data.one_return_stmt) + { + tree t; + t = build (LABEL_EXPR, void_type_node, data.the_return_label); + i = tsi_last (*body_p); + tsi_link_after (&i, t, TSI_CONTINUE_LINKING); + tsi_link_after (&i, data.one_return_stmt, TSI_CONTINUE_LINKING); + } + if (data.block != DECL_INITIAL (current_function_decl)) abort (); BLOCK_SUBBLOCKS (data.block) @@ -136,6 +155,9 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data) case COND_EXPR: lower_cond_expr (tsi, data); return; + case RETURN_EXPR: + lower_return_expr (tsi, data); + return; case TRY_FINALLY_EXPR: case TRY_CATCH_EXPR: @@ -151,7 +173,6 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data) case NOP_EXPR: case ASM_EXPR: - case RETURN_EXPR: case MODIFY_EXPR: case CALL_EXPR: case GOTO_EXPR: @@ -367,6 +388,22 @@ lower_cond_expr (tree_stmt_iterator *tsi, struct lower_data *data) tsi_next (tsi); } + +static void +lower_return_expr (tree_stmt_iterator *tsi, struct lower_data *data) +{ + tree stmt, label = data->the_return_label; + + if (!label) + { + data->the_return_label = label = create_artificial_label (); + data->one_return_stmt = tsi_stmt (*tsi); + } + + stmt = build (GOTO_EXPR, void_type_node, label); + tsi_link_before (tsi, stmt, TSI_SAME_STMT); + tsi_delink (tsi); +} /* Record the variables in VARS. */ @@ -468,5 +505,3 @@ struct tree_opt_pass pass_remove_useless_vars = 0, /* todo_flags_start */ TODO_dump_func /* todo_flags_finish */ }; - - |