tree-gimple.c (is_gimple_reg_rhs, [...]): New fns.
authorJason Merrill <jason@redhat.com>
Wed, 14 Jul 2004 18:16:48 +0000 (14:16 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 14 Jul 2004 18:16:48 +0000 (14:16 -0400)
        * tree-gimple.c (is_gimple_reg_rhs, is_gimple_mem_rhs): New fns.
        (rhs_test_for): New fn.
        (is_gimple_tmp_rhs): Rename from is_gimple_rhs.
        * tree-gimple.h: Declare them.
        * gimplify.c (gimplify_modify_expr): Use the new fns.

From-SVN: r84696

gcc/ChangeLog
gcc/gimplify.c
gcc/tree-gimple.c
gcc/tree-gimple.h

index 59ee70e7dd12c7167e79654495f961eff8785a05..1e179dddd30de4b2652a05c69023c4e8041b5447 100644 (file)
@@ -1,3 +1,11 @@
+2004-07-13  Jason Merrill  <jason@redhat.com>
+
+       * tree-gimple.c (is_gimple_reg_rhs, is_gimple_mem_rhs): New fns.
+       (rhs_test_for): New fn.
+       (is_gimple_tmp_rhs): Rename from is_gimple_rhs.
+       * tree-gimple.h: Declare them.
+       * gimplify.c (gimplify_modify_expr): Use the new fns.
+
 2004-07-14  Richard Henderson  <rth@redhat.com>
 
        * config/arm/arm-protos.h (arm_va_arg): Remove.
index 770739af04aa013478b04d40bfb8dca27a6b3ab4..d1b9618f059526c4c1477aa5936bacb6867412b4 100644 (file)
@@ -446,7 +446,7 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
   tree t, mod;
   char class;
 
-  gimplify_expr (&val, pre_p, post_p, is_gimple_rhs, fb_rvalue);
+  gimplify_expr (&val, pre_p, post_p, is_gimple_tmp_rhs, fb_rvalue);
 
   t = lookup_tmp_var (val, is_formal);
 
@@ -2610,7 +2610,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
            ctor = build (COMPLEX_EXPR, type, r, i);
            TREE_OPERAND (*expr_p, 1) = ctor;
            ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
-                                is_gimple_rhs, fb_rvalue);
+                                is_gimple_tmp_rhs, fb_rvalue);
          }
       }
       break;
@@ -2780,7 +2780,8 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
   if (ret == GS_ERROR)
     return ret;
 
-  ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_rhs, fb_rvalue);
+  ret = gimplify_expr (from_p, pre_p, post_p,
+                      rhs_predicate_for (*to_p), fb_rvalue);
   if (ret == GS_ERROR)
     return ret;
 
@@ -2791,33 +2792,10 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
     return ret;
 
   /* If the destination is already simple, nothing else needed.  */
-  if (is_gimple_tmp_var (*to_p))
+  if (is_gimple_tmp_var (*to_p) || !want_value)
     ret = GS_ALL_DONE;
   else
-    {
-      /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto and
-        the LHS is a user variable, then we need to introduce a temporary.
-        ie temp = RHS; LHS = temp.
-
-        This way the optimizers can determine that the user variable is
-        only modified if evaluation of the RHS does not throw.
-
-        FIXME this should be handled by the is_gimple_rhs predicate.  */
-
-      if (aggregate_value_p (TREE_TYPE (*from_p), NULL_TREE))
-       /* Don't force a temp of a large aggregate type; the copy could be
-          arbitrarily expensive.  Instead we will generate a V_MAY_DEF for
-          the assignment.  */;
-      else if (TREE_CODE (*from_p) == CALL_EXPR
-              || (flag_non_call_exceptions && tree_could_trap_p (*from_p))
-              /* If we're dealing with a renamable type, either source or dest
-                 must be a renamed variable.  */
-              || (is_gimple_reg_type (TREE_TYPE (*from_p))
-                  && !is_gimple_reg (*to_p)))
-       gimplify_expr (from_p, pre_p, post_p, is_gimple_val, fb_rvalue);
-
-      ret = want_value ? GS_OK : GS_ALL_DONE;
-    }
+    ret = GS_OK;
 
   if (want_value)
     {
@@ -3975,7 +3953,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
       *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
     }
-  else if ((fallback & fb_rvalue) && is_gimple_rhs (*expr_p))
+  else if ((fallback & fb_rvalue) && is_gimple_tmp_rhs (*expr_p))
     {
 #if defined ENABLE_CHECKING
       if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
index 97a34a1182ae59a0d05f8eccb2cb8a7ab38f1d07..193f093a8e34d290144d58512d77cbac8b8c5342 100644 (file)
@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA.  */
 #include "tm.h"
 #include "tree.h"
 #include "tree-gimple.h"
+#include "tree-flow.h"
 #include "output.h"
 #include "rtl.h"
 #include "expr.h"
@@ -172,10 +173,10 @@ static inline bool is_gimple_id (tree);
 
 /* Validation of GIMPLE expressions.  */
 
-/* Return true if T is a GIMPLE RHS.  */
+/* Return true if T is a GIMPLE RHS for an assignment to a temporary.  */
 
 bool
-is_gimple_rhs (tree t)
+is_gimple_tmp_rhs (tree t)
 {
   enum tree_code code = TREE_CODE (t);
 
@@ -217,6 +218,57 @@ is_gimple_rhs (tree t)
   return is_gimple_lvalue (t) || is_gimple_val (t);
 }
 
+/* Returns true iff T is a valid RHS for an assignment to a renamed user
+   variable.  */
+
+bool
+is_gimple_reg_rhs (tree t)
+{
+  /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto and
+     the LHS is a user variable, then we need to introduce a temporary.
+     ie temp = RHS; LHS = temp.
+
+     This way the optimizers can determine that the user variable is
+     only modified if evaluation of the RHS does not throw.  */
+  if (is_gimple_reg_type (TREE_TYPE (t))
+      && TREE_SIDE_EFFECTS (t)
+      && (TREE_CODE (t) == CALL_EXPR
+         || (flag_non_call_exceptions && tree_could_trap_p (t))))
+    return is_gimple_val (t);
+  else
+    /* Don't force a temp of a non-renamable type; the copy could be
+       arbitrarily expensive.  Instead we will generate a V_MAY_DEF for
+       the assignment.  */
+    return is_gimple_tmp_rhs (t);
+}
+
+/* Returns true iff T is a valid RHS for an assignment to an un-renamed
+   LHS, or for a call argument.  */
+
+bool
+is_gimple_mem_rhs (tree t)
+{
+  /* If we're dealing with a renamable type, either source or dest
+     must be a renamed variable.  */
+  if (is_gimple_reg_type (TREE_TYPE (t)))
+    return is_gimple_val (t);
+  else
+    return is_gimple_tmp_rhs (t);
+}
+
+/* Returns the appropriate RHS predicate for this LHS.  */
+
+gimple_predicate
+rhs_predicate_for (tree lhs)
+{
+  if (is_gimple_tmp_var (lhs))
+    return is_gimple_tmp_rhs;
+  else if (is_gimple_reg (lhs))
+    return is_gimple_reg_rhs;
+  else
+    return is_gimple_mem_rhs;
+}
+
 /* Returns true if T is a valid CONSTRUCTOR component in GIMPLE, either
    a val or another CONSTRUCTOR.  */
 
index 5395c67667c341003d8bd3a130cbb0699caf7f58..32647a002b89d3020769810763e3368c73f8db8d 100644 (file)
@@ -39,6 +39,8 @@ extern void annotate_all_with_locus (tree *, location_t);
    the basic form of the expression, they don't recurse to make sure that
    underlying nodes are also of the right form.  */
 
+typedef bool (*gimple_predicate)(tree);
+
 /* Returns true iff T is a valid GIMPLE statement.  */
 extern bool is_gimple_stmt (tree);
 
@@ -59,8 +61,15 @@ extern bool is_gimple_lvalue (tree);
 extern bool is_gimple_min_invariant (tree);
 /* Returns true iff T is a GIMPLE rvalue.  */
 extern bool is_gimple_val (tree);
-/* Returns true iff T is a valid rhs for a MODIFY_EXPR.  */
-extern bool is_gimple_rhs (tree);
+/* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
+   GIMPLE temporary, a renamed user variable, or something else,
+   respectively.  */
+extern bool is_gimple_tmp_rhs (tree);
+extern bool is_gimple_reg_rhs (tree);
+extern bool is_gimple_mem_rhs (tree);
+/* Returns the appropriate one of the above three predicates for the LHS
+   T.  */
+extern gimple_predicate rhs_predicate_for (tree);
 
 /* Returns true iff T is a valid if-statement condition.  */
 extern bool is_gimple_condexpr (tree);