summaryrefslogtreecommitdiff
path: root/gcc/gimple-low.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-07 17:53:03 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-07 17:53:03 +0000
commit22e30d4e88b409c985b8ab88a5c51cda27c47e0b (patch)
treeae09b8f6224714650658af6382e87de0bae03de0 /gcc/gimple-low.c
parentd201fb451bc3fb576a48800121e49a1930b5a5e4 (diff)
downloadgcc-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.c41
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 */
};
-
-