]> gcc.gnu.org Git - gcc.git/commitdiff
re PR middle-end/23401 (Gimplifier produces too many temporaries)
authorRichard Guenther <rguenther@suse.de>
Tue, 31 Mar 2009 10:23:44 +0000 (10:23 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 31 Mar 2009 10:23:44 +0000 (10:23 +0000)
2009-03-31  Richard Guenther  <rguenther@suse.de>

PR middle-end/23401
PR middle-end/27810
* tree.h (DECL_GIMPLE_FORMAL_TEMP_P): Remove.
(struct tree_decl_with_vis): Remove gimple_formal_temp member.
* tree-eh.c (lower_eh_constructs_2): Move LHS assignment to
a separate statement.
* gimplify.c (pop_gimplify_context): Remove formal temp handling.
(lookup_tmp_var): Likewise.
(is_gimple_formal_tmp_or_call_rhs): Remove.
(is_gimple_reg_or_call_rhs): Rename to ...
(is_gimple_reg_rhs_or_call): ... this.
(is_gimple_mem_or_call_rhs): Rename to ...
(is_gimple_mem_rhs_or_call): ... this.
(internal_get_tmp_var): Use is_gimple_reg_rhs_or_call.  Set
DECL_GIMPLE_REG_P only if is_formal is true.
(gimplify_compound_lval): Use is_gimple_reg.  Remove workaround
for non-proper post-modify expression gimplification.
(gimplify_self_mod_expr): For post-modify expressions gimplify
the lvalue to a minimal lvalue.
(rhs_predicate_for): Remove formal temp case.
(gimplify_modify_expr_rhs): Likewise.
(gimplify_addr_expr): Use is_gimple_reg.
(gimplify_expr): Remove formal temp cases.
(gimple_regimplify_operands): Likewise.
* tree-ssa-pre.c (get_or_alloc_expr_for): Treat EXC_PTR_EXPR
and FILTER_EXPR like constants.
* gimple.c (walk_gimple_op): Fix val_only initialization, use
is_gimple_reg.
(is_gimple_formal_tmp_rhs): Remove.
(is_gimple_reg_rhs): Remove special casing.
(is_gimple_mem_rhs): Fix.
(is_gimple_reg): Move DECL_GIMPLE_REG_P handling earlier.
(is_gimple_formal_tmp_var): Remove.
(is_gimple_formal_tmp_reg): Likewise.
(is_gimple_min_lval): Allow invariant component ref parts.
* gimple.h (is_gimple_formal_tmp_rhs, is_gimple_formal_tmp_var,
is_gimple_formal_tmp_reg): Remove declarations.
* tree-cfg.c (verify_expr): Verify that variables with address
taken do not have DECL_GIMPLE_REG_P set.
* tree-mudflap.c (mf_build_check_statement_for): Use
force_gimple_operand instead of gimplify_expr.

java/
* java-gimplify.c (java_gimplify_expr): Do not manually gimplify
the first operand of binary and comaprison expressions.

* gcc.dg/tree-ssa/pr23401.c: New testcase.
* gcc.dg/tree-ssa/pr27810.c: Likewise.

From-SVN: r145338

14 files changed:
gcc/ChangeLog
gcc/gimple.c
gcc/gimple.h
gcc/gimplify.c
gcc/java/ChangeLog
gcc/java/java-gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr23401.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr27810.c [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-eh.c
gcc/tree-mudflap.c
gcc/tree-ssa-pre.c
gcc/tree.h

index 81886235bd6ec950513e9088f4abec35cb71cc17..15a8228c6cf9623715828fcfd893f3324a0e2a6e 100644 (file)
@@ -1,3 +1,47 @@
+2009-03-31  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/23401
+       PR middle-end/27810
+       * tree.h (DECL_GIMPLE_FORMAL_TEMP_P): Remove.
+       (struct tree_decl_with_vis): Remove gimple_formal_temp member.
+       * tree-eh.c (lower_eh_constructs_2): Move LHS assignment to
+       a separate statement.
+       * gimplify.c (pop_gimplify_context): Remove formal temp handling.
+       (lookup_tmp_var): Likewise.
+       (is_gimple_formal_tmp_or_call_rhs): Remove.
+       (is_gimple_reg_or_call_rhs): Rename to ...
+       (is_gimple_reg_rhs_or_call): ... this.
+       (is_gimple_mem_or_call_rhs): Rename to ...
+       (is_gimple_mem_rhs_or_call): ... this.
+       (internal_get_tmp_var): Use is_gimple_reg_rhs_or_call.  Set
+       DECL_GIMPLE_REG_P only if is_formal is true.
+       (gimplify_compound_lval): Use is_gimple_reg.  Remove workaround
+       for non-proper post-modify expression gimplification.
+       (gimplify_self_mod_expr): For post-modify expressions gimplify
+       the lvalue to a minimal lvalue.
+       (rhs_predicate_for): Remove formal temp case.
+       (gimplify_modify_expr_rhs): Likewise.
+       (gimplify_addr_expr): Use is_gimple_reg.
+       (gimplify_expr): Remove formal temp cases.
+       (gimple_regimplify_operands): Likewise.
+       * tree-ssa-pre.c (get_or_alloc_expr_for): Treat EXC_PTR_EXPR
+       and FILTER_EXPR like constants.
+       * gimple.c (walk_gimple_op): Fix val_only initialization, use
+       is_gimple_reg.
+       (is_gimple_formal_tmp_rhs): Remove.
+       (is_gimple_reg_rhs): Remove special casing.
+       (is_gimple_mem_rhs): Fix.
+       (is_gimple_reg): Move DECL_GIMPLE_REG_P handling earlier.
+       (is_gimple_formal_tmp_var): Remove.
+       (is_gimple_formal_tmp_reg): Likewise.
+       (is_gimple_min_lval): Allow invariant component ref parts.
+       * gimple.h (is_gimple_formal_tmp_rhs, is_gimple_formal_tmp_var,
+       is_gimple_formal_tmp_reg): Remove declarations.
+       * tree-cfg.c (verify_expr): Verify that variables with address
+       taken do not have DECL_GIMPLE_REG_P set.
+       * tree-mudflap.c (mf_build_check_statement_for): Use
+       force_gimple_operand instead of gimplify_expr.
+
 2009-03-31  Ayal Zaks  <zaks@il.ibm.com>
 
        * modulo-sched.c (sms_schedule_by_order): Pass the actual
index 90de9b3ebc56e9160c781782c88366026148e1df..a1dd6a750723d31b41fefe0fd0f091d771e5d7c2 100644 (file)
@@ -1380,7 +1380,8 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
       /* Walk the RHS operands.  A formal temporary LHS may use a
         COMPONENT_REF RHS.  */
       if (wi)
-       wi->val_only = !is_gimple_formal_tmp_var (gimple_assign_lhs (stmt));
+       wi->val_only = !is_gimple_reg (gimple_assign_lhs (stmt))
+                       || !gimple_assign_single_p (stmt);
 
       for (i = 1; i < gimple_num_ops (stmt); i++)
        {
@@ -2559,37 +2560,13 @@ is_gimple_operand (const_tree op)
   return op && get_gimple_rhs_class (TREE_CODE (op)) == GIMPLE_SINGLE_RHS;
 }
 
-
-/* Return true if T is a GIMPLE RHS for an assignment to a temporary.  */
-
-bool
-is_gimple_formal_tmp_rhs (tree t)
-{
-  if (is_gimple_lvalue (t) || is_gimple_val (t))
-    return true;
-
-  return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
-}
-
 /* Returns true iff T is a valid RHS for an assignment to a renamed
    user -- or front-end generated artificial -- 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 formal
-     temporary.  This way the optimizers can determine that the user
-     variable is only modified if evaluation of the RHS does not throw.
-
-     Don't force a temp of a non-renamable type; the copy could be
-     arbitrarily expensive.  Instead we will generate a VDEF for
-     the assignment.  */
-
-  if (is_gimple_reg_type (TREE_TYPE (t)) && tree_could_throw_p (t))
-    return false;
-
-  return is_gimple_formal_tmp_rhs (t);
+  return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
 }
 
 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
@@ -2603,7 +2580,7 @@ is_gimple_mem_rhs (tree t)
   if (is_gimple_reg_type (TREE_TYPE (t)))
     return is_gimple_val (t);
   else
-    return is_gimple_formal_tmp_rhs (t);
+    return is_gimple_val (t) || is_gimple_lvalue (t);
 }
 
 /*  Return true if T is a valid LHS for a GIMPLE assignment expression.  */
@@ -2895,6 +2872,12 @@ is_gimple_reg (tree t)
   if (!is_gimple_variable (t))
     return false;
 
+  /* Complex and vector values must have been put into SSA-like form.
+     That is, no assignments to the individual components.  */
+  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+    return DECL_GIMPLE_REG_P (t);
+
   if (!is_gimple_reg_type (TREE_TYPE (t)))
     return false;
 
@@ -2921,45 +2904,10 @@ is_gimple_reg (tree t)
   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
     return false;
 
-  /* Complex and vector values must have been put into SSA-like form.
-     That is, no assignments to the individual components.  */
-  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
-      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
-    return DECL_GIMPLE_REG_P (t);
-
   return true;
 }
 
 
-/* Returns true if T is a GIMPLE formal temporary variable.  */
-
-bool
-is_gimple_formal_tmp_var (tree t)
-{
-  if (TREE_CODE (t) == SSA_NAME)
-    return true;
-
-  return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
-}
-
-/* Returns true if T is a GIMPLE formal temporary register variable.  */
-
-bool
-is_gimple_formal_tmp_reg (tree t)
-{
-  /* The intent of this is to get hold of a value that won't change.
-     An SSA_NAME qualifies no matter if its of a user variable or not.  */
-  if (TREE_CODE (t) == SSA_NAME)
-    return true;
-
-  /* We don't know the lifetime characteristics of user variables.  */
-  if (!is_gimple_formal_tmp_var (t))
-    return false;
-
-  /* Finally, it must be capable of being placed in a register.  */
-  return is_gimple_reg (t);
-}
-
 /* Return true if T is a GIMPLE variable whose address is not needed.  */
 
 bool
@@ -3006,6 +2954,8 @@ is_gimple_asm_val (tree t)
 bool
 is_gimple_min_lval (tree t)
 {
+  if (!(t = CONST_CAST_TREE (strip_invariant_refs (t))))
+    return false;
   return (is_gimple_id (t) || TREE_CODE (t) == INDIRECT_REF);
 }
 
index df9bccdc3cdcc02ad17d7896f2826c20062b5df9..b482c1d607dff2a405a08367f0c9e0bee758ddd9 100644 (file)
@@ -859,10 +859,6 @@ extern bool is_gimple_stmt (tree);
 extern bool is_gimple_reg_type (tree);
 /* Returns true iff T is a scalar register variable.  */
 extern bool is_gimple_reg (tree);
-/* Returns true if T is a GIMPLE temporary variable, false otherwise.  */
-extern bool is_gimple_formal_tmp_var (tree);
-/* Returns true if T is a GIMPLE temporary register variable.  */
-extern bool is_gimple_formal_tmp_reg (tree);
 /* Returns true iff T is any sort of variable.  */
 extern bool is_gimple_variable (tree);
 /* Returns true iff T is any sort of symbol.  */
@@ -894,7 +890,6 @@ extern bool is_gimple_asm_val (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_formal_tmp_rhs (tree);
 extern bool is_gimple_reg_rhs (tree);
 extern bool is_gimple_mem_rhs (tree);
 
index bd82051d158951754764ef441dc3a41e696cc86a..515c58ed57e9ead1a1dcd66f262daa2d7bb08116 100644 (file)
@@ -214,16 +214,12 @@ void
 pop_gimplify_context (gimple body)
 {
   struct gimplify_ctx *c = gimplify_ctxp;
-  tree t;
 
   gcc_assert (c && (c->bind_expr_stack == NULL
                    || VEC_empty (gimple, c->bind_expr_stack)));
   VEC_free (gimple, heap, c->bind_expr_stack);
   gimplify_ctxp = c->prev_context;
 
-  for (t = c->temps; t ; t = TREE_CHAIN (t))
-    DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
-
   if (body)
     declare_vars (c->temps, body, false);
   else
@@ -609,9 +605,6 @@ lookup_tmp_var (tree val, bool is_formal)
        }
     }
 
-  if (is_formal)
-    DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1;
-
   return ret;
 }
 
@@ -622,32 +615,10 @@ lookup_tmp_var (tree val, bool is_formal)
    gimplify_modify_expr.  */
 
 static bool
-is_gimple_formal_tmp_or_call_rhs (tree t)
+is_gimple_reg_rhs_or_call (tree t)
 {
-  return TREE_CODE (t) == CALL_EXPR || is_gimple_formal_tmp_rhs (t);
-}
-
-/* Returns true iff T is a valid RHS for an assignment to a renamed
-   user -- or front-end generated artificial -- variable.  */
-
-static bool
-is_gimple_reg_or_call_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 formal
-     temporary.  This way the optimizers can determine that the user
-     variable is only modified if evaluation of the RHS does not throw.
-
-     Don't force a temp of a non-renamable type; the copy could be
-     arbitrarily expensive.  Instead we will generate a VDEF for
-     the assignment.  */
-
-  if (is_gimple_reg_type (TREE_TYPE (t))
-      && ((TREE_CODE (t) == CALL_EXPR && TREE_SIDE_EFFECTS (t))
-         || tree_could_throw_p (t)))
-    return false;
-
-  return is_gimple_formal_tmp_or_call_rhs (t);
+  return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
+         || TREE_CODE (t) == CALL_EXPR);
 }
 
 /* Return true if T is a valid memory RHS or a CALL_EXPR.  Note that
@@ -655,28 +626,18 @@ is_gimple_reg_or_call_rhs (tree t)
    rationale for this in gimplify_modify_expr.  */
 
 static bool
-is_gimple_mem_or_call_rhs (tree t)
+is_gimple_mem_rhs_or_call (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_formal_tmp_or_call_rhs (t);
+    return (is_gimple_val (t) || is_gimple_lvalue (t)
+           || TREE_CODE (t) == CALL_EXPR);
 }
 
-
-/* Returns a formal temporary variable initialized with VAL.  PRE_P is as
-   in gimplify_expr.  Only use this function if:
-
-   1) The value of the unfactored expression represented by VAL will not
-      change between the initialization and use of the temporary, and
-   2) The temporary will not be otherwise modified.
-
-   For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
-   and #2 means it is inappropriate for && temps.
-
-   For other cases, use get_initialized_tmp_var instead.  */
+/* Helper for get_formal_tmp_var and get_initialized_tmp_var.  */
 
 static tree
 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
@@ -686,7 +647,7 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
 
   /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
      can create an INIT_EXPR and convert it into a GIMPLE_CALL below.  */
-  gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_or_call_rhs,
+  gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
                 fb_rvalue);
 
   t = lookup_tmp_var (val, is_formal);
@@ -707,11 +668,11 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
              SET_DECL_RESTRICT_BASE (t, u);
            }
        }
-    }
 
-  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
-      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
-    DECL_GIMPLE_REG_P (t) = 1;
+      if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+         || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+       DECL_GIMPLE_REG_P (t) = 1;
+    }
 
   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
 
@@ -735,9 +696,17 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
   return t;
 }
 
-/* Returns a formal temporary variable initialized with VAL.  PRE_P
-   points to a sequence where side-effects needed to compute VAL should be
-   stored.  */
+/* Returns a formal temporary variable initialized with VAL.  PRE_P is as
+   in gimplify_expr.  Only use this function if:
+
+   1) The value of the unfactored expression represented by VAL will not
+      change between the initialization and use of the temporary, and
+   2) The temporary will not be otherwise modified.
+
+   For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
+   and #2 means it is inappropriate for && temps.
+
+   For other cases, use get_initialized_tmp_var instead.  */
 
 tree
 get_formal_tmp_var (tree val, gimple_seq *pre_p)
@@ -2006,7 +1975,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                {
                  TREE_OPERAND (t, 2) = low;
                  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
-                                       post_p, is_gimple_formal_tmp_reg,
+                                       post_p, is_gimple_reg,
                                        fb_rvalue);
                  ret = MIN (ret, tret);
                }
@@ -2026,7 +1995,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                {
                  TREE_OPERAND (t, 3) = elmt_size;
                  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
-                                       post_p, is_gimple_formal_tmp_reg,
+                                       post_p, is_gimple_reg,
                                        fb_rvalue);
                  ret = MIN (ret, tret);
                }
@@ -2049,7 +2018,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                {
                  TREE_OPERAND (t, 2) = offset;
                  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
-                                       post_p, is_gimple_formal_tmp_reg,
+                                       post_p, is_gimple_reg,
                                        fb_rvalue);
                  ret = MIN (ret, tret);
                }
@@ -2072,19 +2041,11 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 
       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
        {
-         /* Gimplify the dimension.
-            Temporary fix for gcc.c-torture/execute/20040313-1.c.
-            Gimplify non-constant array indices into a temporary
-            variable.
-            FIXME - The real fix is to gimplify post-modify
-            expressions into a minimal gimple lvalue.  However, that
-            exposes bugs in alias analysis.  The alias analyzer does
-            not handle &PTR->FIELD very well.  Will fix after the
-            branch is merged into mainline (dnovillo 2004-05-03).  */
+         /* Gimplify the dimension.  */
          if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
            {
              tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
-                                   is_gimple_formal_tmp_reg, fb_rvalue);
+                                   is_gimple_val, fb_rvalue);
              ret = MIN (ret, tret);
            }
        }
@@ -2176,9 +2137,18 @@ gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   rhs = TREE_OPERAND (*expr_p, 1);
 
   /* For postfix operator, we evaluate the LHS to an rvalue and then use
-     that as the result value and in the postqueue operation.  */
+     that as the result value and in the postqueue operation.  We also
+     make sure to make lvalue a minimal lval, see
+     gcc.c-torture/execute/20040313-1.c for an example where this matters.  */
   if (postfix)
     {
+      if (!is_gimple_min_lval (lvalue))
+       {
+         mark_addressable (lvalue);
+         lvalue = build_fold_addr_expr (lvalue);
+         gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue);
+         lvalue = build_fold_indirect_ref (lvalue);
+       }
       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
       if (ret == GS_ERROR)
        return ret;
@@ -3448,12 +3418,10 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
 gimple_predicate
 rhs_predicate_for (tree lhs)
 {
-  if (is_gimple_formal_tmp_var (lhs))
-    return is_gimple_formal_tmp_or_call_rhs;
-  else if (is_gimple_reg (lhs))
-    return is_gimple_reg_or_call_rhs;
+  if (is_gimple_reg (lhs))
+    return is_gimple_reg_rhs_or_call;
   else
-    return is_gimple_mem_or_call_rhs;
+    return is_gimple_mem_rhs_or_call;
 }
 
 /* Gimplify a C99 compound literal expression.  This just means adding
@@ -4120,11 +4088,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
                     || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
              /* Don't force regs into memory.  */
              use_target = false;
-           else if (TREE_CODE (*to_p) == VAR_DECL
-                    && DECL_GIMPLE_FORMAL_TEMP_P (*to_p))
-             /* Don't use the original target if it's a formal temp; we
-                don't want to take their addresses.  */
-             use_target = false;
            else if (TREE_CODE (*expr_p) == INIT_EXPR)
              /* It's OK to use the target directly if it's being
                 initialized. */
@@ -4644,7 +4607,7 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
         This mostly happens if the frontend passed us something that
         it could not mark addressable yet, like a fortran
         pass-by-reference parameter (int) floatvar.  */
-      if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0)))
+      if (is_gimple_reg (TREE_OPERAND (expr, 0)))
        TREE_OPERAND (expr, 0)
          = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
 
@@ -6316,16 +6279,12 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   if (gimple_test_f == is_gimple_reg)
     gcc_assert (fallback & (fb_rvalue | fb_lvalue));
   else if (gimple_test_f == is_gimple_val
-           || gimple_test_f == is_gimple_formal_tmp_rhs
-           || gimple_test_f == is_gimple_formal_tmp_or_call_rhs
-           || gimple_test_f == is_gimple_formal_tmp_reg
-           || gimple_test_f == is_gimple_formal_tmp_var
            || gimple_test_f == is_gimple_call_addr
            || gimple_test_f == is_gimple_condexpr
            || gimple_test_f == is_gimple_mem_rhs
-           || gimple_test_f == is_gimple_mem_or_call_rhs
+           || gimple_test_f == is_gimple_mem_rhs_or_call
            || gimple_test_f == is_gimple_reg_rhs
-           || gimple_test_f == is_gimple_reg_or_call_rhs
+           || gimple_test_f == is_gimple_reg_rhs_or_call
            || gimple_test_f == is_gimple_asm_val)
     gcc_assert (fallback & fb_rvalue);
   else if (gimple_test_f == is_gimple_min_lval
@@ -7128,7 +7087,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *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_formal_tmp_or_call_rhs (*expr_p))
+  else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
     {
       /* An rvalue will do.  Assign the gimplified expression into a
         new temporary TMP and replace the original expression with
@@ -7143,9 +7102,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
        *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
       else
        *expr_p = get_formal_tmp_var (*expr_p, pre_p);
-
-      if (TREE_CODE (*expr_p) != SSA_NAME)
-       DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1;
     }
   else
     {
@@ -7597,7 +7553,7 @@ gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
       lhs = gimple_get_lhs (stmt);
       /* If the LHS changed it in a way that requires a simple RHS,
         create temporary.  */
-      if (lhs && !is_gimple_formal_tmp_var (lhs))
+      if (lhs && !is_gimple_reg (lhs))
        {
          bool need_temp = false;
 
@@ -7646,7 +7602,6 @@ gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
            {
              tree temp = create_tmp_var (TREE_TYPE (lhs), NULL);
 
-             DECL_GIMPLE_FORMAL_TEMP_P (temp) = 1;
              if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
                  || TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE)
                DECL_GIMPLE_REG_P (temp) = 1;
index a72a2f9470195d9cc40a7db21315d5e1e1f87ed1..62c76a77c4f3fce998c716e53503b6a5ab1d1cab 100644 (file)
@@ -1,3 +1,8 @@
+2009-03-31  Richard Guenther  <rguenther@suse.de>
+
+       * java-gimplify.c (java_gimplify_expr): Do not manually gimplify
+       the first operand of binary and comaprison expressions.
+
 2009-03-30  Joseph Myers  <joseph@codesourcery.com>
 
        PR rtl-optimization/323
index a43e67e5fec300fb86e102d95ba21bb75b04e889..e2ad02b697a12fbcba8869609eb9ece636ad882f 100644 (file)
@@ -96,26 +96,6 @@ java_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       gcc_unreachable ();
 
     default:
-      /* Java insists on strict left-to-right evaluation of expressions.
-        A problem may arise if a variable used in the LHS of a binary
-        operation is altered by an assignment to that value in the RHS
-        before we've performed the operation.  So, we always copy every
-        LHS to a temporary variable.  
-
-        FIXME: Are there any other cases where we should do this?
-        Parameter lists, maybe?  Or perhaps that's unnecessary because
-        the front end already generates SAVE_EXPRs.  */
-
-      if (TREE_CODE_CLASS (code) == tcc_binary
-         || TREE_CODE_CLASS (code) == tcc_comparison)
-       {
-         enum gimplify_status stat 
-           = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
-                            is_gimple_formal_tmp_var, fb_rvalue);
-         if (stat == GS_ERROR)
-           return stat;
-       }
-
       return GS_UNHANDLED;
     }
 
index aadb0da5e3398486d79af253890f66aaced0f1e2..c21f1074cfb62750a4c0f8b28b0ed4e0d4888708 100644 (file)
@@ -1,3 +1,10 @@
+2009-03-31  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/23401
+       PR middle-end/27810
+       * gcc.dg/tree-ssa/pr23401.c: New testcase.
+       * gcc.dg/tree-ssa/pr27810.c: Likewise.
+
 2009-03-30  Steven G. Kargl  <kargls@comcast.net>
 
        PR fortran/38389
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c
new file mode 100644 (file)
index 0000000..1d30ac7
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple" } */
+
+struct f
+{
+  struct {
+      int i;
+  } ff[10];
+};
+
+struct f g;
+int ffff(int i)
+{
+  int t1 = 0;
+  int i1 = g.ff[t1].i;
+  int i2 = g.ff[i].i;
+  return i1 + i2;
+}
+
+/* We should not use extra temporaries apart from for i1 + i2.  */
+
+/* { dg-final { scan-tree-dump-times "int" 5 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "int D\\\." 1 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c b/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c
new file mode 100644 (file)
index 0000000..c7da3bd
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple" } */
+
+int bar (int);
+
+int qqq (int a)
+{
+    int result;
+    result = bar (a);
+    return result;
+}
+
+/* We should not use an extra temporary for the result of the
+   function call.  */
+
+/* { dg-final { scan-tree-dump-times "int" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "int D\\\." 1 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
index 9c5b2e6c58ca8f15f4d7b313f4a8d738f89455b0..66f121836cb3e27b0d064670ae812369f112d2cd 100644 (file)
@@ -2886,6 +2886,11 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
            error ("address taken, but ADDRESSABLE bit not set");
            return x;
          }
+       if (DECL_GIMPLE_REG_P (x))
+         {
+           error ("DECL_GIMPLE_REG_P set on a variable with address taken");
+           return x;
+         }
 
        break;
       }
index f55a4172b10473173165fa320584e3dace3be0ec..1d9a9bdac3629856a70514536c95e9048bd08c1b 100644 (file)
@@ -1823,6 +1823,25 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
     {
     case GIMPLE_CALL:
     case GIMPLE_ASSIGN:
+      /* If the stmt can throw use a new temporary for the assignment
+         to a LHS.  This makes sure the old value of the LHS is
+        available on the EH edge.  */
+      if (stmt_could_throw_p (stmt)
+         && gimple_has_lhs (stmt)
+         && !tree_could_throw_p (gimple_get_lhs (stmt))
+         && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))))
+       {
+         tree lhs = gimple_get_lhs (stmt);
+         tree tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
+         gimple s = gimple_build_assign (lhs, tmp);
+         gimple_set_location (s, gimple_location (stmt));
+         gimple_set_block (s, gimple_block (stmt));
+         gimple_set_lhs (stmt, tmp);
+         if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
+             || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
+           DECL_GIMPLE_REG_P (tmp) = 1;
+         gsi_insert_after (gsi, s, GSI_SAME_STMT);
+       }
       /* Look for things that can throw exceptions, and record them.  */
       if (state->cur_region && stmt_could_throw_p (stmt))
        {
index 831fcc1791a83cf10ae67aba58354c926a1bbe0d..dae12874dad6c6fe951b0fa5768725f257856995 100644 (file)
@@ -503,7 +503,7 @@ mf_build_check_statement_for (tree base, tree limit,
   tree mf_elem;
   tree mf_limit;
   gimple g;
-  gimple_seq seq;
+  gimple_seq seq, stmts;
 
   /* We first need to split the current basic block, and start altering
      the CFG.  This allows us to insert the statements we're about to
@@ -553,14 +553,16 @@ mf_build_check_statement_for (tree base, tree limit,
   /* Build: __mf_base = (uintptr_t) <base address expression>.  */
   seq = gimple_seq_alloc ();
   t = fold_convert (mf_uintptr_type, unshare_expr (base));
-  gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
+  t = force_gimple_operand (t, &stmts, false, NULL_TREE);
+  gimple_seq_add_seq (&seq, stmts);
   g = gimple_build_assign (mf_base, t);
   gimple_set_location (g, location);
   gimple_seq_add_stmt (&seq, g);
 
   /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
   t = fold_convert (mf_uintptr_type, unshare_expr (limit));
-  gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
+  t = force_gimple_operand (t, &stmts, false, NULL_TREE);
+  gimple_seq_add_seq (&seq, stmts);
   g = gimple_build_assign (mf_limit, t);
   gimple_set_location (g, location);
   gimple_seq_add_stmt (&seq, g);
@@ -577,7 +579,8 @@ mf_build_check_statement_for (tree base, tree limit,
               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
               mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
   t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
-  gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
+  t = force_gimple_operand (t, &stmts, false, NULL_TREE);
+  gimple_seq_add_seq (&seq, stmts);
   g = gimple_build_assign (mf_elem, t);
   gimple_set_location (g, location);
   gimple_seq_add_stmt (&seq, g);
@@ -622,7 +625,8 @@ mf_build_check_statement_for (tree base, tree limit,
      result of the evaluation of 't' in a temporary variable which we
      can use as the condition for the conditional jump.  */
   t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
-  gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
+  t = force_gimple_operand (t, &stmts, false, NULL_TREE);
+  gimple_seq_add_seq (&seq, stmts);
   cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
   g = gimple_build_assign  (cond, t);
   gimple_set_location (g, location);
@@ -663,7 +667,8 @@ mf_build_check_statement_for (tree base, tree limit,
   v = fold_build2 (PLUS_EXPR, integer_type_node,
                   fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
                   integer_one_node);
-  gimplify_expr (&v, &seq, &seq, is_gimple_mem_rhs, fb_rvalue);
+  v = force_gimple_operand (v, &stmts, true, NULL_TREE);
+  gimple_seq_add_seq (&seq, stmts);
   g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
   gimple_seq_add_stmt (&seq, g);
 
index 9d06a8a3f297b7523dcc5a9ad517881a1564426a..267c2fcfea22cabaf15ed24cf7257bd726ccb04e 100644 (file)
@@ -1051,7 +1051,9 @@ get_or_alloc_expr_for (tree t)
 {
   if (TREE_CODE (t) == SSA_NAME)
     return get_or_alloc_expr_for_name (t);
-  else if (is_gimple_min_invariant (t))
+  else if (is_gimple_min_invariant (t)
+          || TREE_CODE (t) == EXC_PTR_EXPR
+          || TREE_CODE (t) == FILTER_EXPR)
     return get_or_alloc_expr_for_constant (t);
   else
     {
index 830852de8b561b0f408ddd490d782dfaa3e2b427..1a83c2505da5bda7b70c6ed35307a4f381180d88 100644 (file)
@@ -2928,11 +2928,6 @@ struct tree_parm_decl GTY(())
   /* Used to indicate that this DECL has weak linkage.  */
 #define DECL_WEAK(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.weak_flag)
 
-/* Internal to the gimplifier.  Indicates that the value is a formal
-   temporary controlled by the gimplifier.  */
-#define DECL_GIMPLE_FORMAL_TEMP_P(DECL) \
-  DECL_WITH_VIS_CHECK (DECL)->decl_with_vis.gimple_formal_temp
-
 /* Used to indicate that the DECL is a dllimport.  */
 #define DECL_DLLIMPORT_P(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.dllimport_flag)
 
@@ -3044,7 +3039,6 @@ struct tree_decl_with_vis GTY(())
  unsigned thread_local:1;
  unsigned common_flag:1;
  unsigned in_text_section : 1;
- unsigned gimple_formal_temp : 1;
  unsigned dllimport_flag : 1;
  unsigned based_on_restrict_p : 1;
  /* Used by C++.  Might become a generic decl flag.  */
@@ -3062,7 +3056,7 @@ struct tree_decl_with_vis GTY(())
 
  /* Belongs to VAR_DECL exclusively.  */
  ENUM_BITFIELD(tls_model) tls_model : 3;
- /* 12 unused bits. */
+ /* 13 unused bits. */
 };
 
 /* In a VAR_DECL that's static,
This page took 0.112727 seconds and 5 git commands to generate.