This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Complete useless_type_conversion_p_1 some more (need Ada help)
On Tue, 4 Aug 2009, Eric Botcazou wrote:
> > During the array work I came along some oddities wrt the Ada frontend
> > and the stuff that is left in the types. For example if you remove
> > the hack
> >
> > + /* ??? Ada does weird things with type sizes and defers
> > gimplifying
> > + them. To not ICE during expansion for for example cdd2a01 we
> > + avoid stripping conversions from types whose size contains
> > + placeholder exprs. */
> > + if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (inner_type)))
> > + return false;
> >
> > then expansion fails for cdd2a01 (and some other testcases) because
> > we end up calling expr_size when expanding an aggregate assignment
> > from store_expr and that runs into a TYPE_SIZE with a call expression
> > and call arguments with placeholder expressions. The patch would
> > only remove conversions from one to another array type with variable
> > bounds (though I don't look at TYPE_SIZE - may that become constant
>
> Not sure what you call "weird". Sizes of self-referential types cannot be
> gimplified because they must first be instantiated on a given object:
>
> /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
> a size or position, has had all of its SAVE_EXPRs evaluated.
> We add any required statements to *STMT_P. */
>
> void
> gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
> {
> tree type, expr = *expr_p;
>
> /* We don't do anything if the value isn't there, is constant, or contains
> A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
> a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
> will want to replace it with a new variable, but that will cause problems
> if this type is from outside the function. It's OK to have that here.
> */
> if (expr == NULL_TREE || TREE_CONSTANT (expr)
> || TREE_CODE (expr) == VAR_DECL
> || CONTAINS_PLACEHOLDER_P (expr))
> return;
>
> This would be true for any language supporting self-referential types. All
> the instantiations must have been performed by the time gimplification is
> done so ICEing during expansion very likely means that an instantiation now
> fails during gimplification. So I'd indeed avoid messing as much as possible
> with self-referential types before and during gimplification.
>
> > Even with the above hack c41203b still fails at runtime with
> > * C41203A WRONG VALUE FOR IN PARAMETER - N5.
>
> I'll look into it.
I have it debugged and fixed - it was a bug in SCCVN:
I'm testing the following ontop of the patch.
Richard.
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c (revision 150368)
+++ gcc/tree-ssa-sccvn.c (working copy)
@@ -561,18 +561,9 @@ copy_reference_ops_from_ref (tree ref, V
case ARRAY_REF:
/* Record index as operand. */
temp.op0 = TREE_OPERAND (ref, 1);
- /* Record even constant lower bounds. */
- if (TREE_OPERAND (ref, 2))
- temp.op1 = TREE_OPERAND (ref, 2);
- else
- {
- tree domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
- if (domain
- && TYPE_MIN_VALUE (domain)
- && !integer_zerop (TYPE_MIN_VALUE (domain)))
- temp.op1 = TYPE_MIN_VALUE (domain);
- }
- temp.op2 = TREE_OPERAND (ref, 3);
+ /* Always record lower bounds and element size. */
+ temp.op1 = array_ref_low_bound (ref);
+ temp.op2 = array_ref_element_size (ref);
break;
case STRING_CST:
case INTEGER_CST:
@@ -731,19 +722,17 @@ ao_ref_init_from_vn_reference (ao_ref *r
case ARRAY_RANGE_REF:
case ARRAY_REF:
- /* Same for ARRAY_REFs. We do not have access to the array
- type here, but we recorded the lower bound in op1. */
- if (op->op2
- || !host_integerp (op->op0, 0)
- || (op->op1 && !host_integerp (op->op1, 0))
- || !host_integerp (TYPE_SIZE (op->type), 1))
+ /* We recorded the lower bound and the element size. */
+ if (!host_integerp (op->op0, 0)
+ || !host_integerp (op->op1, 0)
+ || !host_integerp (op->op2, 0))
max_size = -1;
else
{
HOST_WIDE_INT hindex = TREE_INT_CST_LOW (op->op0);
- if (op->op1)
- hindex -= TREE_INT_CST_LOW (op->op1);
- hindex *= TREE_INT_CST_LOW (TYPE_SIZE (op->type));
+ hindex -= TREE_INT_CST_LOW (op->op1);
+ hindex *= TREE_INT_CST_LOW (op->op2);
+ hindex *= BITS_PER_UNIT;
offset += hindex;
}
break;