OSDN Git Service

* gimple-low.c (struct lower_data): Add the_return_label and
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Jun 2004 17:53:03 +0000 (17:53 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Jun 2004 17:53:03 +0000 (17:53 +0000)
        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

gcc/ChangeLog
gcc/gimple-low.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
gcc/tree-gimple.c
gcc/tree-ssa-copyrename.c

index a096a8a..e42f1cc 100644 (file)
@@ -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.
 
index 56f02b7..458980f 100644 (file)
@@ -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);
+}
 \f
 
 /* 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 */
 };
-
-
index 20d1945..8ec6e0d 100644 (file)
@@ -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;
 }
 
index af1f8d8..8063bac 100644 (file)
@@ -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.
index 4bc04bc..04d5a51 100644 (file)
@@ -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);
index e749ec8..4643ac6 100644 (file)
@@ -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
index dd69883..369c02f 100644 (file)
@@ -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);