aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-06-07 10:53:03 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-06-07 10:53:03 -0700
commitf5a76aea0ddbb87fe8b4f64a283951d7e687b84c (patch)
treeae09b8f6224714650658af6382e87de0bae03de0
parent8cd0b81e9e372e8d7ff510d59e74e1a74616d773 (diff)
downloadgcc-f5a76aea0ddbb87fe8b4f64a283951d7e687b84c.zip
gcc-f5a76aea0ddbb87fe8b4f64a283951d7e687b84c.tar.gz
gcc-f5a76aea0ddbb87fe8b4f64a283951d7e687b84c.tar.bz2
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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/gimple-low.c41
-rw-r--r--gcc/gimplify.c49
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c2
-rw-r--r--gcc/tree-gimple.c4
-rw-r--r--gcc/tree-ssa-copyrename.c7
7 files changed, 68 insertions, 53 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a096a8a..e42f1cc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
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
* expmed.c (extract_bit_field): Fix vector_extract return.
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 56f02b7..458980f 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 */
};
-
-
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 20d1945..8ec6e0d 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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
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) = 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;
- }
+ TREE_OPERAND (stmt, 0) = result;
- append_to_statement_list (ret_expr, pre_p);
return GS_ALL_DONE;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index af1f8d8..8063bac 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
* g++.dg/eh/elide1.C: Remove XFAIL.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
index 4bc04bc..04d5a51 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
@@ -35,7 +35,7 @@ objects_must_conflict_p (t1, t2)
if ((t1->common.code == ARRAY_TYPE) != (t2
&& t2->common.code == ARRAY_TYPE))
- return 0;
+ return 11;
return foo (t2 ? get_alias_set (t2) : 0);
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c
index e749ec8..4643ac6 100644
--- a/gcc/tree-gimple.c
+++ b/gcc/tree-gimple.c
@@ -79,9 +79,7 @@ Boston, MA 02111-1307, USA. */
GOTO_EXPR
op0 -> LABEL_DECL | '*' ID
| RETURN_EXPR
- op0 -> modify-stmt | NULL_TREE
- (maybe -> RESULT_DECL | NULL_TREE? seems like some of expand_return
- depends on getting a MODIFY_EXPR.)
+ op0 -> RESULT_DECL | NULL_TREE
| THROW_EXPR? do we need/want such a thing for opts, perhaps
to generate an ERT_THROW region? I think so.
Hmm...this would only work at the GIMPLE level, where we know that
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index dd69883..369c02f 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -187,6 +187,13 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
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);
gimp2 = is_gimple_tmp_var (root2);