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>
* 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)
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)))
......
......@@ -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. */
......
......@@ -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);
......
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