tree.h (struct tree_decl): Add gimple_formal_temp.

* tree.h (struct tree_decl): Add gimple_formal_temp.
        (DECL_GIMPLE_FORMAL_TEMP_P): New.
        * gimplify.c (pop_gimplify_context): Clear it.
        (lookup_tmp_var): Set it, if is_formal.
        (gimplify_init_constructor): Use rhs_predicate_for for COMPLEX.
        Use is_gimple_val for VECTOR.  Simplify return value.
        (gimplify_save_expr): Use and set DECL_GIMPLE_FORMAL_TEMP_P.
        (gimplify_expr): Likewise.
        * tree-gimple.c (is_gimple_formal_tmp_rhs): Rename from
        is_gimple_tmp_rhs for clarity.  Update all callers.
        (is_gimple_reg_rhs): Simplify logic.
        (is_gimple_formal_tmp_var): Rename from is_gimple_tmp_var for
        clarity; use DECL_GIMPLE_FORMAL_TEMP_P.
        (is_gimple_formal_tmp_reg): Similarly.
        * tree-gimple.h: Update decls.
        * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Use
        DECL_IGNORED_P, not DECL_ARTIFICIAL.  Tidy formatting.
        * tree-ssa-live.c (var_union, type_var_init): Likewise.
java/
        * java-gimplify.c (java_gimplify_expr): Move '2' handling into
        default case.  Treat '<' similarly.  Update for
        is_gimple_formal_tmp_var name change.
testsuite/
        * gcc.dg/20040206-1.c: XFAIL.

From-SVN: r86176
This commit is contained in:
Richard Henderson 2004-08-18 00:46:33 -07:00 committed by Richard Henderson
parent 5b0eba617b
commit 17ad5b5ec2
11 changed files with 148 additions and 107 deletions

View File

@ -1,3 +1,24 @@
2004-08-18 Richard Henderson <rth@redhat.com>
* tree.h (struct tree_decl): Add gimple_formal_temp.
(DECL_GIMPLE_FORMAL_TEMP_P): New.
* gimplify.c (pop_gimplify_context): Clear it.
(lookup_tmp_var): Set it, if is_formal.
(gimplify_init_constructor): Use rhs_predicate_for for COMPLEX.
Use is_gimple_val for VECTOR. Simplify return value.
(gimplify_save_expr): Use and set DECL_GIMPLE_FORMAL_TEMP_P.
(gimplify_expr): Likewise.
* tree-gimple.c (is_gimple_formal_tmp_rhs): Rename from
is_gimple_tmp_rhs for clarity. Update all callers.
(is_gimple_reg_rhs): Simplify logic.
(is_gimple_formal_tmp_var): Rename from is_gimple_tmp_var for
clarity; use DECL_GIMPLE_FORMAL_TEMP_P.
(is_gimple_formal_tmp_reg): Similarly.
* tree-gimple.h: Update decls.
* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Use
DECL_IGNORED_P, not DECL_ARTIFICIAL. Tidy formatting.
* tree-ssa-live.c (var_union, type_var_init): Likewise.
2004-08-18 Paolo Bonzini <bonzini@gnu.org>
* c4x.c (legitimize_operands): Remove calls to

View File

@ -128,9 +128,14 @@ push_gimplify_context (void)
void
pop_gimplify_context (tree body)
{
tree t;
if (!gimplify_ctxp || gimplify_ctxp->current_bind_expr)
abort ();
for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
if (body)
declare_tmp_vars (gimplify_ctxp->temps, body);
else
@ -402,8 +407,10 @@ create_tmp_from_val (tree val)
static tree
lookup_tmp_var (tree val, bool is_formal)
{
tree ret;
if (!is_formal || TREE_SIDE_EFFECTS (val))
return create_tmp_from_val (val);
ret = create_tmp_from_val (val);
else
{
elt_t elt, *elt_p;
@ -415,17 +422,22 @@ lookup_tmp_var (tree val, bool is_formal)
{
elt_p = xmalloc (sizeof (*elt_p));
elt_p->val = val;
elt_p->temp = create_tmp_from_val (val);
TREE_READONLY (elt_p->temp) = 1;
elt_p->temp = ret = create_tmp_from_val (val);
*slot = (void *) elt_p;
}
else
{
elt_p = (elt_t *) *slot;
return elt_p->temp;
ret = elt_p->temp;
}
}
if (is_formal)
DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1;
return ret;
}
/* Returns a formal temporary variable initialized with VAL. PRE_P is as
in gimplify_expr. Only use this function if:
@ -444,7 +456,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_tmp_rhs, fb_rvalue);
gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue);
t = lookup_tmp_var (val, is_formal);
@ -1571,7 +1583,7 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
{
TREE_OPERAND (t, 2) = low;
tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
is_gimple_tmp_reg, fb_rvalue);
is_gimple_formal_tmp_reg, fb_rvalue);
ret = MIN (ret, tret);
}
}
@ -1590,7 +1602,7 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
{
TREE_OPERAND (t, 3) = elmt_size;
tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
is_gimple_tmp_reg, fb_rvalue);
is_gimple_formal_tmp_reg, fb_rvalue);
ret = MIN (ret, tret);
}
}
@ -1612,7 +1624,7 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
{
TREE_OPERAND (t, 2) = offset;
tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
is_gimple_tmp_reg, fb_rvalue);
is_gimple_formal_tmp_reg, fb_rvalue);
ret = MIN (ret, tret);
}
}
@ -1643,7 +1655,7 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
{
tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
is_gimple_tmp_reg, fb_rvalue);
is_gimple_formal_tmp_reg, fb_rvalue);
ret = MIN (ret, tret);
}
}
@ -2744,7 +2756,8 @@ 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_tmp_rhs, fb_rvalue);
rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
fb_rvalue);
}
}
break;
@ -2761,7 +2774,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
{
enum gimplify_status tret;
tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p,
is_gimple_constructor_elt, fb_rvalue);
is_gimple_val, fb_rvalue);
if (tret == GS_ERROR)
ret = GS_ERROR;
}
@ -2932,19 +2945,14 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
}
}
/* If the destination is already simple, nothing else needed. */
if (is_gimple_tmp_var (*to_p) || !want_value)
ret = GS_ALL_DONE;
else
ret = GS_OK;
if (want_value)
{
append_to_statement_list (*expr_p, pre_p);
*expr_p = *to_p;
return GS_OK;
}
return ret;
return GS_ALL_DONE;
}
/* Gimplify a comparison between two variable-sized objects. Do this
@ -3090,7 +3098,7 @@ gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
/* If the operand is already a GIMPLE temporary, just re-write the
SAVE_EXPR node. */
if (is_gimple_tmp_var (val))
if (TREE_CODE (val) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (val))
*expr_p = val;
/* The operand may be a void-valued expression such as SAVE_EXPRs
generated by the Java frontend for class initialization. It is
@ -3103,8 +3111,11 @@ gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
*expr_p = NULL;
}
else
*expr_p = TREE_OPERAND (*expr_p, 0)
= get_initialized_tmp_var (val, pre_p, post_p);
{
val = get_initialized_tmp_var (val, pre_p, post_p);
DECL_GIMPLE_FORMAL_TEMP_P (val) = 1;
*expr_p = TREE_OPERAND (*expr_p, 0) = val;
}
return ret;
}
@ -4095,7 +4106,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_tmp_rhs (*expr_p))
else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p))
{
#if defined ENABLE_CHECKING
if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
@ -4112,6 +4123,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *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);
DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1;
}
else if (fallback & fb_mayfail)
{

View File

@ -1,3 +1,9 @@
2004-08-18 Richard Henderson <rth@redhat.com>
* java-gimplify.c (java_gimplify_expr): Move '2' handling into
default case. Treat '<' similarly. Update for
is_gimple_formal_tmp_var name change.
2004-08-17 Andrew Haley <aph@redhat.com>
* lang.c (lang_printable_name): Obey verbose flag.

View File

@ -60,28 +60,9 @@ int
java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
tree *post_p ATTRIBUTE_UNUSED)
{
char code_class = TREE_CODE_CLASS(TREE_CODE (*expr_p));
enum tree_code code = TREE_CODE (*expr_p);
/* 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 (code_class == '2')
{
tree lhs = TREE_OPERAND (*expr_p, 0);
enum gimplify_status stat
= gimplify_expr (&lhs, pre_p, post_p, is_gimple_tmp_var, fb_rvalue);
if (stat == GS_ERROR)
return stat;
TREE_OPERAND (*expr_p, 0) = lhs;
}
switch (TREE_CODE (*expr_p))
switch (code)
{
case BLOCK:
*expr_p = java_gimplify_block (*expr_p);
@ -150,6 +131,25 @@ java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
abort ();
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) == '2' || TREE_CODE_CLASS (code) == '<')
{
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;
}

View File

@ -1,3 +1,7 @@
2004-08-18 Richard Henderson <rth@redhat.com>
* gcc.dg/20040206-1.c: XFAIL.
2004-08-17 Mark Mitchell <mark@codesourcery.com>
PR c++/16246

View File

@ -8,4 +8,4 @@
returning non-void" is PR 13000. */
static int foo (int a __attribute__((unused)) ) { } /* { dg-warning "return" "" { xfail *-*-* } } */
int main (void) { return foo (0); }
int main (void) { return foo (0); } /* { dg-bogus "uninitialized" "" { xfail *-*-* } } */

View File

@ -195,7 +195,7 @@ static inline bool is_gimple_id (tree);
/* Return true if T is a GIMPLE RHS for an assignment to a temporary. */
bool
is_gimple_tmp_rhs (tree t)
is_gimple_formal_tmp_rhs (tree t)
{
enum tree_code code = TREE_CODE (t);
@ -235,28 +235,27 @@ is_gimple_tmp_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. */
/* 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 temporary.
ie temp = RHS; LHS = temp.
/* 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.
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
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);
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_rhs (t);
}
/* Returns true iff T is a valid RHS for an assignment to an un-renamed
@ -270,7 +269,7 @@ is_gimple_mem_rhs (tree t)
if (is_gimple_reg_type (TREE_TYPE (t)))
return is_gimple_val (t);
else
return is_gimple_tmp_rhs (t);
return is_gimple_formal_tmp_rhs (t);
}
/* Returns the appropriate RHS predicate for this LHS. */
@ -278,8 +277,8 @@ is_gimple_mem_rhs (tree t)
gimple_predicate
rhs_predicate_for (tree lhs)
{
if (is_gimple_tmp_var (lhs))
return is_gimple_tmp_rhs;
if (is_gimple_formal_tmp_var (lhs))
return is_gimple_formal_tmp_rhs;
else if (is_gimple_reg (lhs))
return is_gimple_reg_rhs;
else
@ -444,20 +443,18 @@ is_gimple_reg (tree t)
&& ! needs_to_live_in_memory (t));
}
/* Returns true if T is a GIMPLE temporary variable, false otherwise. */
/* Returns true if T is a GIMPLE formal temporary variable. */
bool
is_gimple_tmp_var (tree t)
is_gimple_formal_tmp_var (tree t)
{
/* FIXME this could trigger for other local artificials, too. */
return (TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t)
&& !TREE_STATIC (t) && !DECL_EXTERNAL (t));
return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
}
/* Returns true if T is a GIMPLE temporary register variable. */
/* Returns true if T is a GIMPLE formal temporary register variable. */
bool
is_gimple_tmp_reg (tree t)
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. */
@ -465,7 +462,7 @@ is_gimple_tmp_reg (tree t)
return true;
/* We don't know the lifetime characteristics of user variables. */
if (TREE_CODE (t) != VAR_DECL || !DECL_ARTIFICIAL (t))
if (!is_gimple_formal_tmp_var (t))
return false;
/* Finally, it must be capable of being placed in a register. */

View File

@ -48,9 +48,9 @@ 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_tmp_var (tree);
extern bool is_gimple_formal_tmp_var (tree);
/* Returns true if T is a GIMPLE temporary register variable. */
extern bool is_gimple_tmp_reg (tree);
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 a variable or an INDIRECT_REF (of a variable). */
@ -67,7 +67,7 @@ extern bool is_gimple_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_tmp_rhs (tree);
extern bool is_gimple_formal_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

View File

@ -118,7 +118,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
int p1, p2, p3;
tree root1, root2;
var_ann_t ann1, ann2, ann3;
bool gimp1, gimp2;
bool ign1, ign2;
#ifdef ENABLE_CHECKING
if (TREE_CODE (var1) != SSA_NAME || TREE_CODE (var2) != SSA_NAME)
@ -195,18 +195,17 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
return;
}
gimp1 = (TREE_CODE (root1) == VAR_DECL && DECL_ARTIFICIAL (root1));
gimp2 = (TREE_CODE (root2) == VAR_DECL && DECL_ARTIFICIAL (root2));
ign1 = TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1);
ign2 = TREE_CODE (root2) == VAR_DECL && DECL_IGNORED_P (root2);
/* Never attempt to coalesce 2 user variables unless one is an inline
variable. */
if (!gimp1 && !gimp2)
if (!ign1 && !ign2)
{
if (DECL_FROM_INLINE (root2))
gimp2 = true;
else
if (DECL_FROM_INLINE (root1))
gimp1 = true;
ign2 = true;
else if (DECL_FROM_INLINE (root1))
ign1 = true;
else
{
if (debug)
@ -215,7 +214,6 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
}
}
/* Don't coalesce if there are two different memory tags. */
if (ann1->type_mem_tag && ann2->type_mem_tag
&& ann1->type_mem_tag != ann2->type_mem_tag)
@ -237,15 +235,14 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
}
else
{
gimp2 = true;
gimp1 = false;
ign2 = true;
ign1 = false;
}
}
else
if (default_def (root2))
else if (default_def (root2))
{
gimp1 = true;
gimp2 = false;
ign1 = true;
ign2 = false;
}
/* Don't coalesce if the two variables aren't type compatible. */
@ -261,10 +258,9 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
/* Set the root variable of the partition to the better choice, if there is
one. */
if (!gimp2)
if (!ign2)
replace_ssa_name_symbol (partition_to_var (map, p3), root2);
else
if (!gimp1)
else if (!ign1)
replace_ssa_name_symbol (partition_to_var (map, p3), root1);
/* Update the various flag widgitry of the current base representative. */

View File

@ -135,8 +135,7 @@ var_union (var_map map, tree var1, tree var2)
/* If there is no root_var set, or its not a user variable, set the
root_var to this one. */
if (!root_var
|| (TREE_CODE (root_var) == VAR_DECL && DECL_ARTIFICIAL (root_var)))
if (!root_var || (DECL_P (root_var) && DECL_IGNORED_P (root_var)))
{
other_var = root_var;
root_var = var2;
@ -1040,7 +1039,7 @@ type_var_init (var_map map)
|| TREE_CODE (t) == PARM_DECL
|| (DECL_P (t)
&& (DECL_REGISTER (t)
|| !DECL_ARTIFICIAL (t)
|| !DECL_IGNORED_P (t)
|| DECL_RTL_SET_P (t))))
continue;

View File

@ -2177,6 +2177,11 @@ struct tree_binfo GTY (())
#define DECL_PRESERVE_P(DECL) \
DECL_CHECK (DECL)->decl.preserve_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_CHECK (DECL)->decl.gimple_formal_temp
/* Enumerate visibility settings. */
#ifndef SYMBOL_VISIBILITY_DEFINED
#define SYMBOL_VISIBILITY_DEFINED
@ -2245,6 +2250,7 @@ struct tree_decl GTY(())
unsigned possibly_inlined : 1;
unsigned preserve_flag: 1;
unsigned gimple_formal_temp : 1;
/* 13 unused bits. */
union tree_decl_u1 {