[PATCH] (updated/ping) Fold (T *)&T.x... (aka upcasting)
Richard Guenther
rguenther@suse.de
Fri Jul 22 09:18:00 GMT 2005
This patch is a revision (use handled_component_p) of
http://gcc.gnu.org/ml/gcc-patches/2005-07/msg01031.html
Bootstrapped and regtested on x86_64-unknown-linux-gnu.
Ok for mainline?
Thanks,
Richard.
2005-07-19 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.603
diff -c -3 -p -r1.603 fold-const.c
*** fold-const.c 15 Jul 2005 23:13:54 -0000 1.603
--- fold-const.c 19 Jul 2005 13:19:44 -0000
*************** fold_unary (enum tree_code code, tree ty
*** 6710,6715 ****
--- 6710,6738 ----
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)
+ && handled_component_p (TREE_OPERAND (op0, 0)))
+ {
+ 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))
/* Detect assigning a bitfield. */
/* { 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" } } */
More information about the Gcc-patches
mailing list