This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]