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: [tree-ssa] fix *(&a[1] + 8B)


> The reason for the tree-dfa change is that, as discussed elsewhere,
> this case doesn't work.  We don't create VDEFs for nested constructs
> when the INDIRECT_REF is on the lhs.  But rather than fix that, we
> decided that these cases were in fact illegal.
> 
> Removing that check produced one test suite regression that can show
> this kind of complex address construction: execute/20021120-1.c.
> 
> The extra code in maybe_fold_stmt_plus assures that we reduce
> 
> 	*(&a[1] + 4B)
> to
> 	a[2]
> 
> as we expected.  The change to use int_const_binop just means
> we don't create tree garbage when we don't have to.

Just curious, what happens to *(&a[1] + 3B)?
Thanks for working on this!
Honza
> 
> Bootstrapped and tested with no regressions on i686-linux.
> 
> 
> r~
> 
> 
>         * tree-dfa.c (get_expr_operands): Don't handle PLUS_EXPR inside
>         INDIRECT_REF.
>         * tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Use int_const_binop.
>         (maybe_fold_offset_to_component_ref): Likewise.
>         (maybe_fold_stmt_indirect): Likewise.
>         (maybe_fold_stmt_plus): Expand ARRAY_REF when seen with addend.
>         * fold-const.c (int_const_binop): Export.
>         * tree.h (int_const_binop): Declare.
> 
> Index: fold-const.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
> retrieving revision 1.213.2.64
> diff -u -p -r1.213.2.64 fold-const.c
> --- fold-const.c	24 Nov 2003 20:28:55 -0000	1.213.2.64
> +++ fold-const.c	2 Dec 2003 04:02:24 -0000
> @@ -65,7 +65,6 @@ static bool negate_expr_p (tree);
>  static tree negate_expr (tree);
>  static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
>  static tree associate_trees (tree, tree, enum tree_code, tree);
> -static tree int_const_binop (enum tree_code, tree, tree, int);
>  static tree const_binop (enum tree_code, tree, tree, int);
>  static hashval_t size_htab_hash (const void *);
>  static int size_htab_eq (const void *, const void *);
> @@ -1170,7 +1169,7 @@ associate_trees (tree t1, tree t2, enum 
>  
>     If NOTRUNC is nonzero, do not truncate the result to fit the data type.  */
>  
> -static tree
> +tree
>  int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
>  {
>    unsigned HOST_WIDE_INT int1l, int2l;
> Index: tree-dfa.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
> retrieving revision 1.1.4.190
> diff -u -p -r1.1.4.190 tree-dfa.c
> --- tree-dfa.c	28 Nov 2003 21:26:38 -0000	1.1.4.190
> +++ tree-dfa.c	2 Dec 2003 04:02:27 -0000
> @@ -394,19 +394,6 @@ get_expr_operands (tree stmt, tree *expr
>  	  return;
>  	}
>  
> -      /* This single case might not have been folded to an array reference
> -	 if the immediate doesn't exactly divide the referenced type.  This
> -	 case is likely to be undefined in C, but perhaps not others.  */
> -      else if (TREE_CODE (ptr) == PLUS_EXPR)
> -	{
> -	  if (TREE_CODE (TREE_OPERAND (ptr, 1)) != INTEGER_CST)
> -	    abort ();
> -	  ptr = TREE_OPERAND (ptr, 0);
> -	  if (TREE_CODE (ptr) != ADDR_EXPR)
> -	    abort ();
> -	  pptr = &TREE_OPERAND (ptr, 0);
> -	}
> -
>        /* Everything else should have been folded elsewhere.  */
>        else
>  	abort ();
> Index: tree-ssa-ccp.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
> retrieving revision 1.1.2.118
> diff -u -p -r1.1.2.118 tree-ssa-ccp.c
> --- tree-ssa-ccp.c	27 Nov 2003 21:36:13 -0000	1.1.2.118
> +++ tree-ssa-ccp.c	2 Dec 2003 04:02:28 -0000
> @@ -1531,8 +1531,7 @@ maybe_fold_offset_to_array_ref (tree bas
>  	{
>  	  idx = convert (TREE_TYPE (min_idx), idx);
>  	  if (!integer_zerop (min_idx))
> -	    idx = fold (build (PLUS_EXPR, TREE_TYPE (min_idx),
> -			idx, min_idx));
> +	    idx = int_const_binop (PLUS_EXPR, idx, min_idx, 1);
>  	}
>      }
>  
> @@ -1594,8 +1593,7 @@ maybe_fold_offset_to_component_ref (tree
>  	  if (!DECL_SIZE_UNIT (f)
>  	      || TREE_CODE (DECL_SIZE_UNIT (f)) != INTEGER_CST)
>  	    continue;
> -	  t = fold (build (MINUS_EXPR, TREE_TYPE (offset),
> -			   offset, DECL_FIELD_OFFSET (f)));
> +	  t = int_const_binop (MINUS_EXPR, offset, DECL_FIELD_OFFSET (f), 1);
>  	  if (!tree_int_cst_lt (t, DECL_SIZE_UNIT (f)))
>  	    continue;
>  
> @@ -1664,7 +1662,7 @@ maybe_fold_stmt_indirect (tree expr, tre
>  	return NULL_TREE;
>        base = TREE_OPERAND (base, 0);
>  
> -      offset = fold (build (PLUS_EXPR, TREE_TYPE (offset), offset, offset2));
> +      offset = int_const_binop (PLUS_EXPR, offset, offset2, 1);
>      }
>  
>    if (TREE_CODE (base) == ADDR_EXPR)
> @@ -1760,8 +1758,45 @@ maybe_fold_stmt_plus (tree expr)
>    /* The first operand should be an ADDR_EXPR.  */
>    if (TREE_CODE (op0) != ADDR_EXPR)
>      return NULL_TREE;
> -
>    op0 = TREE_OPERAND (op0, 0);
> +
> +  /* If the first operand is an ARRAY_REF, expand it so that we can fold
> +     the offset into it.  */
> +  while (TREE_CODE (op0) == ARRAY_REF)
> +    {
> +      tree array_obj = TREE_OPERAND (op0, 0);
> +      tree array_idx = TREE_OPERAND (op0, 1);
> +      tree elt_type = TREE_TYPE (op0);
> +      tree elt_size = TYPE_SIZE_UNIT (elt_type);
> +      tree min_idx;
> +
> +      if (TREE_CODE (array_idx) != INTEGER_CST)
> +	break;
> +      if (TREE_CODE (elt_size) != INTEGER_CST)
> +	break;
> +
> +      /* Un-bias the index by the min index of the array type.  */
> +      min_idx = TYPE_DOMAIN (TREE_TYPE (array_obj));
> +      if (min_idx)
> +	{
> +	  min_idx = TYPE_MIN_VALUE (min_idx);
> +	  if (min_idx)
> +	    {
> +	      array_idx = convert (TREE_TYPE (min_idx), array_idx);
> +	      if (!integer_zerop (min_idx))
> +		array_idx = int_const_binop (MINUS_EXPR, array_idx, min_idx, 0);
> +	    }
> +	}
> +
> +      /* Convert the index to a byte offset.  */
> +      array_idx = convert (sizetype, array_idx);
> +      array_idx = int_const_binop (MULT_EXPR, array_idx, elt_size, 0);
> +
> +      /* Update the operands for the next round, or for folding.  */
> +      op1 = int_const_binop (PLUS_EXPR, array_idx, op1, 0);
> +      op0 = array_obj;
> +    }
> +
>    ptd_type = TREE_TYPE (ptr_type);
>  
>    /* At which point we can try some of the same things as for indirects.  */
> Index: tree.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/tree.h,v
> retrieving revision 1.342.2.141
> diff -u -p -r1.342.2.141 tree.h
> --- tree.h	27 Nov 2003 04:01:03 -0000	1.342.2.141
> +++ tree.h	2 Dec 2003 04:02:32 -0000
> @@ -3307,6 +3307,7 @@ extern tree invert_truthvalue (tree);
>  extern tree nondestructive_fold_unary_to_constant (enum tree_code, tree, tree);
>  extern tree nondestructive_fold_binary_to_constant (enum tree_code, tree, tree, tree);
>  extern tree fold_read_from_constant_string (tree);
> +extern tree int_const_binop (enum tree_code, tree, tree, int);
>  
>  /* In builtins.c */
>  extern tree fold_builtin (tree);


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