Commit f5a76aea by Richard Henderson Committed by Richard Henderson

gimple-low.c (struct lower_data): Add the_return_label and one_return_stmt.

        * 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.

From-SVN: r82701
parent 8cd0b81e
2004-06-07 Richard Henderson <rth@redhat.com> 2004-06-07 Richard Henderson <rth@redhat.com>
* 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.
2004-06-07 Richard Henderson <rth@redhat.com>
PR rtl-opt/15193 PR rtl-opt/15193
* expmed.c (extract_bit_field): Fix vector_extract return. * expmed.c (extract_bit_field): Fix vector_extract return.
......
...@@ -46,11 +46,16 @@ struct lower_data ...@@ -46,11 +46,16 @@ struct lower_data
{ {
/* Block the current statement belongs to. */ /* Block the current statement belongs to. */
tree block; 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_stmt (tree_stmt_iterator *, struct lower_data *);
static void lower_bind_expr (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_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); static bool expand_var_p (tree);
/* Lowers the body of current_function_decl. */ /* Lowers the body of current_function_decl. */
...@@ -71,11 +76,25 @@ lower_function_body (void) ...@@ -71,11 +76,25 @@ lower_function_body (void)
BLOCK_CHAIN (data.block) = NULL_TREE; BLOCK_CHAIN (data.block) = NULL_TREE;
TREE_ASM_WRITTEN (data.block) = 1; TREE_ASM_WRITTEN (data.block) = 1;
data.the_return_label = NULL_TREE;
data.one_return_stmt = NULL_TREE;
*body_p = alloc_stmt_list (); *body_p = alloc_stmt_list ();
i = tsi_start (*body_p); i = tsi_start (*body_p);
tsi_link_after (&i, bind, TSI_NEW_STMT); tsi_link_after (&i, bind, TSI_NEW_STMT);
lower_bind_expr (&i, &data); 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)) if (data.block != DECL_INITIAL (current_function_decl))
abort (); abort ();
BLOCK_SUBBLOCKS (data.block) BLOCK_SUBBLOCKS (data.block)
...@@ -136,6 +155,9 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data) ...@@ -136,6 +155,9 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
case COND_EXPR: case COND_EXPR:
lower_cond_expr (tsi, data); lower_cond_expr (tsi, data);
return; return;
case RETURN_EXPR:
lower_return_expr (tsi, data);
return;
case TRY_FINALLY_EXPR: case TRY_FINALLY_EXPR:
case TRY_CATCH_EXPR: case TRY_CATCH_EXPR:
...@@ -151,7 +173,6 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data) ...@@ -151,7 +173,6 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
case NOP_EXPR: case NOP_EXPR:
case ASM_EXPR: case ASM_EXPR:
case RETURN_EXPR:
case MODIFY_EXPR: case MODIFY_EXPR:
case CALL_EXPR: case CALL_EXPR:
case GOTO_EXPR: case GOTO_EXPR:
...@@ -367,6 +388,22 @@ lower_cond_expr (tree_stmt_iterator *tsi, struct lower_data *data) ...@@ -367,6 +388,22 @@ lower_cond_expr (tree_stmt_iterator *tsi, struct lower_data *data)
tsi_next (tsi); 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. */ /* Record the variables in VARS. */
...@@ -468,5 +505,3 @@ struct tree_opt_pass pass_remove_useless_vars = ...@@ -468,5 +505,3 @@ struct tree_opt_pass pass_remove_useless_vars =
0, /* todo_flags_start */ 0, /* todo_flags_start */
TODO_dump_func /* todo_flags_finish */ TODO_dump_func /* todo_flags_finish */
}; };
...@@ -899,54 +899,11 @@ gimplify_return_expr (tree stmt, tree *pre_p) ...@@ -899,54 +899,11 @@ gimplify_return_expr (tree stmt, tree *pre_p)
/* We need to pass the full MODIFY_EXPR down so that special handling /* We need to pass the full MODIFY_EXPR down so that special handling
can replace it with something else. */ can replace it with something else. */
gimplify_stmt (&ret_expr); gimplify_stmt (&TREE_OPERAND (stmt, 0));
append_to_statement_list (TREE_OPERAND (stmt, 0), pre_p);
if (result == NULL_TREE) TREE_OPERAND (stmt, 0) = result;
TREE_OPERAND (stmt, 0) = NULL_TREE;
else if (ret_expr == TREE_OPERAND (stmt, 0))
/* It was already GIMPLE. */
return GS_ALL_DONE;
else
{
/* If there's still a MODIFY_EXPR of the RESULT_DECL after
gimplification, find it so we can put it in the RETURN_EXPR. */
tree ret = NULL_TREE;
if (TREE_CODE (ret_expr) == STATEMENT_LIST)
{
tree_stmt_iterator si;
for (si = tsi_start (ret_expr); !tsi_end_p (si); tsi_next (&si))
{
tree sub = tsi_stmt (si);
if (TREE_CODE (sub) == MODIFY_EXPR
&& TREE_OPERAND (sub, 0) == result)
{
ret = sub;
if (tsi_one_before_end_p (si))
tsi_delink (&si);
else
{
/* If there were posteffects after the MODIFY_EXPR,
we need a temporary. */
tree tmp = create_tmp_var (TREE_TYPE (result), "retval");
TREE_OPERAND (ret, 0) = tmp;
ret = build (MODIFY_EXPR, TREE_TYPE (result),
result, tmp);
}
break;
}
}
}
if (ret)
TREE_OPERAND (stmt, 0) = ret;
else
/* The return value must be set up some other way. Just tell
expand_return that we're returning the RESULT_DECL. */
TREE_OPERAND (stmt, 0) = result;
}
append_to_statement_list (ret_expr, pre_p);
return GS_ALL_DONE; return GS_ALL_DONE;
} }
......
2004-06-07 Richard Henderson <rth@redhat.com>
* gcc.dg/tree-ssa/20030728-1.c: Fixup return value to not match
if temporaries.
2004-06-07 David Edelsohn <edelsohn@gnu.org> 2004-06-07 David Edelsohn <edelsohn@gnu.org>
* g++.dg/eh/elide1.C: Remove XFAIL. * g++.dg/eh/elide1.C: Remove XFAIL.
......
...@@ -35,7 +35,7 @@ objects_must_conflict_p (t1, t2) ...@@ -35,7 +35,7 @@ objects_must_conflict_p (t1, t2)
if ((t1->common.code == ARRAY_TYPE) != (t2 if ((t1->common.code == ARRAY_TYPE) != (t2
&& t2->common.code == ARRAY_TYPE)) && t2->common.code == ARRAY_TYPE))
return 0; return 11;
return foo (t2 ? get_alias_set (t2) : 0); return foo (t2 ? get_alias_set (t2) : 0);
......
...@@ -79,9 +79,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -79,9 +79,7 @@ Boston, MA 02111-1307, USA. */
GOTO_EXPR GOTO_EXPR
op0 -> LABEL_DECL | '*' ID op0 -> LABEL_DECL | '*' ID
| RETURN_EXPR | RETURN_EXPR
op0 -> modify-stmt | NULL_TREE op0 -> RESULT_DECL | NULL_TREE
(maybe -> RESULT_DECL | NULL_TREE? seems like some of expand_return
depends on getting a MODIFY_EXPR.)
| THROW_EXPR? do we need/want such a thing for opts, perhaps | THROW_EXPR? do we need/want such a thing for opts, perhaps
to generate an ERT_THROW region? I think so. to generate an ERT_THROW region? I think so.
Hmm...this would only work at the GIMPLE level, where we know that Hmm...this would only work at the GIMPLE level, where we know that
......
...@@ -187,6 +187,13 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) ...@@ -187,6 +187,13 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
return; return;
} }
if ((TREE_CODE (root1) == RESULT_DECL) != (TREE_CODE (root2) == RESULT_DECL))
{
if (debug)
fprintf (debug, " : One root a RESULT_DECL. No coalesce.\n");
return;
}
gimp1 = is_gimple_tmp_var (root1); gimp1 = is_gimple_tmp_var (root1);
gimp2 = is_gimple_tmp_var (root2); gimp2 = is_gimple_tmp_var (root2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment