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]

[PATCH] Help PR19637 by canonicalizing (T *)&array in more cases


I'm not really sure about whether, when and where to canonicalize 
ADDR_EXPRs more.  (Again I hope maybe the new VN will consider &a and 
&a[0] the same)

But this removes some restriction on when we do the canonicalization 
during gimplification.  So it now always prefers &a[0] over &a if
the ADDR_EXPR &a was suitably constructed (in particular, the C frontend
still generates "wrong" ADDR_EXPRs for arrays).

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Ok for mainline?

Thanks,
Richard.

:ADDPATCH middle-end:

2007-03-05  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/19637
	* gimplify.c (canonicalize_addr_expr): Always canonicalize
	(T *)&array.

Index: gimplify.c
===================================================================
*** gimplify.c	(revision 122550)
--- gimplify.c	(working copy)
*************** canonicalize_component_ref (tree *expr_p
*** 1558,1570 ****
  }
  
  /* If a NOP conversion is changing a pointer to array of foo to a pointer
!    to foo, embed that change in the ADDR_EXPR by converting
        T array[U];
        (T *)&array
     ==>
        &array[L]
!    where L is the lower bound.  For simplicity, only do this for constant
!    lower bound.  */
  
  static void
  canonicalize_addr_expr (tree *expr_p)
--- 1558,1572 ----
  }
  
  /* If a NOP conversion is changing a pointer to array of foo to a pointer
!    to foo, embed that change in the ADDR_EXPR if possible by converting
        T array[U];
        (T *)&array
     ==>
        &array[L]
!    where L is the lower bound.  For canonicalization always produce
!       (T *)&array[L]
!    even if T is not the type of the array element.
!    For simplicity, only do this for constant lower bound.  */
  
  static void
  canonicalize_addr_expr (tree *expr_p)
*************** canonicalize_addr_expr (tree *expr_p)
*** 1573,1579 ****
    tree ctype = TREE_TYPE (expr);
    tree addr_expr = TREE_OPERAND (expr, 0);
    tree atype = TREE_TYPE (addr_expr);
!   tree dctype, datype, ddatype, otype, obj_expr;
  
    /* Both cast and addr_expr types should be pointers.  */
    if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype))
--- 1575,1581 ----
    tree ctype = TREE_TYPE (expr);
    tree addr_expr = TREE_OPERAND (expr, 0);
    tree atype = TREE_TYPE (addr_expr);
!   tree datype, ddatype, otype, obj_expr;
  
    /* Both cast and addr_expr types should be pointers.  */
    if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype))
*************** canonicalize_addr_expr (tree *expr_p)
*** 1584,1595 ****
    if (TREE_CODE (datype) != ARRAY_TYPE)
      return;
  
-   /* Both cast and addr_expr types should address the same object type.  */
-   dctype = TREE_TYPE (ctype);
-   ddatype = TREE_TYPE (datype);
-   if (!lang_hooks.types_compatible_p (ddatype, dctype))
-     return;
- 
    /* The addr_expr and the object type should match.  */
    obj_expr = TREE_OPERAND (addr_expr, 0);
    otype = TREE_TYPE (obj_expr);
--- 1586,1591 ----
*************** canonicalize_addr_expr (tree *expr_p)
*** 1597,1615 ****
      return;
  
    /* The lower bound and element sizes must be constant.  */
!   if (!TYPE_SIZE_UNIT (dctype)
!       || TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
        || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
        || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
      return;
  
    /* All checks succeeded.  Build a new node to merge the cast.  */
!   *expr_p = build4 (ARRAY_REF, dctype, obj_expr,
  		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
  		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
! 		    size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (dctype),
! 				size_int (TYPE_ALIGN_UNIT (dctype))));
!   *expr_p = build1 (ADDR_EXPR, ctype, *expr_p);
  }
  
  /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
--- 1593,1612 ----
      return;
  
    /* The lower bound and element sizes must be constant.  */
!   ddatype = TREE_TYPE (datype);
!   if (!TYPE_SIZE_UNIT (ddatype)
!       || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
        || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
        || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
      return;
  
    /* All checks succeeded.  Build a new node to merge the cast.  */
!   *expr_p = build4 (ARRAY_REF, ddatype, obj_expr,
  		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
  		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
! 		    size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (ddatype),
! 				size_int (TYPE_ALIGN_UNIT (ddatype))));
!   *expr_p = fold_convert (ctype, build_fold_addr_expr (*expr_p));
  }
  
  /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions


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