Commit 0c322af3 by Jason Merrill Committed by Jason Merrill

tree-gimple.c (is_gimple_reg_rhs, [...]): New fns.

        * 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
parent 3ac5ea7c
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> 2004-07-14 Richard Henderson <rth@redhat.com>
* config/arm/arm-protos.h (arm_va_arg): Remove. * config/arm/arm-protos.h (arm_va_arg): Remove.
......
...@@ -446,7 +446,7 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal) ...@@ -446,7 +446,7 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
tree t, mod; tree t, mod;
char class; 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); t = lookup_tmp_var (val, is_formal);
...@@ -2610,7 +2610,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -2610,7 +2610,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
ctor = build (COMPLEX_EXPR, type, r, i); ctor = build (COMPLEX_EXPR, type, r, i);
TREE_OPERAND (*expr_p, 1) = ctor; TREE_OPERAND (*expr_p, 1) = ctor;
ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
is_gimple_rhs, fb_rvalue); is_gimple_tmp_rhs, fb_rvalue);
} }
} }
break; break;
...@@ -2780,7 +2780,8 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value) ...@@ -2780,7 +2780,8 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
if (ret == GS_ERROR) if (ret == GS_ERROR)
return ret; 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) if (ret == GS_ERROR)
return ret; return ret;
...@@ -2791,33 +2792,10 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value) ...@@ -2791,33 +2792,10 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
return ret; return ret;
/* If the destination is already simple, nothing else needed. */ /* 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; ret = GS_ALL_DONE;
else else
{ ret = GS_OK;
/* 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;
}
if (want_value) if (want_value)
{ {
...@@ -3975,7 +3953,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, ...@@ -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); gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
*expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp); *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 defined ENABLE_CHECKING
if (VOID_TYPE_P (TREE_TYPE (*expr_p))) if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
......
...@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */
#include "tm.h" #include "tm.h"
#include "tree.h" #include "tree.h"
#include "tree-gimple.h" #include "tree-gimple.h"
#include "tree-flow.h"
#include "output.h" #include "output.h"
#include "rtl.h" #include "rtl.h"
#include "expr.h" #include "expr.h"
...@@ -172,10 +173,10 @@ static inline bool is_gimple_id (tree); ...@@ -172,10 +173,10 @@ static inline bool is_gimple_id (tree);
/* Validation of GIMPLE expressions. */ /* 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 bool
is_gimple_rhs (tree t) is_gimple_tmp_rhs (tree t)
{ {
enum tree_code code = TREE_CODE (t); enum tree_code code = TREE_CODE (t);
...@@ -217,6 +218,57 @@ is_gimple_rhs (tree t) ...@@ -217,6 +218,57 @@ is_gimple_rhs (tree t)
return is_gimple_lvalue (t) || is_gimple_val (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 /* Returns true if T is a valid CONSTRUCTOR component in GIMPLE, either
a val or another CONSTRUCTOR. */ a val or another CONSTRUCTOR. */
......
...@@ -39,6 +39,8 @@ extern void annotate_all_with_locus (tree *, location_t); ...@@ -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 the basic form of the expression, they don't recurse to make sure that
underlying nodes are also of the right form. */ underlying nodes are also of the right form. */
typedef bool (*gimple_predicate)(tree);
/* Returns true iff T is a valid GIMPLE statement. */ /* Returns true iff T is a valid GIMPLE statement. */
extern bool is_gimple_stmt (tree); extern bool is_gimple_stmt (tree);
...@@ -59,8 +61,15 @@ extern bool is_gimple_lvalue (tree); ...@@ -59,8 +61,15 @@ extern bool is_gimple_lvalue (tree);
extern bool is_gimple_min_invariant (tree); extern bool is_gimple_min_invariant (tree);
/* Returns true iff T is a GIMPLE rvalue. */ /* Returns true iff T is a GIMPLE rvalue. */
extern bool is_gimple_val (tree); extern bool is_gimple_val (tree);
/* Returns true iff T is a valid rhs for a MODIFY_EXPR. */ /* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
extern bool is_gimple_rhs (tree); 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. */ /* Returns true iff T is a valid if-statement condition. */
extern bool is_gimple_condexpr (tree); extern bool is_gimple_condexpr (tree);
......
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