This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fold upcasts, fix PR22486 (partly)
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 15 Jul 2005 11:38:51 +0200 (CEST)
- Subject: [PATCH] Fold upcasts, fix PR22486 (partly)
This patch folds unnecessary component references and casts
resulting from so called "upcasting" (common in C++) and then
accessing the base again. Notably this removes one of the last obstacles
from IVOPTs optimizing tramp3d loops - still aliasing info is not
good enough to let IVOPTs do its work.
Bootstrapped and regtested on x86_64-unknown-linux-gnu for all
default languages.
Ok for mainline?
Thanks,
Richard.
2005-07-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/22486
* fold-const.c (fold_unary): Fold away useless component
references of the form (T *)&T.x, if the address
doesn't change. Common result of upcasting in C++.
* gcc.dg/tree-ssa/upcast-1.c: New testcase.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.602
diff -c -3 -p -r1.602 fold-const.c
*** fold-const.c 13 Jul 2005 16:31:05 -0000 1.602
--- fold-const.c 14 Jul 2005 17:03:18 -0000
*************** fold_unary (enum tree_code code, tree ty
*** 6705,6711 ****
&& TYPE_MODE (type) == TYPE_MODE (inter_type))
&& ! final_ptr)
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
! }
if (TREE_CODE (op0) == MODIFY_EXPR
&& TREE_CONSTANT (TREE_OPERAND (op0, 1))
--- 6705,6735 ----
&& TYPE_MODE (type) == TYPE_MODE (inter_type))
&& ! final_ptr)
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
! }
!
! /* Handle (T *)&A.B.C for A being of type T and B and C
! living at offset zero. This occours frequently in
! C++ upcasting and then accessing the base. */
! if (TREE_CODE (op0) == ADDR_EXPR
! && POINTER_TYPE_P (type)
! && (TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
! || TREE_CODE (TREE_OPERAND (op0, 0)) == ARRAY_REF))
! {
! HOST_WIDE_INT bitsize, bitpos;
! tree offset;
! enum machine_mode mode;
! int unsignedp, volatilep;
! tree base = TREE_OPERAND (op0, 0);
! base = get_inner_reference (base, &bitsize, &bitpos, &offset,
! &mode, &unsignedp, &volatilep, false);
! /* If the reference was to a (constant) zero offset, we can use
! the address of the base if it has the same base type
! as the result type. */
! if (! offset && bitpos == 0
! && TYPE_MAIN_VARIANT (TREE_TYPE (type))
! == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
! return fold_convert (type, build_fold_addr_expr (base));
! }
if (TREE_CODE (op0) == MODIFY_EXPR
&& TREE_CONSTANT (TREE_OPERAND (op0, 1))
/* { do-go compile } */
/* { dg-options "-fdump-tree-gimple" } */
typedef struct { int i; } Foo;
Foo foo;
Foo *bar(void)
{
return (Foo *)&foo.i;
}
/* { dg-final { scan-tree-dump "&foo" "gimple" } } */
/* { dg-final { cleanup-tree-dump "gimple" } } */