This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Help PR19637 by canonicalizing (T *)&array in more cases
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 5 Mar 2007 17:29:28 +0100 (CET)
- Subject: [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