This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][tuples] Make acats ICE-clean
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at google dot com>
- Date: Tue, 22 Jul 2008 16:50:43 +0200 (CEST)
- Subject: Re: [PATCH][tuples] Make acats ICE-clean
- References: <alpine.LNX.1.10.0807221442300.4328@zhemvz.fhfr.qr>
On Tue, 22 Jul 2008, Richard Guenther wrote:
>
> This fixes all remaining ICEs in running the Ada acats testsuite.
>
> Some ICEs relate to using sub-types instead of base-types when folding
> operations, the fix is to always use gimple_expr_type instead of
> TREE_TYPE (gimple_get_lhs (stmt)).
>
> The second kind of ICE happens when we try to map TREE_BLOCK during
> inlining a function multiple times into the same function. While
> I may have missed a latent bug here it doesn't make sense to try to
> set TREE_BLOCK on a gimple stmts operands -- instead we can assert
> that we never get a set TREE_BLOCK here.
>
> In theory we should be able to remove the tree->exp.block field,
> but we still currently need it during expansion where we go back
> from tuple statements to tree statements :(
>
> Bootstrap and regtest running, I'll commit this if it succeeds.
This is what I ended up applying. The stage1 Ada testsuite is now
clean of ICEs.
Richard.
2008-07-22 Richard Guenther <rguenther@suse.de>
* tree-ssa-ccp.c (ccp_fold): Use gimple_expr_type.
(fold_gimple_assign): Likewise.
* tree-inline.c (remap_gimple_op_r): Do not set TREE_BLOCK on
non-statements. Recurse to copy_tree_body_r with NULL block.
(copy_phis_for_bb): Likewise.
* tree-cfg.c (move_stmt_op): Do not set TREE_BLOCK on
non-statements.
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c (revision 138048)
--- gcc/tree-ssa-ccp.c (working copy)
*************** ccp_fold (gimple stmt)
*** 994,1006 ****
TREE_TYPE (op0))))
return op0;
! return fold_unary (subcode, TREE_TYPE (lhs), op0);
}
case GIMPLE_BINARY_RHS:
{
/* Handle binary operators that can appear in GIMPLE form. */
- tree lhs = gimple_assign_lhs (stmt);
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
--- 994,1005 ----
TREE_TYPE (op0))))
return op0;
! return fold_unary (subcode, gimple_expr_type (stmt), op0);
}
case GIMPLE_BINARY_RHS:
{
/* Handle binary operators that can appear in GIMPLE form. */
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
*************** ccp_fold (gimple stmt)
*** 1019,1025 ****
op1 = val->value;
}
! return fold_binary (subcode, TREE_TYPE (lhs), op0, op1);
}
default:
--- 1018,1024 ----
op1 = val->value;
}
! return fold_binary (subcode, gimple_expr_type (stmt), op0, op1);
}
default:
*************** fold_gimple_assign (gimple_stmt_iterator
*** 2669,2675 ****
case GIMPLE_UNARY_RHS:
result = fold_unary (subcode,
! TREE_TYPE (gimple_assign_lhs (stmt)),
gimple_assign_rhs1 (stmt));
if (result)
--- 2668,2674 ----
case GIMPLE_UNARY_RHS:
result = fold_unary (subcode,
! gimple_expr_type (stmt),
gimple_assign_rhs1 (stmt));
if (result)
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c (revision 138048)
--- gcc/tree-cfg.c (working copy)
*************** move_stmt_op (tree *tp, int *walk_subtre
*** 5255,5275 ****
tree t = *tp;
if (EXPR_P (t))
! {
! tree block = TREE_BLOCK (t);
! if (p->orig_block == NULL_TREE
! || block == p->orig_block
! || block == NULL_TREE)
! TREE_BLOCK (t) = p->new_block;
! #ifdef ENABLE_CHECKING
! else if (block != p->new_block)
! {
! while (block && block != p->orig_block)
! block = BLOCK_SUPERCONTEXT (block);
! gcc_assert (block);
! }
! #endif
! }
else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
{
--- 5255,5262 ----
tree t = *tp;
if (EXPR_P (t))
! /* We should never have TREE_BLOCK set on non-statements. */
! gcc_assert (!TREE_BLOCK (t));
else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
{
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c (revision 138052)
--- gcc/tree-inline.c (working copy)
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 732,753 ****
&& id->remapping_type_depth == 0)
add_referenced_var (*tp);
! /* If EXPR has block defined, map it to newly constructed block.
! When inlining we want EXPRs without block appear in the block
! of function call. */
if (EXPR_P (*tp))
! {
! tree new_block = id->block;
! if (TREE_BLOCK (*tp))
! {
! tree *n;
! n = (tree *) pointer_map_contains (id->decl_map,
! TREE_BLOCK (*tp));
! gcc_assert (n);
! new_block = *n;
! }
! TREE_BLOCK (*tp) = new_block;
! }
if (TREE_CODE (*tp) != OMP_CLAUSE)
TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
--- 732,740 ----
&& id->remapping_type_depth == 0)
add_referenced_var (*tp);
! /* We should never have TREE_BLOCK set on non-statements. */
if (EXPR_P (*tp))
! gcc_assert (!TREE_BLOCK (*tp));
if (TREE_CODE (*tp) != OMP_CLAUSE)
TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 763,771 ****
{
/* Variable substitution need not be simple. In particular,
the INDIRECT_REF substitution above. Make sure that
! TREE_CONSTANT and friends are up-to-date. */
int invariant = is_gimple_min_invariant (*tp);
walk_tree (&TREE_OPERAND (*tp, 0), copy_tree_body_r, id, NULL);
/* Handle the case where we substituted an INDIRECT_REF
into the operand of the ADDR_EXPR. */
--- 750,762 ----
{
/* Variable substitution need not be simple. In particular,
the INDIRECT_REF substitution above. Make sure that
! TREE_CONSTANT and friends are up-to-date. But make sure
! to not improperly set TREE_BLOCK on some sub-expressions. */
int invariant = is_gimple_min_invariant (*tp);
+ tree block = id->block;
+ id->block = NULL_TREE;
walk_tree (&TREE_OPERAND (*tp, 0), copy_tree_body_r, id, NULL);
+ id->block = block;
/* Handle the case where we substituted an INDIRECT_REF
into the operand of the ADDR_EXPR. */
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 1665,1672 ****
= find_edge ((basic_block) new_edge->src->aux, bb);
tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
tree new_arg = arg;
!
walk_tree (&new_arg, copy_tree_body_r, id, NULL);
gcc_assert (new_arg);
/* With return slot optimization we can end up with
non-gimple (foo *)&this->m, fix that here. */
--- 1656,1665 ----
= find_edge ((basic_block) new_edge->src->aux, bb);
tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
tree new_arg = arg;
! tree block = id->block;
! id->block = NULL_TREE;
walk_tree (&new_arg, copy_tree_body_r, id, NULL);
+ id->block = block;
gcc_assert (new_arg);
/* With return slot optimization we can end up with
non-gimple (foo *)&this->m, fix that here. */